Bookmarklets are bookmarks that do something other than just linking to a web page (though they sometimes do that as well). They are pieces of software that run in your browser on the web page that is open when you click them. Like regular bookmarks, you can simply drag and drop the link to your bookmarks bar for use later, perhaps on a different web page.
Bookmarklet links always start with "javascript:" and, on this page, they have this pic beside them: For example, this link: Alert Title will popup an alert displaying the web page's title, which is useful if you want to copy it.
I create & test bookmarlets in the console (F12) - refresh (F5), paste, execute, edit, repeat - but globally scoped variables can interfere with other scripts.
javascript: {/* linearized/minified code is safely scoped here */};
IF you use let
not var
. See also, this old PITA:(function(){})()
javascript:location.href='https://12ft.io/proxy?&q='+location.href;
javascript:location.href='steam://openurl/'+location.href;
javascript:let f=location.href.match(/^(.*?)(0*(\d+))([^\d]*)$/);if(f){location=(f[1]+(f[3]*1-1+'').padStart(f[2].length,'0')+f[4]);}
javascript:let f=location.href.match(/^(.*?)(0*(\d+))([^\d]*)$/);if(f){location=(f[1]+(f[3]*1+1+'').padStart(f[2].length,'0')+f[4]);}
javascript:location.href=location.href.replace(/\/[^\/]+$/,'')
javascript:location.href='https://backend.deviantart.com/rss.xml?q=gallery:'+location.href.match(/^(?:https:\/\/www\.deviantart\.com\/(?:watch\/)?)(\w+)/)[1]
Alert => can copy alert(location.href);
javascript:alert('https://redd.it/'+location.href.split('/')[6]);
javascript:alert(document.title);
javascript:window.open(
'https://DoStuff?q='+location.href,
'window name/key'
);
javascript:window.open('https://web.archive.org/web/*/'+location.href,'waybackmachine');
javascript:{window.open('http://tineye.com/search?url=location.href');}
... window.open('http://stone.dialog.jp/tumblr/gallery.html?user='+location.hostname.split('.',1)[0]+'&small=250&large=400&start=0#');
... window.open('http://tumb.la/'+location.hostname.split('.',1)[0]);
let a='URL1',
b='URL2',
l=location.href;
location.href=l.replace(b,a);
javascript:{let a='watch?v=',b='embed/' ... window.open(l.replace(b,a));}
bi-directional ... location.href=( l.includes(b)? l.replace(b,a) : l.replace(a,b) );
javascript:{let a='watch?v=',b='embed/';l=location.href;location.href=(l.includes(b)?l.replace(b,a):l.replace(a,b));}
javascript:window.open('https://www.inoreader.com/article/'+document.querySelector('div[data-oid].article_current').getAttribute('data-oid'));
InoReader uses jQuery => we can too javascript:window.open('https://www.inoreader.com/article/'+$('div[data-oid].article_current').attr('data-oid'));
javascript:window.open('https://old.reddit.com/r/'+[...document.querySelectorAll('li>a.choice[href*="/user/"]')].map(e=>e.textContent.replace('/','_')).join('+'));
javascript:window.open('https://old.reddit.com/r/'+[...document.querySelectorAll('a[role="menuitem"][aria-label^="u/"]')].map(e=>e.textContent.replace('/','_')).join('+'));
javascript:window.open('https://old.reddit.com/r/'+[...document.querySelectorAll(typeof header=='object'?'li>a.choice[href*="/user/"]':'a[role="menuitem"][aria-label^="u/"]')].map(e=>e.textContent.replace('/','_')).join('+'));
javascript:var a=prompt('Clockwise angle?','90');document.getElementsByTagName('img')[0].setAttribute('style','transform:rotate('+a+'deg);margin:auto;');
javascript:{let i=document.getElementsByTagName('img')[0],b=document.body,r=b.clientWidth/i.width;if(r.toFixed(1)==1){r=b.clientHeight/i.height};i.width*=r;i.height*=r;}
javascript:[...document.querySelectorAll('input[name=productSkuId]')].forEach(n=>n.insertAdjacentHTML('beforebegin', '<a href="https://www.mitre10.co.nz/shop/p/'+n.value+'">link</a>'));
javascript:{[...document.styleSheets].forEach(x=>{x.disabled=true;})};
This is a pattern that's used a lot. E.g. "search for the selected text in <SearchEngine>" is so common, that it's in the context menu for most(all?) browsers.
//this get selection boilerplate covered a bunch of browser types and is probably not needed anymore.
let text = (
( window.getSelection && window.getSelection() )
||
( document.getSelection && document.getSelection() )
);
if (text == '') {
text = prompt('Blah?')
};
if (text) {
DoStuff
}
else {
DoOtherStuff
};
↪ (concise)
let w = window,
g = w.getSelection,
d = document.getSelection,
t = ((g && g()) || (d && d()));
if (t == '') {
t = prompt('Blah?')
};
if (t) {
DoStuff
} else {
DoOtherStuff
};
Whitespace is only needed to seperate letters (and readability).
↪ (linearized) javascript:{let w=window,g=w.getSelection,d=document.getSelection,t=((g&&g())||(d&&d()));if(t==''){t=prompt('Blah?')};if(t){DoStuff}else{DoOtherStuff}};
Regex replace: /s/(?<=\w)\s(?!\w)|(?<!\w)\s(?!\w)|(?<!\w)\s(?=\w)//
↪ (minified) javascript:{let w=window,g=w.getSelection,d=document.getSelection,t=g&&g()||d&&d();""==t&&(t=prompt("Blah?")),t?DoStuff:DoOtherStuff}
(original minified) javascript:{let text=window.getSelection&&window.getSelection()||document.getSelection&&document.getSelection();""==text&&(text=prompt("Blah?")),text?DoStuff:DoOtherStuff;}
No selection? => Prompt for parameter let t=((g&&g())||(d&&d())) ... if(t==''){t=prompt('Query?')};
Confirm address => can copy and/or not open let p = 'address' ... if(confirm(p)){window.open(p)};
encodeURIComponent = safe parameters let p = 'address' ... p = p+encodeURIComponent(t) ... if(confirm(p)){window.open(p)};
javascript:{let p='https://letmegooglethat.com/?q=',w=window,g=w.getSelection,d=document.getSelection,t=((g&&g())||(d&&d()));if(t==''){t=prompt('Query?')};p=p+encodeURIComponent(t);if(confirm(p)){w.open(p)};}
... p='https://duckduckgo.com/?q=' ...
... p='https://www.themoviedb.org/search?query=' ...
... p=location.href+'#:~:text=' ... {t=prompt('Highlight text?')}; ...
... p='magnet:?xt=urn:btih:',n=prompt('Name?') ... {t=prompt('Hash?')};p=p+t+'&dn='+n; ...
DoStuff: let s=w.speechSynthesis,m=new SpeechSynthesisUtterance(),f=function(){m.voice=s.getVoices().filter(function(voice){return /UK.*Fem/.test(voice.name)})[0];s.speak(m)};m.rate=m.pitch=1;m.text=t;if(!s.getVoices().length){setTimeout(f,500)}
javascript:{
var f='PPPT-',
p='Ticket Number?',
w=window,
x=w.getSelection,
y=document.getSelection,
z=((x&&x())||(y&&y())).toString().trim(),
j='https://mohits.atlassian.net/browse/',
c='https://servicescentre.moh.govt.nz/CAisd/pdmweb.exe',
b='?OP=SEARCH+FACTORY=',
a='+SKIPLIST=1+QBE.EQ.',
s='ref_num=',
d='chg';
if(z==''){z=prompt(p)};
if(!z){j=c};
if(/^(\d{1,4})$/.test(z)){z=f+z;};
if(/^(\d{5})$/.test(z)){j=c+b+d+a+d+'_'+s;};
if(/^(\d{6})$/.test(z)){j=c+b+'cr'+a+s;};
p=j+encodeURIComponent(z);
if(confirm('Open? '+p)){
w.open(p);
};
}
javascript:document.body.contentEditable='true';document.designMode='on';
javascript:{
let d=document,
l=d.links,
re=/.+\.(bmp|gif|jfif|jpe?g|png|svg|tiff|webp)/,
h='<html><head><title>'+d.title
+' gallery</title><style>img{max-width:15%;}</style></head><body><div>';
for(i=0;i<l.length;i++){
let p=l[i].href;
if(p.toLowerCase().match(re)){
h+='<img src="'+p+'"/>'
}
}
h+='</div></body></html>';
d.body.innerHTML=h;
}
javascript:[...document.links].forEach(a =>{
if( a.text.endsWith('>') ) a.innerText=decodeURIComponent( a.href.split('/').pop() )
})
The linked scripts are not my code. Use at your own risk.
javascript:{
let d=document,
s=d.createElement('script');
s.src='http://hi.kickassapp.com/kickass.js';
d.body.appendChild(s);
};
or multiple scripts...
javascript:{
let d=document,s;
[
'http://kathack.com/js/kh.js',
'http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js'
].forEach(u=>{
s=d.createElement('script');
s.src=u;
d.body.appendChild(s);
})
};
Subresource Integrity lets you verify the js file hasn't been altered but CORS needs to be enabled by the host (all CDNs support this). The downside is that every update to the js file requires updating the bookmarklet - or the integrity hash inside it (Hash generator).
javascript:{
let d=document,s;
[
{
u:'https://www.gible.net/YATS.js', //script file
h:'sha384-uEw6nnHT+KwA7i6mSslMVnwEmAEzmzRx+sQMJ7eISEvi54QY6qXvddZyS95VTl1N', //integrity hash
e:function(){ //error handler for when integrity hash check inevitably fails
if(confirm('JS load failed! Update bookmarklet?')){
window.open('https://www.gible.net/bookmarklets.html#yats')
}
}
},
{
u:'https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js',
h:'sha384-hhQ2DWmF+rxpBS/u5Hl/5JYmaKB7TRlXyKPFCeq7M7CIQsUih3E3M3+IUjgB5uE1'
}
].forEach(e=>{
s=d.createElement('script');
s.src=e.u;
s.integrity=e.h;
s.crossOrigin='anonymous';
if(e.e)s.onerror=e.e;
d.body.appendChild(s);
});
};
Just do the thing.
... [
'https://www.gible.net/do.js'
] ...