-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
651 lines (649 loc) · 50.5 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="styles.css" />
<link
rel="apple-touch-icon"
sizes="180x180"
href="favicon/apple-touch-icon.png"
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href="favicon/favicon-32x32.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="favicon/favicon-16x16.png"
/>
<link rel="manifest" href="site.webmanifest" />
<title>Bookmarklets</title>
</head>
<body>
<h1>A collection of bookmarklets</h1>
<p>Here are some of the bookmarklets I've created or collected over the years for my personal use.</p>
<p>What are <a href="https://en.wikipedia.org/wiki/Bookmarklet">bookmarklets</a>? 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!</p>
<h2>How to install and use bookmarklets</h2>
<p>To install a bookmarklet, create a new bookmark and paste the code into the URL bar. See examples below, images taken from <a href="https://www.freecodecamp.org/news/what-are-bookmarklets/">freeCodeCamp</a>.</p>
<p>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 might be different as it has been minified.</p>
<p><strong>Only install bookmarklets from sources you trust and whenever possible, review the code before running it!</strong></p>
<h4>Example using Firefox:</h4>
<p><img src="https://github.com/bk7312/bookmarklets/assets/14029543/db38cfc8-145d-4fb0-8395-2a06cbc76723" alt="firefox-1"></p>
<h4>Example using Chromium:</h4>
<p><img src="https://github.com/bk7312/bookmarklets/assets/14029543/f53a55f2-ecc0-4a68-8231-e85bad099072" alt="chromium"></p>
<h2>Delete element on click</h2>
<p>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).</p>
<p>Thinking of adding some new fun features in the future, or maybe turn it into a browser extension.</p>
<p><a class='btn' href="javascript:(()=>{let mouseX=0,mouseY=0;const undo=[],handleMouseover=e=>{mouseX=e.clientX,mouseY=e.clientY,e.target.style.outline="dashed"},handleMouseout=e=>{e.target.style.outline=""},handleClick=e=>{e.preventDefault();var e=e.target,index=Array.from(e.parentElement.children).indexOf(e);undo.push([e,e.parentElement,index]),e.remove()},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)},handleKeydown=e=>{var parentEl,index;"Escape"===e.key&&(e.preventDefault(),unmount()),"z"===e.key&&(e.ctrlKey||e.metaKey)&&0<undo.length&&([e,parentEl,index]=undo.pop(),e.style.outline="",parentEl.insertBefore(e,parentEl.children[index]))},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)})();" title="To install, drag and drop this link to your bookmarks">delete-element.js</a></p>
<pre><code>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);
})();
</code></pre>
<p>Deletes an element on click, one time only, no undo. Press the Esc key or right-click to cancel.</p>
<p><a class='btn' href="javascript:(()=>{let mouseX=0,mouseY=0;const handleMouseover=e=>{mouseX=e.clientX,mouseY=e.clientY,e.target.style.outline="dashed"},handleMouseout=e=>{e.target.style.outline=""},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)},handleClick=e=>{e.preventDefault(),e.target.remove(),unmount()},handleKeydown=e=>{"Escape"===e.key&&(e.preventDefault(),unmount())},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)})();" title="To install, drag and drop this link to your bookmarks">delete-element-one.js</a></p>
<pre><code>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);
})();
</code></pre>
<h2>Remove CSS, image, and other media from a webpage</h2>
<p>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.</p>
<p>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.</p>
<p><a class='btn' href="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")),void document.querySelectorAll('style, link[rel="stylesheet"]').forEach(el=>el.remove());" title="To install, drag and drop this link to your bookmarks">remove-css-media.js</a></p>
<pre><code>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());
})();
</code></pre>
<h2>Audio/Video-related bookmarklets</h2>
<p>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.</p>
<p>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.</p>
<p>I was thinking of turning this into a browser extension to fix the iframe issue (see note above) but ended up using <a href="https://github.com/igrigorik/videospeed">this extension</a> instead. Thinking of forking it and making my own version sometime.</p>
<h4>Audio/Video Controller</h4>
<p>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.</p>
<p>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.</p>
<p>Note: Due to the use of <code>innerHTML</code>, this bookmarklet will not work on sites that require <a href="https://developer.mozilla.org/en-US/docs/Web/API/TrustedHTML">TrustedHTML</a> assignment (CSP). In such cases, use the other bookmarklets below instead.</p>
<p>Audio:
<a class='btn' href="javascript:(()=>{var audControl=document.querySelector("#audControl-div");return audControl?audControl.remove():document.querySelector("audio")?((audControl=document.createElement("div")).id="audControl-div",audControl.style.zIndex="9999",audControl.style.position="fixed",audControl.style.top="0%",audControl.style.right="0%",audControl.style.display="flex",audControl.style.gap="0.2em",audControl.style.padding="0.1em",audControl.style.userSelect="none",audControl.innerHTML=`
<button id="ac-s" style="pointer-events: none;">${document.querySelector("audio").playbackRate.toFixed(1)}x</button>
<button onclick="const aud = document.querySelector('audio'); aud.playbackRate -= 0.2; document.querySelector('#ac-s').textContent = aud.playbackRate.toFixed(1) + 'x'" style="cursor: pointer;">-</button>
<button onclick="const aud = document.querySelector('audio'); aud.playbackRate = 1; document.querySelector('#ac-s').textContent = aud.playbackRate.toFixed(1) + 'x'" style="cursor: pointer;">1x</button>
<button onclick="const aud = document.querySelector('audio'); aud.playbackRate = 2; document.querySelector('#ac-s').textContent = aud.playbackRate.toFixed(1) + 'x'" style="cursor: pointer;">2x</button>
<button onclick="const aud = document.querySelector('audio'); aud.playbackRate = 3; document.querySelector('#ac-s').textContent = aud.playbackRate.toFixed(1) + 'x'" style="cursor: pointer;">3x</button>
<button onclick="const aud = document.querySelector('audio'); aud.playbackRate += 0.2; document.querySelector('#ac-s').textContent = aud.playbackRate.toFixed(1) + 'x'" style="cursor: pointer;">+</button>
<button onclick="document.querySelector('audio').currentTime = 0;" style="cursor: pointer;">Restart</button>
<button onclick="document.querySelector('audio').currentTime -= 10;" style="cursor: pointer;">-10s</button>
<button onclick="const aud = document.querySelector('audio'); aud.paused ? aud.play() : aud.pause(); document.querySelector('#ac-p').textContent = aud.paused ? 'Play' : 'Pause'" id="ac-p" style="cursor: pointer;">${document.querySelector("audio").paused?"Play":"Pause"}</button>
<button onclick="document.querySelector('audio').currentTime += 10;" style="cursor: pointer;">+10s</button>
<button onclick="const aud = document.querySelector('audio'); aud.muted = !aud.muted; document.querySelector('#ac-m').textContent = aud.muted ? 'Unmute' : 'Mute'" id="ac-m" style="cursor: pointer;">${document.querySelector("audio").loop?"Unmute":"Mute"}</button>
<button onclick="const aud = document.querySelector('audio'); aud.loop = !aud.loop; document.querySelector('#ac-l').textContent = aud.loop ? 'Loop ON' : 'Loop OFF'" id="ac-l" style="cursor: pointer;">${document.querySelector("audio").loop?"Loop ON":"Loop OFF"}</button>
`,document.body.appendChild(audControl),void 0):alert("No audio tags found")})();" title="To install, drag and drop this link to your bookmarks">aud-controller.js</a></p>
<pre><code>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 onclick="const aud = document.querySelector('audio'); aud.playbackRate -= 0.2; document.querySelector('#ac-s').textContent = aud.playbackRate.toFixed(1) + 'x'" style="cursor: pointer;">-</button>
<button onclick="const aud = document.querySelector('audio'); aud.playbackRate = 1; document.querySelector('#ac-s').textContent = aud.playbackRate.toFixed(1) + 'x'" style="cursor: pointer;">1x</button>
<button onclick="const aud = document.querySelector('audio'); aud.playbackRate = 2; document.querySelector('#ac-s').textContent = aud.playbackRate.toFixed(1) + 'x'" style="cursor: pointer;">2x</button>
<button onclick="const aud = document.querySelector('audio'); aud.playbackRate = 3; document.querySelector('#ac-s').textContent = aud.playbackRate.toFixed(1) + 'x'" style="cursor: pointer;">3x</button>
<button onclick="const aud = document.querySelector('audio'); aud.playbackRate += 0.2; document.querySelector('#ac-s').textContent = aud.playbackRate.toFixed(1) + 'x'" style="cursor: pointer;">+</button>
<button onclick="document.querySelector('audio').currentTime = 0;" style="cursor: pointer;">Restart</button>
<button onclick="document.querySelector('audio').currentTime -= 10;" style="cursor: pointer;">-10s</button>
<button onclick="const aud = document.querySelector('audio'); aud.paused ? aud.play() : aud.pause(); document.querySelector('#ac-p').textContent = aud.paused ? 'Play' : 'Pause'" id="ac-p" style="cursor: pointer;">${
document.querySelector('audio').paused ? 'Play' : 'Pause'
}</button>
<button onclick="document.querySelector('audio').currentTime += 10;" style="cursor: pointer;">+10s</button>
<button onclick="const aud = document.querySelector('audio'); aud.muted = !aud.muted; document.querySelector('#ac-m').textContent = aud.muted ? 'Unmute' : 'Mute'" id="ac-m" style="cursor: pointer;">${
document.querySelector('audio').loop ? 'Unmute' : 'Mute'
}</button>
<button onclick="const aud = document.querySelector('audio'); aud.loop = !aud.loop; document.querySelector('#ac-l').textContent = aud.loop ? 'Loop ON' : 'Loop OFF'" id="ac-l" style="cursor: pointer;">${
document.querySelector('audio').loop ? 'Loop ON' : 'Loop OFF'
}</button>
`;
document.body.appendChild(div);
})();
</code></pre>
<p>Video:
<a class='btn' href="javascript:(()=>{var vidControl=document.querySelector("#vidControl-div");return vidControl?vidControl.remove():document.querySelector("video")?((vidControl=document.createElement("div")).id="vidControl-div",vidControl.style.zIndex="9999",vidControl.style.position="fixed",vidControl.style.top="0%",vidControl.style.right="0%",vidControl.style.display="flex",vidControl.style.gap="0.2em",vidControl.style.padding="0.1em",vidControl.style.userSelect="none",vidControl.innerHTML=`
<button id="vc-s" style="pointer-events: none;">${document.querySelector("video").playbackRate.toFixed(1)}x</button>
<button onclick="const vid = document.querySelector('video'); vid.playbackRate -= 0.2; document.querySelector('#vc-s').textContent = vid.playbackRate.toFixed(1) + 'x'" style="cursor: pointer;">-</button>
<button onclick="const vid = document.querySelector('video'); vid.playbackRate = 1; document.querySelector('#vc-s').textContent = vid.playbackRate.toFixed(1) + 'x'" style="cursor: pointer;">1x</button>
<button onclick="const vid = document.querySelector('video'); vid.playbackRate = 2; document.querySelector('#vc-s').textContent = vid.playbackRate.toFixed(1) + 'x'" style="cursor: pointer;">2x</button>
<button onclick="const vid = document.querySelector('video'); vid.playbackRate = 3; document.querySelector('#vc-s').textContent = vid.playbackRate.toFixed(1) + 'x'" style="cursor: pointer;">3x</button>
<button onclick="const vid = document.querySelector('video'); vid.playbackRate += 0.2; document.querySelector('#vc-s').textContent = vid.playbackRate.toFixed(1) + 'x'" style="cursor: pointer;">+</button>
<button onclick="document.querySelector('video').currentTime = 0;" style="cursor: pointer;">Restart</button>
<button onclick="document.querySelector('video').currentTime -= 10;" style="cursor: pointer;">-10s</button>
<button onclick="const vid = document.querySelector('video'); vid.paused ? vid.play() : vid.pause(); document.querySelector('#vc-p').textContent = vid.paused ? 'Play' : 'Pause'" id="vc-p" style="cursor: pointer;">${document.querySelector("video").paused?"Play":"Pause"}</button>
<button onclick="document.querySelector('video').currentTime += 10;" style="cursor: pointer;">+10s</button>
<button onclick="const vid = document.querySelector('video'); vid.muted = !vid.muted; document.querySelector('#vc-m').textContent = vid.muted ? 'Unmute' : 'Mute'" id="vc-m" style="cursor: pointer;">${document.querySelector("video").loop?"Unmute":"Mute"}</button>
<button onclick="const vid = document.querySelector('video'); vid.loop = !vid.loop; document.querySelector('#vc-l').textContent = vid.loop ? 'Loop ON' : 'Loop OFF'" id="vc-l" style="cursor: pointer;">${document.querySelector("video").loop?"Loop ON":"Loop OFF"}</button>
`,document.body.appendChild(vidControl),void 0):alert("No video tags found")})();" title="To install, drag and drop this link to your bookmarks">vid-controller.js</a></p>
<pre><code>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 onclick="const vid = document.querySelector('video'); vid.playbackRate -= 0.2; document.querySelector('#vc-s').textContent = vid.playbackRate.toFixed(1) + 'x'" style="cursor: pointer;">-</button>
<button onclick="const vid = document.querySelector('video'); vid.playbackRate = 1; document.querySelector('#vc-s').textContent = vid.playbackRate.toFixed(1) + 'x'" style="cursor: pointer;">1x</button>
<button onclick="const vid = document.querySelector('video'); vid.playbackRate = 2; document.querySelector('#vc-s').textContent = vid.playbackRate.toFixed(1) + 'x'" style="cursor: pointer;">2x</button>
<button onclick="const vid = document.querySelector('video'); vid.playbackRate = 3; document.querySelector('#vc-s').textContent = vid.playbackRate.toFixed(1) + 'x'" style="cursor: pointer;">3x</button>
<button onclick="const vid = document.querySelector('video'); vid.playbackRate += 0.2; document.querySelector('#vc-s').textContent = vid.playbackRate.toFixed(1) + 'x'" style="cursor: pointer;">+</button>
<button onclick="document.querySelector('video').currentTime = 0;" style="cursor: pointer;">Restart</button>
<button onclick="document.querySelector('video').currentTime -= 10;" style="cursor: pointer;">-10s</button>
<button onclick="const vid = document.querySelector('video'); vid.paused ? vid.play() : vid.pause(); document.querySelector('#vc-p').textContent = vid.paused ? 'Play' : 'Pause'" id="vc-p" style="cursor: pointer;">${
document.querySelector('video').paused ? 'Play' : 'Pause'
}</button>
<button onclick="document.querySelector('video').currentTime += 10;" style="cursor: pointer;">+10s</button>
<button onclick="const vid = document.querySelector('video'); vid.muted = !vid.muted; document.querySelector('#vc-m').textContent = vid.muted ? 'Unmute' : 'Mute'" id="vc-m" style="cursor: pointer;">${
document.querySelector('video').loop ? 'Unmute' : 'Mute'
}</button>
<button onclick="const vid = document.querySelector('video'); vid.loop = !vid.loop; document.querySelector('#vc-l').textContent = vid.loop ? 'Loop ON' : 'Loop OFF'" id="vc-l" style="cursor: pointer;">${
document.querySelector('video').loop ? 'Loop ON' : 'Loop OFF'
}</button>
`;
document.body.appendChild(div);
})();
</code></pre>
<h4>Toggles default HTML5 audio/video controls</h4>
<p>Toggles the default HTML5 audio/video controls and remove all <code>controlsList</code> attributes.</p>
<p>Audio:
<a class='btn' href="javascript:(()=>{var aud=document.querySelector("audio");return aud?(aud.controls=!aud.controls,console.log("ControlsList before overwrite:",aud.controlsList),aud.controlsList="",console.log("ControlsList after overwrite:",aud.controlsList),void 0):alert("No audio tags found")})();" title="To install, drag and drop this link to your bookmarks">aud-toggle-ctrl.js</a></p>
<pre><code>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);
})();
</code></pre>
<p>Video:
<a class='btn' href="javascript:(()=>{var vid=document.querySelector("video");return vid?(vid.controls=!vid.controls,console.log("ControlsList before overwrite:",vid.controlsList),vid.controlsList="",console.log("ControlsList after overwrite:",vid.controlsList),void 0):alert("No video tags found")})();" title="To install, drag and drop this link to your bookmarks">vid-toggle-ctrl.js</a></p>
<pre><code>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);
})();
</code></pre>
<h4>Change audio/video playback speed</h4>
<p>Changes the first audio/video's playback speed, should work with youtube/vimeo and etc, also shows the current playback speed.</p>
<p>Audio:
<a class='btn' href="javascript:(()=>{var x,aud=document.querySelector("audio");return aud?(x=prompt(`Playback Speed? (Current: ${aud.playbackRate})`),aud.playbackRate=parseFloat(x),void 0):alert("No audio tags found")})();" title="To install, drag and drop this link to your bookmarks">aud-speed.js</a></p>
<pre><code>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);
})();
</code></pre>
<p>Video:
<a class='btn' href="javascript:(()=>{var x,vid=document.querySelector("video");return vid?(x=prompt(`Playback Speed? (Current: ${vid.playbackRate})`),vid.playbackRate=parseFloat(x),void 0):alert("No video tags found")})();" title="To install, drag and drop this link to your bookmarks">vid-speed.js</a></p>
<pre><code>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);
})();
</code></pre>
<h4>Change all audios/videos playback speed</h4>
<p>Useful if there are multiple audios/videos in a single page, changes the playback speed for all audios/videos.</p>
<p>Audio:
<a class='btn' href="javascript:(()=>{var aud=document.querySelectorAll("audio");if(0===aud.length)return alert("No audio tags found");const x=prompt("Playback Speed?");aud.forEach(a=>a.playbackRate=parseFloat(x))})();" title="To install, drag and drop this link to your bookmarks">aud-speed-all.js</a></p>
<pre><code>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)));
})();
</code></pre>
<p>Video:
<a class='btn' href="javascript:(()=>{var vid=document.querySelectorAll("video");if(0===vid.length)return alert("No video tags found");const x=prompt("Playback Speed?");vid.forEach(v=>v.playbackRate=parseFloat(x))})();" title="To install, drag and drop this link to your bookmarks">vid-speed-all.js</a></p>
<pre><code>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)));
})();
</code></pre>
<h4>Play/pause audio or audio/video</h4>
<p>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.</p>
<p>Audio:
<a class='btn' href="javascript:(()=>{var aud=document.querySelector("audio");return aud?(aud.paused?aud.play():aud.pause(),void 0):alert("No audio tags found")})();" title="To install, drag and drop this link to your bookmarks">aud-play-pause.js</a></p>
<pre><code>javascript: (() => {
const aud = document.querySelector('audio');
if (!aud) {
return alert('No audio tags found');
}
aud.paused ? aud.play() : aud.pause();
})();
</code></pre>
<p>Video:
<a class='btn' href="javascript:(()=>{var vid=document.querySelector("video");return vid?(vid.paused?vid.play():vid.pause(),void 0):alert("No video tags found")})();" title="To install, drag and drop this link to your bookmarks">vid-play-pause.js</a></p>
<pre><code>javascript: (() => {
const vid = document.querySelector('video');
if (!vid) {
return alert('No video tags found');
}
vid.paused ? vid.play() : vid.pause();
})();
</code></pre>
<h2>Check for iframes and show their source URL</h2>
<p>Handy bookmarklet to check for iframes on a website.</p>
<h4>Show iframes in separate panel</h4>
<p>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.</p>
<p>Note: Due to the use of <code>innerHTML</code>, this bookmarklet will not work on sites that require <a href="https://developer.mozilla.org/en-US/docs/Web/API/TrustedHTML">TrustedHTML</a> assignment (CSP). In such cases, use the other bookmarklets below instead.</p>
<p><a class='btn' href="javascript:(()=>{var ipd=document.querySelector("#iframe-panel-div");if(ipd)return ipd.remove();ipd=document.querySelectorAll("iframe");if(0===ipd.length)return alert("No iframes found");var 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="";ipd.forEach(i=>{buttons+=""===i.src?'<button style="pointer-events: none;">This iframe has no source</button>':`<button onclick="window.open('${i.src}', '_blank');" 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;"> ${ipd.length} iframe(s) found, source(s) below
</button>
<button onclick="document.querySelectorAll('iframe').forEach(i => i.remove())" 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)})();" title="To install, drag and drop this link to your bookmarks">iframe-panel.js</a></p>
<pre><code>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 onclick="window.open('${i.src}', '_blank');" 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 onclick="document.querySelectorAll('iframe').forEach(i => i.remove())" 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);
})();
</code></pre>
<h4>Show iframes in an alert dialog</h4>
<p>Less versatile but works if the above bookmarklet doesn't.</p>
<p><a class='btn' href="javascript:(()=>{var iframes=document.querySelectorAll("iframe");if(0===iframes.length)return alert("No iframes found");let src="";iframes.forEach((i,idx)=>src+=`${idx+1}: ${i.src}, `),alert(iframes.length+" iframes found, "+src)})();" title="To install, drag and drop this link to your bookmarks">iframe-alert.js</a></p>
<pre><code>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}`);
})();
</code></pre>
<h2>Color sampler bookmarklets</h2>
<p>Some bookmarklets that help with color sampling.</p>
<h4>Using the EyeDropper API</h4>
<p>Uses the <a href="https://developer.mozilla.org/en-US/docs/Web/API/EyeDropper">EyeDropper API</a>, unfortunately it is not supported in Firefox and Safari at the time of writing (Dec 2023).</p>
<p>Also converts the HEX code to RGB and HSL values, code for converting RGB to HSL referenced from <a href="https://www.30secondsofcode.org/js/s/rgb-to-hsl/">https://www.30secondsofcode.org/js/s/rgb-to-hsl/</a></p>
<p><a class='btn' href="javascript:void(void 0===window.EyeDropper?(alert("Your browser doens't support the EyeDropper API"),void 0):(new EyeDropper).open().then(res=>{var hex=res.sRGBHex,r=parseInt(hex.slice(1,3),16),g=parseInt(hex.slice(3,5),16),hex=parseInt(hex.slice(5),16);alert(`Color is ${res.sRGBHex}, rgb(${r} ${g} ${hex}), hsl(${((r,g,b)=>{r/=255,g/=255,b/=255;var l=Math.max(r,g,b),s=l-Math.min(r,g,b),b=0!=s?l===r?(g-b)/s:l===g?2+(b-r)/s:4+(r-g)/s:0;return[(60*b<0?60*b+360:60*b).toFixed(2),(100*(s?l<=.5?s/(2*l-s):s/(2-(2*l-s)):0)).toFixed(2)+"%",(100*(2*l-s)/2).toFixed(2)+"%"]})(r,g,hex).join(" ")})`)}).catch(e=>alert("Error: "+e)));" title="To install, drag and drop this link to your bookmarks">color-eyedropper.js</a></p>
<pre><code>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}`));
})();
</code></pre>
<h4>New popup window with color input element</h4>
<p>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 <a href="https://css-tricks.com/web-development-bookmarklets/#comment-1795325">https://css-tricks.com/web-development-bookmarklets/#comment-1795325</a>, lightly modified for readability and to set the popup on the bottom right corner.</p>
<p><a class='btn' href="javascript:(()=>{var windowFeatures=`
popup,
width=100,
height=100,
left=${window.screen.availWidth},
top=${window.screen.availHeight},
`;window.open("","",windowFeatures).document.body.innerHTML='<input type="color">'})();" title="To install, drag and drop this link to your bookmarks">color-popup.js</a></p>
<pre><code>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">';
})();
</code></pre>
<h2>Toggle designMode</h2>
<p>Toggles <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/designMode">designMode</a> to make website editable.</p>
<p><a class='btn' href="javascript:void(document.designMode="on"===document.designMode?"off":"on");" title="To install, drag and drop this link to your bookmarks">toggle-designmode.js</a></p>
<pre><code>javascript: (() => {
document.designMode = document.designMode === 'on' ? 'off' : 'on';
})();
</code></pre>
<h2>Check website data</h2>
<p>Reads and displays your cookie data.</p>
<p><a class='btn' href="javascript:alert(document.cookie||"No cookies found");" title="To install, drag and drop this link to your bookmarks">show-cookies.js</a></p>
<pre><code>javascript: (() => alert(document.cookie || 'No cookies found'))();
</code></pre>
<p>Reads and displays your localStorage data.</p>
<p><a class='btn' href="javascript:(()=>{if(0===window.localStorage.length)return alert("No data in localStorage found");let str="";for(var[k,v]of Object.entries(window.localStorage))str+=`key:${k}, val:${v}, `;alert(str)})();" title="To install, drag and drop this link to your bookmarks">show-localstorage.js</a></p>
<pre><code>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);
})();
</code></pre>
<p>Reads and displays your sessionStorage data.</p>
<p><a class='btn' href="javascript:(()=>{if(0===window.sessionStorage.length)return alert("No data in sessionStorage found");let str="";for(var[k,v]of Object.entries(window.sessionStorage))str+=`key:${k}, val:${v}, `;alert(str)})();" title="To install, drag and drop this link to your bookmarks">show-sessionstorage.js</a></p>
<pre><code>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);
})();
</code></pre>
<h2>Slightly improve website readability</h2>
<p>Simple bookmarklet to center the webpage, limit the width, and change the line height. Usually only works on simple websites, might break certain websites.</p>
<p><a class='btn' href="javascript:(b=document.body.style).margin="1em auto",b.maxWidth="80ch",void(b.lineHeight="1.5");" title="To install, drag and drop this link to your bookmarks">simple-center.js</a></p>
<pre><code>javascript: (() => {
b = document.body.style;
b.margin = '1em auto';
b.maxWidth = '80ch';
b.lineHeight = '1.5';
})();
</code></pre>
<h2>Create a simple notepad on the browser</h2>
<p>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 <a href="https://developer.mozilla.org/en-US/docs/web/http/basics_of_http/data_urls">data URL</a> instead.</p>
<p>Alternatively, you could use something like <a href="https://browserpad.org/">https://browserpad.org/</a> which saves your data to localStorage instead.</p>
<h4>Plain text only</h4>
<pre><code>data:text/html, <html contenteditable='plaintext-only'>
</code></pre>
<h4>Able to accept html formatting (when copy/paste from other websites)</h4>
<pre><code>data:text/html, <html contenteditable>
</code></pre>
<h2>Bookmarklets by others that I found useful</h2>
<h4>Kill Sticky</h4>
<p>As the name implies, it's a bookmarklet that kills sticky content.</p>
<p><a href="https://github.com/t-mart/kill-sticky">https://github.com/t-mart/kill-sticky</a></p>
<p>Here's a modified version I use that doesn't remove position fixed/sticky but makes them static instead.</p>
<p><a class='btn' href="javascript:(()=>{document.querySelectorAll("body *").forEach(node=>{["fixed","sticky"].includes(getComputedStyle(node).position)&&(node.style.position="static")}),document.querySelectorAll("html *").forEach(node=>{var s=getComputedStyle(node);"hidden"===s.overflow&&(node.style.overflow="visible"),"hidden"===s["overflow-x"]&&(node.style["overflow-x"]="visible"),"hidden"===s["overflow-y"]&&(node.style["overflow-y"]="visible")});var htmlNode=document.querySelector("html");htmlNode.style.overflow="visible",htmlNode.style["overflow-x"]="visible",htmlNode.style["overflow-y"]="visible"})();" title="To install, drag and drop this link to your bookmarks">kill-sticky-mod.js</a></p>
<pre><code>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';
})();
</code></pre>
<h4>Kick ass app</h4>
<p>Cool bookmarklet that lets you 'destroy' websites.</p>
<p><a href="https://kickassapp.com/">https://kickassapp.com/</a></p>
<h4>Web development bookmarklets from CSS-tricks</h4>
<p>Some useful bookmarklets for web development, more available in the comments section.</p>
<p><a href="https://css-tricks.com/web-development-bookmarklets/">https://css-tricks.com/web-development-bookmarklets/</a></p>
<h2>Some resources on making bookmarklets</h2>
<p><a href="https://www.freecodecamp.org/news/what-are-bookmarklets/">https://www.freecodecamp.org/news/what-are-bookmarklets/</a></p>
<p><a href="https://gist.github.com/caseywatts/c0cec1f89ccdb8b469b1">https://gist.github.com/caseywatts/c0cec1f89ccdb8b469b1</a></p>
<p><a href="https://make-bookmarklets.com/">https://make-bookmarklets.com/</a></p>
<h2>How to contribute</h2>
<p>If you would like to contribute to this project, feel free to:</p>
<ol>
<li><a href="https://github.com/bk7312/bookmarklets/issues">Raise an issue</a> - Let me know if there's any bugs or bookmarklet request and I'll see what I can do.</li>
<li><a href="https://github.com/bk7312/bookmarklets/pulls">Create a pull request</a> - 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.</li>
</ol>
<p>How to add a new bookmarklet to this repo:</p>
<ol>
<li>Fork or clone this repo and run <code>npm i</code> to install the required package, make sure you already have node.js installed.</li>
<li>Create a new <code>bookmarklets/bookmarklet-name.js</code> script for the bookmarklet you want to add.</li>
<li>Update <code>template/readme_template.md</code> to include a description and add <code>@bookmarklet-name.js</code> on a new line after your description.</li>
<li>Run <code>npm run build</code> to generate the updated <code>README.md</code> and <code>index.html</code> with the new bookmarklet.</li>
<li>Create a PR.</li>
</ol>
</body>
</html>