tampermonkey

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Tampermonkey Userscript Development

Tampermonkey用户脚本开发

Expert guidance for writing Tampermonkey userscripts - browser scripts that modify web pages, automate tasks, and enhance browsing experience.
编写Tampermonkey用户脚本的专业指南——这类浏览器脚本可修改网页、自动化任务并增强浏览体验。

Quick Start Template

快速入门模板

javascript
// ==UserScript==
// @name         My Script Name                    // ← CUSTOMISE: Unique script name
// @namespace    https://example.com/scripts/      // ← CUSTOMISE: Your unique namespace
// @version      1.0.0                             // ← INCREMENT on updates
// @description  Brief description of the script   // ← CUSTOMISE: What it does
// @author       Your Name                         // ← CUSTOMISE: Your name
// @match        https://example.com/*             // ← CUSTOMISE: Target URL pattern
// @grant        none                              // ← ADD permissions as needed
// @run-at       document-idle                     // ← ADJUST timing if needed
// ==/UserScript==

(function() {
    'use strict';

    // Your code here
    console.log('Script loaded!');
})();

javascript
// ==UserScript==
// @name         My Script Name                    // ← 自定义:唯一的脚本名称
// @namespace    https://example.com/scripts/      // ← 自定义:你的唯一命名空间
// @version      1.0.0                             // ← 更新时递增版本号
// @description  Brief description of the script   // ← 自定义:脚本功能简介
// @author       Your Name                         // ← 自定义:你的姓名
// @match        https://example.com/*             // ← 自定义:目标URL匹配规则
// @grant        none                              // ← 根据需要添加权限
// @run-at       document-idle                     // ← 根据需要调整注入时机
// ==/UserScript==

(function() {
    'use strict';

    // 你的代码写在这里
    console.log('Script loaded!');
})();

Essential Header Tags

核心头部标签

TagRequiredPurposeExample
@name
YesScript name (supports i18n with
:locale
)
@name My Script
@namespace
RecommendedUnique identifier namespace
@namespace https://yoursite.com/
@version
Yes*Version for updates (*required for auto-update)
@version 1.2.3
@description
RecommendedWhat the script does
@description Enhances page layout
@match
Yes**URLs to run on (**or @include)
@match https://example.com/*
@grant
SituationalAPI permissions (use
none
for no GM_* APIs)
@grant GM_setValue
@run-at
OptionalWhen to inject (default:
document-idle
)
@run-at document-start
For complete header documentation, see: header-reference.md

标签是否必填用途示例
@name
脚本名称(支持通过
:locale
实现多语言)
@name My Script
@namespace
推荐唯一标识符命名空间
@namespace https://yoursite.com/
@version
是*版本号(*自动更新必填)
@version 1.2.3
@description
推荐脚本功能说明
@description 增强页面布局
@match
是**脚本运行的URL(**或使用@include)
@match https://example.com/*
@grant
按需API权限(使用
none
表示不使用GM_* API)
@grant GM_setValue
@run-at
可选脚本注入时机(默认:
document-idle
@run-at document-start
完整头部标签文档请参考: header-reference.md

URL Matching Quick Reference

URL匹配快速参考

javascript
// Exact domain
// @match https://example.com/*

// All subdomains
// @match https://*.example.com/*

// HTTP and HTTPS
// @match *://example.com/*

// Specific path
// @match https://example.com/app/*

// Exclude paths (use with @match)
// @exclude https://example.com/admin/*
For advanced patterns (regex, @include), see: url-matching.md

javascript
// 精确匹配域名
// @match https://example.com/*

// 匹配所有子域名
// @match https://*.example.com/*

// 匹配HTTP和HTTPS协议
// @match *://example.com/*

// 匹配特定路径
// @match https://example.com/app/*

// 排除特定路径(需与@match配合使用)
// @exclude https://example.com/admin/*
高级匹配规则(正则表达式、@include)请参考: url-matching.md

@grant Permissions Quick Reference

@grant权限快速参考

You Need To...Grant This
Store persistent data
@grant GM_setValue
+
@grant GM_getValue
Make cross-origin requests
@grant GM_xmlhttpRequest
+
@connect domain
Add custom CSS
@grant GM_addStyle
Access page's window
@grant unsafeWindow
Show notifications
@grant GM_notification
Add menu commands
@grant GM_registerMenuCommand
Detect URL changes (SPA)
@grant window.onurlchange
javascript
// Disable sandbox (no GM_* except GM_info)
// @grant none

// Cross-origin requests require @connect
// @grant GM_xmlhttpRequest
// @connect api.example.com
// @connect *.googleapis.com
For complete permissions guide, see: header-reference.md

你需要...需授权
存储持久化数据
@grant GM_setValue
+
@grant GM_getValue
发起跨域请求
@grant GM_xmlhttpRequest
+
@connect domain
添加自定义CSS
@grant GM_addStyle
访问页面的window对象
@grant unsafeWindow
显示通知
@grant GM_notification
添加菜单命令
@grant GM_registerMenuCommand
检测SPA的URL变化
@grant window.onurlchange
javascript
// 禁用沙箱(仅可使用GM_info,不可用其他GM_* API)
// @grant none

// 跨域请求需配合@connect
// @grant GM_xmlhttpRequest
// @connect api.example.com
// @connect *.googleapis.com
完整权限指南请参考: header-reference.md

@run-at Injection Timing

@run-at注入时机

ValueWhen Script RunsUse Case
document-start
Before DOM existsBlock resources, modify globals early
document-body
When body existsEarly DOM manipulation
document-end
At DOMContentLoadedMost scripts - DOM ready
document-idle
After DOMContentLoaded (default)Safe default
context-menu
On right-click menuUser-triggered actions

脚本运行时机适用场景
document-start
DOM创建前阻止资源加载、提前修改全局变量
document-body
body标签存在时早期DOM操作
document-end
DOMContentLoaded事件触发时大多数脚本——DOM已就绪
document-idle
DOMContentLoaded事件后(默认)安全的默认选项
context-menu
右键菜单触发时用户触发的操作

Common Patterns

常见实现模式

Wait for Element

等待元素加载

javascript
function waitForElement(selector, timeout = 10000) {
    return new Promise((resolve, reject) => {
        const element = document.querySelector(selector);
        if (element) return resolve(element);

        const observer = new MutationObserver((mutations, obs) => {
            const el = document.querySelector(selector);
            if (el) {
                obs.disconnect();
                resolve(el);
            }
        });

        observer.observe(document.body, { childList: true, subtree: true });

        setTimeout(() => {
            observer.disconnect();
            reject(new Error(`Element ${selector} not found`));
        }, timeout);
    });
}

// Usage
waitForElement('#my-element').then(el => {
    console.log('Found:', el);
});
javascript
function waitForElement(selector, timeout = 10000) {
    return new Promise((resolve, reject) => {
        const element = document.querySelector(selector);
        if (element) return resolve(element);

        const observer = new MutationObserver((mutations, obs) => {
            const el = document.querySelector(selector);
            if (el) {
                obs.disconnect();
                resolve(el);
            }
        });

        observer.observe(document.body, { childList: true, subtree: true });

        setTimeout(() => {
            observer.disconnect();
            reject(new Error(`Element ${selector} not found`));
        }, timeout);
    });
}

// 使用示例
waitForElement('#my-element').then(el => {
    console.log('找到元素:', el);
});

SPA URL Change Detection

SPA URL变化检测

javascript
// @grant window.onurlchange

if (window.onurlchange === null) {
    window.addEventListener('urlchange', (info) => {
        console.log('URL changed to:', info.url);
        // Re-run your modifications
    });
}
javascript
// @grant window.onurlchange

if (window.onurlchange === null) {
    window.addEventListener('urlchange', (info) => {
        console.log('URL已变更为:', info.url);
        // 重新执行你的修改逻辑
    });
}

Cross-Origin Request

跨域请求

javascript
// @grant GM_xmlhttpRequest
// @connect api.example.com

GM_xmlhttpRequest({
    method: 'GET',
    url: 'https://api.example.com/data',
    headers: { 'Content-Type': 'application/json' },
    onload: function(response) {
        const data = JSON.parse(response.responseText);
        console.log(data);
    },
    onerror: function(error) {
        console.error('Request failed:', error);
    }
});
javascript
// @grant GM_xmlhttpRequest
// @connect api.example.com

GM_xmlhttpRequest({
    method: 'GET',
    url: 'https://api.example.com/data',
    headers: { 'Content-Type': 'application/json' },
    onload: function(response) {
        const data = JSON.parse(response.responseText);
        console.log(data);
    },
    onerror: function(error) {
        console.error('请求失败:', error);
    }
});

Add Custom Styles

添加自定义样式

javascript
// @grant GM_addStyle

GM_addStyle(`
    .my-custom-class {
        background: #f0f0f0;
        padding: 10px;
        border-radius: 5px;
    }

    #hide-this-element {
        display: none !important;
    }
`);
javascript
// @grant GM_addStyle

GM_addStyle(`
    .my-custom-class {
        background: #f0f0f0;
        padding: 10px;
        border-radius: 5px;
    }

    #hide-this-element {
        display: none !important;
    }
`);

Persistent Settings

持久化设置

javascript
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_registerMenuCommand

const settings = {
    enabled: GM_getValue('enabled', true),
    theme: GM_getValue('theme', 'dark')
};

GM_registerMenuCommand('Toggle Enabled', () => {
    settings.enabled = !settings.enabled;
    GM_setValue('enabled', settings.enabled);
    location.reload();
});
For more patterns, see: patterns.md

javascript
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_registerMenuCommand

const settings = {
    enabled: GM_getValue('enabled', true),
    theme: GM_getValue('theme', 'dark')
};

GM_registerMenuCommand('切换启用状态', () => {
    settings.enabled = !settings.enabled;
    GM_setValue('enabled', settings.enabled);
    location.reload();
});
更多实现模式请参考: patterns.md

External Resources

外部资源

@require - Load External Scripts

@require - 加载外部脚本

javascript
// @require https://code.jquery.com/jquery-3.6.0.min.js

// With integrity hash (recommended)
// @require https://code.jquery.com/jquery-3.6.0.min.js#sha256-/xUj+3OJU...

// Built-in libraries
// @require tampermonkey://vendor/jquery.js
javascript
// @require https://code.jquery.com/jquery-3.6.0.min.js

// 带完整性哈希(推荐)
// @require https://code.jquery.com/jquery-3.6.0.min.js#sha256-/xUj+3OJU...

// 内置库
// @require tampermonkey://vendor/jquery.js

@resource - Preload Resources

@resource - 预加载资源

javascript
// @resource myCSS https://example.com/style.css
// @grant GM_getResourceText
// @grant GM_addStyle

const css = GM_getResourceText('myCSS');
GM_addStyle(css);

javascript
// @resource myCSS https://example.com/style.css
// @grant GM_getResourceText
// @grant GM_addStyle

const css = GM_getResourceText('myCSS');
GM_addStyle(css);

What Tampermonkey Cannot Do

Tampermonkey的限制

Userscripts have limitations:
  • Access local files - Cannot read/write files on your computer
  • Run before page scripts - In isolated sandbox mode, page scripts run first
  • Access cross-origin iframes - Browser security prevents this
  • Persist across machines - GM storage is local to each browser
  • Bypass all CSP - Some very strict CSP cannot be bypassed
Most limitations have workarounds - see common-pitfalls.md.

用户脚本存在以下限制:
  • 访问本地文件 - 无法读取/写入本地计算机上的文件
  • 优先于页面脚本运行 - 在隔离沙箱模式下,页面脚本会先运行
  • 访问跨域iframe - 浏览器安全机制阻止此操作
  • 跨设备同步 - GM存储仅对当前浏览器本地有效
  • 绕过所有CSP - 部分严格的CSP无法被绕过
大多数限制都有解决方案 - 请参考 common-pitfalls.md

When Generating Userscripts

生成用户脚本的规范

Always include in your response:
  1. Explanation - What the script does (1-2 sentences)
  2. Complete userscript - Full code with all headers in a code block
  3. Installation - "Copy/paste into Tampermonkey dashboard" or "Save as .user.js"
  4. Customisation points - What the user can safely modify (selectors, timeouts, etc.)
  5. Permissions used - Which @grants and why they're needed
  6. Browser support - If Chrome-only, Firefox-only, or universal
Example response format:
This script adds a dark mode toggle to Example.com and remembers the user's preference.
javascript
// ==UserScript==
// @name         Example.com Dark Mode
// ...
// ==/UserScript==
Installation: Copy/paste into Tampermonkey dashboard Customisation: Change
DARK_BG_COLOR
to adjust the background colour Permissions: Uses
GM_setValue
/
GM_getValue
to remember preference Browsers: Chrome and Firefox

返回用户脚本时需包含以下内容:
  1. 功能说明 - 脚本的作用(1-2句话)
  2. 完整用户脚本 - 包含所有头部标签的完整代码,放在代码块中
  3. 安装方法 - "复制粘贴到Tampermonkey控制台" 或 "保存为.user.js文件"
  4. 可自定义项 - 用户可安全修改的内容(选择器、超时时间等)
  5. 使用的权限 - 使用了哪些@grant权限及原因
  6. 浏览器支持 - 是否仅支持Chrome、仅支持Firefox,或全平台兼容
示例返回格式:
该脚本为Example.com添加深色模式切换功能,并记住用户的偏好设置。
javascript
// ==UserScript==
// @name         Example.com Dark Mode
// ...
// ==/UserScript==
安装方法: 复制粘贴到Tampermonkey控制台 可自定义项: 修改
DARK_BG_COLOR
变量调整背景颜色 使用的权限: 使用
GM_setValue
/
GM_getValue
保存用户偏好 支持浏览器: Chrome和Firefox

Pre-Delivery Checklist

交付前检查清单

Before returning a userscript, verify:
返回用户脚本前,请验证以下内容:

Critical (Must Pass)

关键项(必须通过)

  • No hardcoded API keys, tokens, or passwords
  • @match is specific (not
    *://*/*
    )
  • All external URLs use HTTPS
  • User input sanitised before DOM insertion
  • 无硬编码的API密钥、令牌或密码
  • @match规则具体(非
    *://*/*
  • 所有外部URL均使用HTTPS
  • 用户输入在插入DOM前已被清理

Important (Should Pass)

重要项(建议通过)

  • Wrapped in IIFE with 'use strict'
  • All @grant statements are necessary
  • @connect includes all external domains
  • Error handling for async operations
  • Null checks before DOM manipulation
  • 使用IIFE包裹并启用'use strict'
  • 所有@grant声明均为必要项
  • @connect包含所有外部域名
  • 异步操作有错误处理
  • DOM操作前进行空值检查

Recommended

推荐项

  • @version follows semantic versioning (X.Y.Z)
  • Works in both Chrome and Firefox
  • Comments explain non-obvious code
For complete security checklist, see: security-checklist.md

  • @version遵循语义化版本规范(X.Y.Z)
  • 同时支持Chrome和Firefox
  • 对非直观代码添加注释
完整安全检查清单请参考: security-checklist.md

Reference Files Guide

参考文件指南

Load these on-demand based on user needs:
可根据用户需求按需加载以下文件:

Core Documentation

核心文档

FileWhen to LoadContent
header-reference.mdHeader syntax questionsAll @tags with examples
url-matching.mdURL pattern questions@match, @include, @exclude
patterns.mdImplementation patternsCommon script patterns
sandbox-modes.mdSecurity/isolationExecution contexts
文件加载场景内容
header-reference.md头部语法问题所有@标签及示例
url-matching.mdURL规则问题@match、@include、@exclude
patterns.md实现模式问题常见脚本模式
sandbox-modes.md安全/隔离问题执行上下文

API Reference

API参考

FileWhen to LoadContent
api-sync.mdGM_* function usageSync API documentation
api-async.mdGM.* promise usageAsync API documentation
api-storage.mdData persistencesetValue, getValue, listeners
http-requests.mdHTTP requestsGM_xmlhttpRequest
web-requests.mdRequest interceptionGM_webRequest (Firefox)
api-cookies.mdCookie manipulationGM_cookie
api-dom-ui.mdDOM/UI manipulationaddElement, addStyle, unsafeWindow
api-tabs.mdTab managementgetTab, saveTab, openInTab
api-audio.mdAudio controlMute/unmute tabs
文件加载场景内容
api-sync.mdGM_*函数使用问题同步API文档
api-async.mdGM.* promise使用问题异步API文档
api-storage.md数据持久化问题setValue、getValue、监听器
http-requests.mdHTTP请求问题GM_xmlhttpRequest
web-requests.md请求拦截问题GM_webRequest(Firefox)
api-cookies.mdCookie操作问题GM_cookie
api-dom-ui.mdDOM/UI操作问题addElement、addStyle、unsafeWindow
api-tabs.md标签页管理问题getTab、saveTab、openInTab
api-audio.md音频控制问题标签页静音/取消静音

Troubleshooting & Quality

故障排查与质量

FileWhen to LoadContent
common-pitfalls.mdScript issuesWhat breaks scripts
debugging.mdTroubleshootingHow to debug
browser-compatibility.mdCross-browserChrome vs Firefox
security-checklist.mdPre-deliverySecurity validation
version-numbering.mdVersion stringsComparison rules
文件加载场景内容
common-pitfalls.md脚本问题导致脚本失效的原因
debugging.md故障排查调试方法
browser-compatibility.md跨浏览器问题Chrome与Firefox差异
security-checklist.md交付前检查安全验证
version-numbering.md版本字符串问题版本比较规则