Making JavaScript Bookmarklets

@makerhacks · 2025-08-15 16:04 · programming

image.png

A bookmarklet runs JavaScript on the page you’re already on. This can be very convenient versus trying to get around security and bot-busting, especially when the site you are on doesn't have any convenient automation features.

You can do a lot with them. You could turn the background to dark mode, swap out words or URLs across an entire page, or add interactive elements.

This is a cool one which removes popup layers on web sites, you know like "agree to our terms before reading" and stuff:

javascript:(function()%7B(function () %7Bvar i%2C elements %3D document.querySelectorAll('body *')%3Bfor (i %3D 0%3B i < elements.length%3B i%2B%2B) %7Bif (getComputedStyle(elements%5Bi%5D).position %3D%3D%3D 'fixed') %7Belements%5Bi%5D.parentNode.removeChild(elements%5Bi%5D)%3B%7D%7D%7D)()%7D)()

Another fun one allows you to edit the content of the current page, like virtual graffiti:

javascript:document.body.contentEditable %3D %27true%27%3B document.designMode%3D%27on%27%3B void 0

Here is how to make one yourself.

Try One Out

  1. Make a new bookmark in your browser (right-click the bookmarks bar and select “Add Page…”).
  2. For the name, type something like Prince Me!.
  3. Copy this code and paste it into the bookmark’s location field:
javascript:(function(){document.body.style.background = 'purple';})();
  1. Visit any site, click your new bookmark, and the background should change (most of the time).

How to Make Your Own

You only need three steps:

  1. Write the JavaScript you want to run (start by testing in the browser console).
  2. Add javascript: to the front.
  3. Wrap it in an IIFE (Immediately Invoked Function Expression) so the page runs it cleanly without reloading.

Example, replace “AI” with “ball sack” everywhere on a page:

javascript:document.body.innerHTML = document.body.innerHTML.replace(/AI/g, "ball sack").replace(/AI/g, "Ball Sack");

If you try that directly, the page may refresh or break some styles. Wrapping it in an IIFE fixes this most of the time:

javascript:(function(){
  document.body.innerHTML = document.body.innerHTML.replace(/AI/g, "ball sack").replace(/AI/g, "ball sack");
})();

image.png

That’s the general template you can use:

javascript:(function(){ /* your code here */ })();

Quicker Debugging

Updating the bookmark every time you change the code can be slow. You can test in the browser’s location bar instead:

Paste your code there with javascript: at the front.

Note: browsers usually strip javascript: when you paste, so you’ll have to retype it.

Editing Bookmarklets

When you save a bookmarklet, the browser removes newlines and indentation, making it hard to read. Two ways to handle this:

  1. Keep a copy in a text file (or a code repository like GitHub).
  2. Use a tool like JSBeautifier to reformat it before editing. Then paste it back into the bookmark when ready.

Useful JavaScript You Can Test First

Before you put code into a bookmarklet, it’s best to test it in the console.

Open the browser console

Windows or Linux

  • Chrome, Edge, Brave: F12 or Ctrl+Shift+I, then click Console
  • Firefox: F12 or Ctrl+Shift+K for Console

Mac

  • Chrome, Edge, Brave: Cmd+Option+I, then Console
  • Firefox: Cmd+Option+K
  • Safari: enable Develop menu in Preferences, then Option+Cmd+C

Use console.log for quick checks

console.log prints to the Console. It’s the easiest way to see what your code is doing.

console.log('Starting script');
console.log({ location: window.location.href });

You can also use it for lightweight notifications during a bookmarklet run.

console.log('Changed background to pink');

Select elements on the page

By tag name

Returns a live HTMLCollection.

var inputs = document.getElementsByTagName('input');
console.log('Found', inputs.length, 'inputs');

By id

Returns a single element or null.

var searchBox = document.getElementById('search');

By class name

Returns a live HTMLCollection.

var errors = document.getElementsByClassName('error');

With CSS selectors

querySelector returns the first match. querySelectorAll returns a static NodeList.

var firstButton = document.querySelector('button.primary');
var allLinks = document.querySelectorAll('a[href^="https://"]');

Check if a string contains text

Use indexOf("some text"). It returns the position or -1 if not found.

var title = document.title;
if (title.indexOf('Pricing') >= 0) {
  console.log('This looks like a pricing page');
}

Case-insensitive check:

if (title.toLowerCase().indexOf('pricing') >= 0) { /* ... */ }

Work with parents and children

var el = document.querySelector('.item');

/* parent */
var parent = el.parentElement;

/* nearest matching ancestor */
var card = el.closest('.card');

/* children collection */
var kids = el.children;               // HTMLCollection of element children
var firstKid = el.firstElementChild;
var next = el.nextElementSibling;

Turn collections into arrays

Many DOM methods return HTMLCollection or NodeList. Convert them so you can use array helpers like find, filter, and map.

var inputs = Array.from(document.getElementsByTagName('input'));

Now you can iterate with full array methods.

Find a specific input with Array.find

find returns the first matching element or undefined.

var matchingInput = inputs.find(function(item) {
  return item.defaultValue && item.defaultValue.indexOf('Inspect any URL') >= 0;
});

if (matchingInput) {
  console.log('Found:', matchingInput);
}

Arrow function version:

var matchingInput = inputs.find(i =>
  typeof i.defaultValue === 'string' &&
  i.defaultValue.indexOf('Inspect any URL') >= 0
);

Act on what you found

Once you have the element, you can change it or click related controls.

if (matchingInput) {
  matchingInput.value = 'https://example.com';
  /* example: click the next sibling button if it exists */
  var btn = matchingInput.nextElementSibling;
  if (btn && btn.tagName === 'BUTTON') btn.click();
}

Combine these in a bookmarklet

Test in the console first. When it works, wrap it and prefix with javascript:.

javascript:(function(){
  var inputs = Array.from(document.getElementsByTagName('input'));
  var target = inputs.find(i =>
    typeof i.defaultValue === 'string' &&
    i.defaultValue.toLowerCase().indexOf('inspect any url') >= 0
  );

  if (target) {
    target.value = 'https://example.com';
    console.log('Filled target input');
    var submit = target.form && target.form.querySelector('button, input[type="submit"]');
    if (submit) {
      submit.click();
      console.log('Submitted form');
    } else {
      console.log('Submit control not found');
    }
  } else {
    console.log('Target input not found');
  }
})();

Small patterns you will reuse

Safe text replace across the page

Be careful with innerHTML because it re-parses the whole DOM. Safer for text-only changes:

function replaceText(node, from, to) {
  if (node.nodeType === Node.TEXT_NODE) {
    node.nodeValue = node.nodeValue.replace(from, to);
  } else {
    Array.from(node.childNodes).forEach(function(child){
      replaceText(child, from, to);
    });
  }
}

// usage
replaceText(document.body, /cloud/gi, 'butt');

Wrap for a bookmarklet when you’re happy with it.

Guard against missing elements

Avoid errors when something isn’t on the page.

var el = document.querySelector('#search');
if (!el) {
  console.log('Search box not found');
} else {
  el.value = 'test';
}

Time your code

Measure how long something takes.

console.time('replace');
replaceText(document.body, /cloud/gi, 'butt');
console.timeEnd('replace');

Test each snippet in the console first, then wrap it in a bookmarklet when it does what you want.

#programming #javascript #technology
Payout: 4.430 HBD
Votes: 20
More interactions (upvote, reblog, reply) coming soon.