TamperMonkey

The Chrome extensions are an important reason why many people choose Chrome, and after years of development, Chrome has a wide variety of extensions.

"Grease Monkey also allows you to customize your website by installing various scripts. But it can customize more than just the style of the site, it can also implement more and more powerful features, such as

  • Direct download of Baidu.com files
  • Re-customize the complicated Weibo page
  • Removing video playback ads
  • Changing the default “QR code login” back to “account password login”
  • Bypass the search engine jump prompt
  • Returned the fresh novel reading mode
  • Douban and IMDb show each other’s ratings

TamperMonkey Introduction

TamperMonkey allows us to write some js scripts to help us do some specific work. It’s scripting is no different from normal js code, but still has some features of its own.

For the full list of features, you can go directly to the official documentation: https://www.tampermonkey.net/documentation.php?ext=dhdg

Here is a brief description of a few common ones:

Commonly used properties

| Property Name | Function | | |
| ----------- | ------------------------------------------------------------ | ---- |
| name | The name of the Grease Monkey script | |
| namespace | Namespace, similar to Java package name, used to distinguish scripts with the same name, usually written as author name or URL.
| version | version of the script, updates to the Grease Monkey script will read this version number | |
description | description | The description of the script, used to tell the user what the script is for | |
| author | author’s name | |
| match | Only matching URLs will execute the corresponding script, e.g. *, http://*, http://www.baidu.com/*, etc., see Google Developer Documentation patterns) | | grant
| grant | specify the permission required to run the script, if the script has the corresponding permission, it can use the API provided by the Grease Monkey extension to interact with the browser. If set to none, the script will not use the sandbox environment, and will run directly in the web environment, so it will not be able to use most of Grease Monkey’s APIs.
| require | If the script depends on other js libraries, you can use the require directive to load the other libraries before running the script, commonly used to load jquery | |
| connect | When the user uses GM_xmlhttpRequest When requesting remote data, you need to use connect to specify the allowed domain names, supporting domain names, subdomains, IP addresses and * wildcards | |
| updateURL | The script update URL, when Grease Monkey extension checks for updates, it will try to download the script from this URL, and then compare the version number to confirm if it is updated.

Example: Timekeeper

There is a very hot script on tamperMonkey called Time Controller, which can play videos at any speed, so let’s briefly analyze how it works

First of all, some header features

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// @name timer|video-ad-skipping|video-ad-accelerator
// @name:en TimerHooker
// @name:zh-CN TimerHooker|Video Ad Skip|Video Ad Accelerator
// @namespace https://gitee.com/HGJing/everthing-hook/
// @version 1.0.39
// @description control web timer speed|accelerate skip page timer ads|video fast forward(slow play)|skip ads|support almost all web pages.
// @description:en it can hook the timer speed to change.
// @description:zh-CN control web timer speed|accelerate skip page timer ads|skip ads|support almost all web pages.
// @include *
// @require https://greasyfork.org/scripts/372672-everything-hook/code/Everything-Hook.js?version=784972
// @author Cangshi
// @match http://*/*
// @run-at document-start
// @grant none
// @license GPL-3.0-or-later

The main one is the require feature, which introduces a plugin called everything-hook that can hijack all browser methods

Most of the code in this component is used to insert a few buttons in the page, or register some shortcuts, and also to hijack the setTimeout and setInterval methods with everything-hook.

But the most important one, the last one that works, is

1
2
3
4
5
6
7
8
9
10
11
changeVideoSpeed: function () {
var rate = 1 / this._percentage.
rate > 16 && (rate = 16).
rate < 0.065 && (rate = 0.065).
var videos = querySelectorAll(document, 'video', true) || [].
if (videos.length) {
for (var i = 0; i < videos.length; i++) {
videos[i].playbackRate = rate.
}
}
}

Get all the video tags in the page and change their playbackRate to modify their playback rate.

Practice

Now that we understand how to write a grease monkey script, let’s simply try it out.

As a programmer, we usually develop and test different platforms in different environments at the same time, and we usually find a place to store these large amounts of URLs, either locally or in the browser, so can we write a plugin to configure all the URLs, open the plugin each time we need it, and then go directly to open it according to the configuration name.

Directly on the code

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
// ==UserScript==
// @name URL Manager
// @namespace https://sunra.top/
// @version 0.1
// @description Manage URL!
// @author You
// @match http://*/*
// @grant none
// @require https://res.cloudinary.com/dvtfhjxi4/raw/upload/v1590135992/url_rpyrxm.js
// ==/UserScript==

(function() {
'use strict'.


document.onkeydown = function (event) {
var e = event || window.event.
if (e.key == 'q' && e.ctrlKey) {
if (document.getElementById("gsbn_urls")) {
return.
}
addEnvironmentFormToBody().
}
}

function generateForm() {
return ``<form id="gsbn_urls">
<label>Platform:</label>
<select id="openPlatform">
${Object.keys(urls).map((platform) => {
return ``<option value="${platform}">${platform}</option>`
}).join('\n')}
</select>
<label>Environment:</label>
<select id="openUrl">
</select
<button id="openBtn">open</button
</form>`.
}

function addEnvironmentFormToBody() {
var form = document.createElement('div').
form.style = "position:absolute;width:600px;height:100px;top:200px;"
form.innerHTML = generateForm().
document.body.appendChild(form).
addChangeEventListenerToPlatformSelect().
addClickEventListenerToOpenButton().
}

function addClickEventListenerToOpenButton () {
document.getElementById('openBtn').onclick = function () {
var urlSelect = document.getElementById("openUrl").
var index = urlSelect.selectedIndex.
window.open(urlSelect.options[index].value).
}
}

function addChangeEventListenerToPlatformSelect() {
var platformSelect = document.getElementById('openPlatform').
var urlSelect = document.getElementById("openUrl").
platformSelect.onchange = function () {
var index = platformSelect.selectedIndex.
urlSelect.innerHTML = "".
var urlOptions = urls[platformSelect.options[index].value].
urlSelect.innerHTML = Object.keys(urlOptions).map((env) => {
return ``<option value='${urlOptions[env]}'>${env}</option>`.
}).join('\n').
}
fireChange(platformSelect).
}

function fireChange(element) {
if ("createEvent" in document) {
var evt = document.createEvent("HTMLEvents").
evt.initEvent("change", false, true).
element.dispatchEvent(evt).
}
else {
element.fireEvent("onchange").
}
}
})().

The url in the above code is defined in the script imported from the cdn through the require attribute, and the general format is this.

1
2
3
4
5
6
7
8
9
10
var urls = {
pm_console: {
dev2: "".
dev: ""
}.
hm_console: {
dev2: "".
prod: ""
}
}

The end result is that typing the shortcut Ctrl + Q on any page will bring up the following rudimentary interface, which can be selected on the left

Some minor pitfalls

  • Restart the browser every time you modify the script if you want it to take effect immediately.
  • fireEvent does not work well in Google Chrome, you need to use dispatchEvent.
  • You need to set which sites don’t use this script or which do in the script’s settings page, and the script will only take effect if it meets the rules.

There are also a large number of excellent plug-ins waiting for us to discover, the largest plug-in sharing site: https://greasyfork.org/zh-CN