Skip to content

Bookmarklet Snippets

Cory Forsyth edited this page Feb 10, 2019 · 29 revisions

JavaScript snippets

Here are some useful snippets of code you might want to use in a bookmarklet. They can also be used in content scripts of extensions.

Inject p5

p5.js can also be injected via a bookmarklet. It requires some special functions to be defined on the global window object (setup and draw), so this snippet explicitly sets those. This code will inject p5 and then draw a circle (it will be added at the bottom of the page).

function injectP5(callback) {
  let script = document.createElement('script');
  script.setAttribute(
    'src',
    '//cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/p5.js'
  );
  script.onload = () => callback();
  script.onerror = e => alert('The script failed to load: ' + e);
  document.head.appendChild(script);
}

function setup() {
  // CHANGEME - Put your p5 setup code here
  console.log('hello from p5 setup');
}
window.setup = setup; // This defines a global `setup` function on the window so that p5 can find it

function draw() {
  // CHANGEME - Put your p5 draw code here
  window.ellipse(50, 50, 80, 80);
}
window.setup = setup; // This defines a global `draw` function on the window so that p5 can find it

injectP5(function() {
  // CHANGEME - If you want to run any other code after p5 has been injected, you can add it here
  console.log('p5 was injected');
});

Snippets that use jQuery

Change a CSS property for every matching element:

// change every paragraph ("p" tag) to have a blue background:
$('p').css({'background-color': 'blue'});

// change every link to be 24px:
$('a').css({'font-size': '24px'});

Change the text of an element:

// changes the text of *every* p tag to be "Hi there"
// Note this also replaces the contents of the *p* tag with this text
// (if it had other elements, like images, inside it, they would be replaced also)
$('p').text('Hi there');

// change the text of only the p tag with id "stuff" to "I have stuff"
$('p#stuff').text('I have stuff');

Add/remove elements to/from the page

Add a div with text to the page

// Use jQuery to create a div with the text "Here is some text"
var div = $("<div>Here is some text</div>");

// add some css properties to the div
div.css({
  'position': 'absolute', // position absolutely
  'top': '100px',           // 100px from the top
  'left': '50%',          // 50% from the left
  'border': '1px solid black', // black border
  'background-color': 'white',
  'width': '200px',
  'height': '200px'
});

// Append the div to the <body> tag
$('body').append(div);

Add an image to the page

var imgSrc = '//via.placeholder.com/150';
var imgHTML = '<img id="my-image" src="' + imgSrc + '">';

// Append the html to the <body> (the browser reads the HTML and adds it appropriately)
// This appends it to the end of the body (it will appear on screen at the bottom of the page)
$('body').append(imgHTML);

// Now that the img is added to the DOM, get it by its id
var img = $('#my-image');

// `animate` is like `css`, except jQuery will animate the property change
// This will make the img animate from 200x150 to 400x300
img.animate({
  width: '400px',
  height: '300px'
});
// Removes *every* P tag that has the class 'first'
$('p.first').remove();

Add a click listener to an element(s)

// add a click listener to *every* p element on the page
$('p').click(function() {
  // This function is executed every time someone clicks on a P element
  var paragraphText = $(this).text();
  alert('You clicked a paragraph that had the text: ' + paragraphText);
  
  // Change the text
  $(this).text('I was clicked on.');
});

Snippets that don't use jQuery

Load an external script

Note: This will be blocked by CSP at domains that use CSP.

// This creates a DOM "script" element, e.g.: <script src="..."></script>
var script = document.createElement('script');
// remove the "http:" or "https:". E.g. instead of "http://my-url.com/a.js" use "//my-url.com/a.js"
link.src = '<URL to the script>';

// Add the element to the <head> tag of the document
document.head.appendChild(script);

Add an external stylesheet

Note: This will be blocked by CSP at domains that use CSP.

// This creates a DOM "link" element, e.g.: <link rel="stylesheet" href="..." />
var link = document.createElement('link');
link.rel = 'stylesheet';
// remove the "http:" or "https:". E.g. instead of "http://my-url.com/a.css" use "//my-url.com/a.css"
link.href = '<URL to the stylesheet>';

// Add the link to the <head> tag of the document
document.head.appendChild(link);

Add inline styles

// Create a style element, e.g.: <style type='text/css'></style>
var style = document.createElement('style');
style.type = 'text/css';

// Use an ES2015 (new-style JavaScript) multi-line string to define styles:
style.textContent = `
  /* add your own styles here: */
  body {
    color: blue;
  }
`;

// Add the style tag to the <head> tag of the document
document.head.appendChild(style);

Get the user's selected (highlighted) text

var text = window.getSelection().toString();
if (text !== '') {
  // there is some text selected
  alert('You selected the text: "' + text + '"');
} else {
  // no text was selected
  alert('No text is selected');
}

Read/change the title of the document

var title = document.title; // read the title
document.title = 'Taken Over By A Bookmarklet'; // set the title

Find/replace text (simple, doesn't work in all cases)

var html = document.body.innerHTML;

// use a regular expression with "g" (global) flag to replace all occurrences
html = html.replace(/cloud/g, 'butt');

// or, here is a technique to replace all instances of a string without a regular expression
html = html.split('Cloud').join('Butt');

// update the document's html with your changes
document.body.innerHTML = html;

Find/replace text (more complicated but more accurate)

// gets all text nodes
// You don't need to understand exactly how this works, just know that you can use it to
// iterate over all the text nodes on the page.
// Read more about TreeWalker here: https://developer.mozilla.org/en-US/docs/Web/API/TreeWalker
// And read more about Text Nodes here: https://developer.mozilla.org/en-US/docs/Web/API/Text
// and here: https://developer.mozilla.org/en-US/docs/Web/API/Node
function getTextNodes() {
  var nodes = [];

  var treeWalker = document.createTreeWalker(
    document.body,
    NodeFilter.SHOW_TEXT,
    { acceptNode: function(node) { return NodeFilter.FILTER_ACCEPT; } },
    false
  );

  while(treeWalker.nextNode()) {
    var parentNode = treeWalker.currentNode.parentNode;
    var parentTagName = parentNode.tagName;
    if (parentTagName !== "SCRIPT" && parentTagName !== "STYLE" && parentTagName !== "TITLE") {
      nodes.push(treeWalker.currentNode);
    }
  }

  return nodes;
}

var textNodes = getTextNodes();

textNodes.forEach(function(textNode) {
  var text = textNode.textContent;

  // Now, do something to this text — perhaps check if it contains a certain substring:
  var textHasWordZombie = text.indexOf('Zombie') !== -1;
  if (textHasWordZombie) {
    // do something special
  }

  // and/or modify the text, for example replace every "Z" with and "A":
  var modifiedText = text.replace(/Z/g, "A");

  // finally, update the text of this Text Node by setting its `textContent` property:
  textNode.textContent = "updated text";
});

Open a new window/tab and put some information (HTML, DOM, etc) in it

Use window.open() to create a new tab. This returns the window, and you can therefore get access to its document and change it that way.

var otherWindow = window.open(); // opens a blank window in a new tab
otherWindow.document.body.innerHTML = "<h1>Hi I was put here with JavaScript. Take me to your leader...</h1>";

You can also use DOM apis to interact with it:

var otherWindow = window.open(); // opens a blank window in a new tab
var otherDoc = otherWindow.document;
var h1 = otherDoc.createElement('h1');
h1.textContent = "Hi there, I'm an h1 from outer space.";
otherDoc.body.appendChild(h1);

Completely replace the page with new HTML

document.body.innerHTML = "Hi <b>I'm</b> new here";

Get all DOM Elements by CSS selector

Note that this returns an array actual DOM Element objects, which have their own methods available. It's similar to jQuery's $(cssSeelctor), but behaves a bit differently

var allParagraphs = document.querySelectorAll("p");

var allParagraphsWithClassNamedDog = document.querySelectorAll("p.dog");

The result is a NodeList, which is like an array but is missing some methods you might expect it to have. It's easiest to just convert it to an array like this:

var allPsNodeList = document.querySelectorAll("p");
console.log(allPsNodeList.map); // undefined
var allPsArray = Array.prototype.slice.call(allPsNodeList);
console.log(allPsArray.map); // f map() { [native code] }

Prompt the user for a string

var favoriteFood = prompt('What is your favorite food?');

Load another script

// The script must be hosted somewhere publicly available
// When selecting the src, leave off the "http:" or "https:" at the beginning
var scriptSrc = "//cdnjs.cloudflare.com/ajax/libs/audiosynth/1.0.0/audiosynth.js";
var script = document.createElement('script');
script.src = scriptSrc;
script.onload = script.onreadystatechange = function() {
  var state = this.state;
  if (state === 'loaded' || state === 'complete') {
    // script has loaded, call a function here that
    // should run after the script has loaded
  }
}
document.getElementsByTagName("head")[0].appendChild(script);

Get location

if (navigator.geolocation) {
  navigator.geolocation.getCurrentPosition(function(position) {
    alert('You are at latitude: ' + position.coords.latitude + ', ' +
          'and longitude: ' +position.coords.longitude);

   // All properties on position.coords are:
   // 'latitude', 'longitude', 'altitude', 'heading', 'speed', 'accuracy'
  });
}

Display a map image for lat/lon

Create a URL with your lat/long like this: https://maps.googleapis.com/maps/api/staticmap?center=LAT,LON&zoom=3&size=300x300&sensor=false

Example URL: https://maps.googleapis.com/maps/api/staticmap?center=36,-73&zoom=3&size=300x300&sensor=false

You can also change the zoom & size parameters.