Here are some of the bookmarklets I've created or collected over the years for my personal use.
What are bookmarklets? They are basically bookmarks that execute javascript code when clicked instead of opening a website. Bookmarklets give you the power of javascript to do whatever you want (within the limits of your browser), so use it with care and only use bookmarklets you trust!
To install a bookmarklet, create a new bookmark and paste the code into the URL bar. See examples below, images taken from freeCodeCamp.
Alternatively, if the bookmarklet is available as a link, you can also drag and drop it to your bookmarks menu to install. Note that the JS code in the bookmarklet link will be different as it has been minified.
Only install bookmarklets from sources you trust and whenever possible, review the code before running it!
Deletes an element on click. Press the Esc key or right-click to exit, able to undo using Ctrl + Z or Cmd + Z (favorite bookmarklet thus far, fun to play with).
Thinking of adding some new fun features in the future, or maybe turn it into a browser extension.
delete-element.js
javascript: (() => {
let mouseX = 0;
let mouseY = 0;
const undo = [];
const handleMouseover = (e) => {
mouseX = e.clientX;
mouseY = e.clientY;
e.target.style.outline = 'dashed';
};
const handleMouseout = (e) => {
e.target.style.outline = '';
};
const handleClick = (e) => {
e.preventDefault();
const el = e.target;
const index = Array.from(el.parentElement.children).indexOf(el);
undo.push([el, el.parentElement, index]);
el.remove();
};
const unmount = () => {
document.elementFromPoint(mouseX, mouseY).style.outline = '';
document.body.removeEventListener('click', handleClick);
document.body.removeEventListener('mouseover', handleMouseover);
document.body.removeEventListener('mouseout', handleMouseout);
document.body.removeEventListener('keydown', handleKeydown);
document.body.removeEventListener('contextmenu', handleContextmenu);
};
const handleKeydown = (e) => {
if (e.key === 'Escape') {
e.preventDefault();
unmount();
}
if (e.key === 'z' && (e.ctrlKey || e.metaKey) && undo.length > 0) {
const [el, parentEl, index] = undo.pop();
el.style.outline = '';
parentEl.insertBefore(el, parentEl.children[index]);
}
};
const handleContextmenu = (e) => {
e.preventDefault();
unmount();
};
document.body.addEventListener('click', handleClick);
document.body.addEventListener('mouseover', handleMouseover);
document.body.addEventListener('mouseout', handleMouseout);
document.body.addEventListener('keydown', handleKeydown);
document.body.addEventListener('contextmenu', handleContextmenu);
})();
Deletes an element on click, one time only, no undo. Press the Esc key or 8000 right-click to cancel.
delete-element-one.js
javascript: (() => {
let mouseX = 0;
let mouseY = 0;
const handleMouseover = (e) => {
mouseX = e.clientX;
mouseY = e.clientY;
e.target.style.outline = 'dashed';
};
const handleMouseout = (e) => {
e.target.style.outline = '';
};
const unmount = () => {
document.elementFromPoint(mouseX, mouseY).style.outline = '';
document.body.removeEventListener('click', handleClick);
document.body.removeEventListener('mouseover', handleMouseover);
document.body.removeEventListener('mouseout', handleMouseout);
document.body.removeEventListener('keydown', handleKeydown);
document.body.removeEventListener('contextmenu', handleContextmenu);
};
const handleClick = (e) => {
e.preventDefault();
e.target.remove();
unmount();
};
const handleKeydown = (e) => {
if (e.key === 'Escape') {
e.preventDefault();
unmount();
}
};
const handleContextmenu = (e) => {
e.preventDefault();
unmount();
};
document.body.addEventListener('click', handleClick);
document.body.addEventListener('mouseover', handleMouseover);
document.body.addEventListener('mouseout', handleMouseout);
document.body.addEventListener('keydown', handleKeydown);
document.body.addEventListener('contextmenu', handleContextmenu);
})();
A collection of audio/video-related bookmarklets, works as long as the website uses audio/video tags. Applies to the first audio/video on the website, won't work for audios/videos inside an iframe.
Note: If you want to apply to a audio/video inside an iframe, use the iframe bookmarklet below to open the audio/video iframe in a new tab, then try the audio/video bookmarklet.
I was thinking of turning this into a browser extension to fix the iframe issue (see note above) but ended up using this extension instead. Thinking of forking it and making my own version sometime.
Creates a small audio/video playback controller fixed to the top right side of the screen, click the bookmarklet again to remove. Note that the controller buttons will be affected by the website's existing CSS.
Able to change playback speed, restart the audio/video, rewind or fast forward in 10s increments, play/pause, and mute/unmute the audio/video. The video controller is my most used bookmarklet when watching videos.
Note: Due to the use of innerHTML
, this bookmarklet will not work on sites that require TrustedHTML assignment (CSP). In such cases, use the other bookmarklets below instead.
Audio: aud-controller.js
javascript: (() => {
const audControl = document.querySelector('#audControl-div');
if (audControl) {
return audControl.remove();
}
if (!document.querySelector('audio')) {
return alert('No audio tags found');
}
const div = document.createElement('div');
div.id = 'audControl-div';
div.style.zIndex = '9999';
div.style.position = 'fixed';
div.style.top = '0%';
div.style.right = '0%';
div.style.display = 'flex';
div.style.gap = '0.2em';
div.style.padding = '0.1em';
div.style.userSelect = 'none';
div.innerHTML = `
<button id="ac-s" style="pointer-events: none;">${document
.querySelector('audio')
.playbackRate.toFixed(1)}x</button>
<button style="cursor: pointer;">-</button>
<button style="cursor: pointer;">1x</button>
<button style="cursor: pointer;">2x</button>
<button style="cursor: pointer;">3x</button>
<button style="cursor: pointer;">+</button>
<button style="cursor: pointer;">Restart</button>
<button style="cursor: pointer;">-10s</button>
<button id="ac-p" style="cursor: pointer;">${
document.querySelector('audio').paused ? 'Play' : 'Pause'
}</button>
<button style="cursor: pointer;">+10s</button>
<button id="ac-m" style="cursor: pointer;">${
document.querySelector('audio').loop ? 'Unmute' : 'Mute'
}</button>
<button id="ac-l" style="cursor: pointer;">${
document.querySelector('audio').loop ? 'Loop ON' : 'Loop OFF'
}</button>
`;
document.body.appendChild(div);
})();
Video: vid-controller.js
javascript: (() => {
const vidControl = document.querySelector('#vidControl-div');
if (vidControl) {
return vidControl.remove();
}
if (!document.querySelector('video')) {
return alert('No video tags found');
}
const div = document.createElement('div');
div.id = 'vidControl-div';
div.style.zIndex = '9999';
div.style.position = 'fixed';
div.style.top = '0%';
div.style.right = '0%';
div.style.display = 'flex';
div.style.gap = '0.2em';
div.style.padding = '0.1em';
div.style.userSelect = 'none';
div.innerHTML = `
<button id="vc-s" style="pointer-events: none;">${document
.querySelector('video')
.playbackRate.toFixed(1)}x</button>
<button style="cursor: pointer;">-</button>
<button style="cursor: pointer;">1x</button>
<button style="cursor: pointer;">2x</button>
<button style="cursor: pointer;">3x</button>
<button style="cursor: pointer;">+</button>
<button style="cursor: pointer;">Restart</button>
<button style="cursor: pointer;">-10s</button>
<button id="vc-p" style="cursor: pointer;">${
document.querySelector('video').paused ? 'Play' : 'Pause'
}</button>
<button style="cursor: pointer;">+10s</button>
<button id="vc-m" style="cursor: pointer;">${
document.querySelector('video').loop ? 'Unmute' : 'Mute'
}</button>
<button id="vc-l" style="cursor: pointer;">${
document.querySelector('video').loop ? 'Loop ON' : 'Loop OFF'
}</button>
`;
document.body.appendChild(div);
})();
Toggles the default HTML5 audio/video controls and remove all controlsList
attributes.
Audio: aud-toggle-ctrl.js
javascript: (() => {
const aud = document.querySelector('audio');
if (!aud) {
return alert('No audio tags found');
}
aud.controls = !aud.controls;
console.log('ControlsList before overwrite:', aud.controlsList);
aud.controlsList = '';
console.log('ControlsList after overwrite:', aud.controlsList);
})();
Video: vid-toggle-ctrl.js
javascript: (() => {
const vid = document.querySelector('video');
if (!vid) {
return alert('No video tags found');
}
vid.controls = !vid.controls;
console.log('ControlsList before overwrite:', vid.controlsList);
vid.controlsList = '';
console.log('ControlsList after overwrite:', vid.controlsList);
})();
Changes the first audio/video's playback speed, should work with youtube/vimeo and etc, also shows the current playback speed.
Audio: aud-speed.js
javascript: (() => {
const aud = document.querySelector('audio');
if (!aud) {
return alert('No audio tags found');
}
const x = prompt(`Playback Speed? (Current: ${aud.playbackRate})`);
aud.playbackRate = parseFloat(x);
})();
Video: vid-speed.js
javascript: (() => {
const vid = document.querySelector('video');
if (!vid) {
return alert('No video tags found');
}
const x = prompt(`Playback Speed? (Current: ${vid.playbackRate})`);
vid.playbackRate = parseFloat(x);
})();
Useful if there are multiple audios/videos in a single page, changes the playback speed for all audios/videos.
Audio: aud-speed-all.js
javascript: (() => {
const aud = document.querySelectorAll('audio');
if (aud.length === 0) {
return alert('No audio tags found');
}
const x = prompt(`Playback Speed?`);
aud.forEach((a) => (a.playbackRate = parseFloat(x)));
})();
Video: vid-speed-all.js
javascript: (() => {
const vid = document.querySelectorAll('video');
if (vid.length === 0) {
return alert('No video tags found');
}
const x = prompt(`Playback Speed?`);
vid.forEach((v) => (v.playbackRate = parseFloat(x)));
})();
Able to play/pause the first audio/video, useful if audio/video controls are hidden but recommend to use the audio/video controller bookmarklet instead.
Audio: aud-play-pause.js
javascript: (() => {
const aud = document.querySelector('audio');
if (!aud) {
return alert('No audio tags found');
}
aud.paused ? aud.play() : aud.pause();
})();
Video: vid-play-pause.js
javascript: (() => {
const vid = document.querySelector('video');
if (!vid) {
return alert('No video tags found');
}
vid.paused ? vid.play() : vid.pause();
})();
Handy bookmarklet to check for iframes on a website.
Creates a set of buttons showing the iframe's source URL (opens in new tab when clicked) fixed to the top right side of the screen, click the bookmarklet again to remove the buttons. Note that the buttons will be affected by the website's existing CSS.
Note: Due to the use of innerHTML
, this bookmarklet will not work on sites that require TrustedHTML assignment (CSP). In such cases, use the other bookmarklets below instead.
iframe-panel.js
javascript: (() => {
const ipd = document.querySelector('#iframe-panel-div');
if (ipd) {
return ipd.remove();
}
const iframes = document.querySelectorAll('iframe');
if (iframes.length === 0) {
return alert('No iframes found');
}
const div = document.createElement('div');
div.id = 'iframe-panel-div';
div.style.zIndex = '9999';
div.style.position = 'fixed';
div.style.top = '0%';
div.style.right = '0%';
div.style.display = 'flex';
div.style.flexDirection = 'column';
div.style.gap = '0.2em';
div.style.padding = '0.1em';
div.style.userSelect = 'none';
div.style.maxWidth = '320px';
div.style.maxHeight = '320px';
div.style.overflow = 'auto';
let buttons = '';
iframes.forEach((i) => {
buttons +=
i.src === ''
? `<button style="pointer-events: none;">This iframe has no source</button>`
: `<button style="cursor: pointer; width: 100%; overflow-wrap: anywhere;">${i.src}</button>`;
});
div.innerHTML = `
<div style="display: flex;">
<button id="vc-s" style="pointer-events: none; flex-grow: 1;">\
${iframes.length} iframe(s) found, source(s) below
</button>
<button style="cursor: pointer; margin-left: auto;">
Remove all
</button>
</div>
<button id="vc-s" style="pointer-events: none; background: lightgray; border: none;">
Click the url(s) to open in new tab
</button>
${buttons}
`;
document.body.appendChild(div);
})();
Less versatile but works if the above bookmarklet doesn't.
iframe-alert.js
javascript: (() => {
const iframes = document.querySelectorAll('iframe');
if (iframes.length === 0) {
return alert('No iframes found');
}
let src = '';
iframes.forEach((i, idx) => (src += `${idx + 1}: ${i.src}, `));
alert(`${iframes.length} iframes found, ${src}`);
})();
Some bookmarklets that help with color sampling.
Uses the EyeDropper API, unfortunately it is not supported in Firefox and Safari at the time of writing (Dec 2023).
Also converts the HEX code to RGB and HSL values, code for converting RGB to HSL referenced from 30secondsofcode.org
color-eyedropper.js
javascript: (() => {
if (typeof window.EyeDropper === 'undefined') {
alert("Your browser doens't support the EyeDropper API");
return;
}
const x = new EyeDropper();
x.open()
.then((res) => {
const hex = res.sRGBHex;
const r = parseInt(hex.slice(1, 3), 16);
const g = parseInt(hex.slice(3, 5), 16);
const b = parseInt(hex.slice(5), 16);
const rgbToHsl = (r, g, b) => {
r /= 255;
g /= 255;
b /= 255;
const l = Math.max(r, g, b);
const s = l - Math.min(r, g, b);
const h =
s !== 0
? l === r
? (g - b) / s
: l === g
? 2 + (b - r) / s
: 4 + (r - g) / s
: 0;
return [
(60 * h < 0 ? 60 * h + 360 : 60 * h).toFixed(2),
(
100 * (s ? (l <= 0.5 ? s / (2 * l - s) : s / (2 - (2 * l - s))) : 0)
).toFixed(2) + '%',
((100 * (2 * l - s)) / 2).toFixed(2) + '%',
];
};
alert(
`Color is ${res.sRGBHex}, rgb(${r} ${g} ${b}), hsl(${rgbToHsl(
r,
g,
b
).join(' ')})`
);
})
.catch((e) => alert(`Error: ${e}`));
})();
Or alternatively, the bookmarklet below is an alternative if the EyeDropper API is not supported. It opens a color input element on a new popup window. Referenced from css-tricks.com, lightly modified for readability and to set the popup on the bottom right corner.
color-popup.js
javascript: (() => {
const windowFeatures = `
popup,
width=100,
height=100,
left=${window.screen.availWidth},
top=${window.screen.availHeight},
`;
window.open('', '', windowFeatures).document.body.innerHTML =
'<input type="color">';
})();
Reads and displays your cookie data.
show-cookies.js
javascript: (() => alert(document.cookie || 'No cookies found'))();
Reads and displays your localStorage data.
show-localstorage.js
javascript: (() => {
if (window.localStorage.length === 0) {
return alert('No data in localStorage found');
}
let str = '';
for (let [k, v] of Object.entries(window.localStorage)) {
str += `key:${k}, val:${v}, `;
}
alert(str);
})();
Reads and displays your sessionStorage data.
show-sessionstorage.js
javascript: (() => {
if (window.sessionStorage.length === 0) {
return alert('No data in sessionStorage found');
}
let str = '';
for (let [k, v] of Object.entries(window.sessionStorage)) {
str += `key:${k}, val:${v}, `;
}
alert(str);
})();
Toggles designMode to make website editable.
toggle-designmode.js
javascript: (() => {
document.designMode = document.designMode === 'on' ? 'off' : 'on';
})();
Simple bookmarklet to center the webpage, limit the width, and change the line height. Usually only works on simple websites, might break certain websites.
simple-center.js
javascript: (() => {
b = document.body.style;
b.margin = '1em auto';
b.maxWidth = '80ch';
b.lineHeight = '1.5';
})();
Makes the text in every element user selectable.
user-select-text.js
javascript: (() => {
document.querySelectorAll("*").forEach((el) => {
el.style.webkitUserSelect = "text";
el.style.MozUserSelect = "text";
el.style.msUserSelect = "text";
el.style.userSelect = "text";
});
})();
Unblurs all element on the page.
unblur-all.js
javascript: (() => {
document.querySelectorAll("*").foreach((el) => {
el.style.filter = "blur(0) !important;";
el.style.webkitFilter = "blur(0) !important;";
el.style.backdropFilter = "blur(0) !important;";
el.style.webkitBackdropFilter = "blur(0) !important;";
});
})();
Ever want to remove all the CSS and images/videos/etc on a webpage? Well now you can with this amazing new bookmarklet! Removes img/svg/iframe/audio/video/canvas.
Why would you ever want to do that? Well, you can browse flashy websites without attracting the attention of others walking by (my current use case), and you can use it to see a before/after comparison of the website/webapp with and without CSS applied.
remove-css-media.js
javascript: (() => {
document.querySelectorAll('img').forEach((el) => {
el.replaceWith(`img_alt: ${el.alt}`);
});
document.querySelectorAll('svg').forEach((el) => {
el.replaceWith(
`svg_title: ${el.querySelector('title')?.textContent ?? ''}`
);
});
document
.querySelectorAll('iframe, audio, video')
.forEach((el) =>
el.replaceWith(`${el.tagName.toLowerCase()}_src: ${el.src}`)
);
document
.querySelectorAll('canvas')
.forEach((el) => el.replaceWith(`canvas_WxH: ${el.width}x${el.height}`));
document
.querySelectorAll('[style]')
.forEach((el) => el.removeAttribute('style'));
document
.querySelectorAll('style, link[rel="stylesheet"]')
.forEach((el) => el.remove());
})();
javascript:location.href='https://web.archive.org/web/*/%27+document.location.href;
javascript:location.href='https://archive.is/%27+document.location.href;
Shortcut for removepaywall.com, has five options to remove paywall. Also has the option to view with archive.is.
javascript:location.href='https://www.removepaywall.com/search?url=%27+document.location.href;
It would be awesome to create a calculator bookmarklet, but honestly, it's probably easier to open the developer tools and use the console to calculate anything. But, I found two apps that works great as calculators in the browser.
The unsure calculator calculates with uncertainty. There's also the unsure app which lets you do back of the napkin calculations with uncertainty. Created by Filip Hráček
A cool notepad calculator for quick calculations. Created by Steve Ridout
Using html contenteditable to create an empty notepad to jot things down. To save your data, press Ctrl + S or save like a regular webpage, not the ideal but it works. Technically not a bookmarklet but a data URL instead.
Alternatively, you could use something like browserpad which saves your data to localStorage instead.
data:text/html,
<html contenteditable="plaintext-only"></html>
data:text/html,
<html contenteditable></html>
As the name implies, kill sticky it's a bookmarklet that kills sticky content.
Here's a modified version I use that doesn't remove position fixed/sticky but makes them static instead.
kill-sticky-mod.js
javascript: (() => {
document.querySelectorAll('body *').forEach((node) => {
if (['fixed', 'sticky'].includes(getComputedStyle(node).position)) {
node.style.position = 'static';
}
});
document.querySelectorAll('html *').forEach((node) => {
const s = getComputedStyle(node);
if ('hidden' === s['overflow']) {
node.style['overflow'] = 'visible';
}
if ('hidden' === s['overflow-x']) {
node.style['overflow-x'] = 'visible';
}
if ('hidden' === s['overflow-y']) {
node.style['overflow-y'] = 'visible';
}
});
const htmlNode = document.querySelector('html');
htmlNode.style['overflow'] = 'visible';
htmlNode.style['overflow-x'] = 'visible';
htmlNode.style['overflow-y'] = 'visible';
})();
Cool kick ass app bookmarklet that lets you 'destroy' websites.
Some useful bookmarklets from css-tricks.com for web development, more available in the comments section.
If you would like to contribute to this project, feel free to:
- Raise an issue - Let me know if there's any bugs or bookmarklet request and I'll see what I can do.
- Create a pull request - If you want to get your hands dirty and fix/improve/add a new bookmarklet yourself, feel free to fork this repo and create a PR.
How to add a new bookmarklet to this repo:
- Fork or clone this repo and run
npm i
to install the required package, make sure you already have node.js installed. - Create a new
bookmarklets/bookmarklet-name.js
script for the bookmarklet you want to add. - Update
template/readme_template.md
to include a description and add@bookmarklet-name.js
on a new line after your description. - Run
npm run build
to generate the updatedREADME.md
andindex.html
with the new bookmarklet. - Create a PR.