tampermonkey
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTampermonkey 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
核心头部标签
| Tag | Required | Purpose | Example |
|---|---|---|---|
| Yes | Script name (supports i18n with | |
| Recommended | Unique identifier namespace | |
| Yes* | Version for updates (*required for auto-update) | |
| Recommended | What the script does | |
| Yes** | URLs to run on (**or @include) | |
| Situational | API permissions (use | |
| Optional | When to inject (default: | |
For complete header documentation, see: header-reference.md
| 标签 | 是否必填 | 用途 | 示例 |
|---|---|---|---|
| 是 | 脚本名称(支持通过 | |
| 推荐 | 唯一标识符命名空间 | |
| 是* | 版本号(*自动更新必填) | |
| 推荐 | 脚本功能说明 | |
| 是** | 脚本运行的URL(**或使用@include) | |
| 按需 | API权限(使用 | |
| 可选 | 脚本注入时机(默认: | |
完整头部标签文档请参考: 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 | |
| Make cross-origin requests | |
| Add custom CSS | |
| Access page's window | |
| Show notifications | |
| Add menu commands | |
| Detect URL changes (SPA) | |
javascript
// Disable sandbox (no GM_* except GM_info)
// @grant none
// Cross-origin requests require @connect
// @grant GM_xmlhttpRequest
// @connect api.example.com
// @connect *.googleapis.comFor complete permissions guide, see: header-reference.md
| 你需要... | 需授权 |
|---|---|
| 存储持久化数据 | |
| 发起跨域请求 | |
| 添加自定义CSS | |
| 访问页面的window对象 | |
| 显示通知 | |
| 添加菜单命令 | |
| 检测SPA的URL变化 | |
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注入时机
| Value | When Script Runs | Use Case |
|---|---|---|
| Before DOM exists | Block resources, modify globals early |
| When body exists | Early DOM manipulation |
| At DOMContentLoaded | Most scripts - DOM ready |
| After DOMContentLoaded (default) | Safe default |
| On right-click menu | User-triggered actions |
| 值 | 脚本运行时机 | 适用场景 |
|---|---|---|
| DOM创建前 | 阻止资源加载、提前修改全局变量 |
| body标签存在时 | 早期DOM操作 |
| DOMContentLoaded事件触发时 | 大多数脚本——DOM已就绪 |
| DOMContentLoaded事件后(默认) | 安全的默认选项 |
| 右键菜单触发时 | 用户触发的操作 |
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.jsjavascript
// @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:
- Explanation - What the script does (1-2 sentences)
- Complete userscript - Full code with all headers in a code block
- Installation - "Copy/paste into Tampermonkey dashboard" or "Save as .user.js"
- Customisation points - What the user can safely modify (selectors, timeouts, etc.)
- Permissions used - Which @grants and why they're needed
- 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: Changeto adjust the background colour Permissions: UsesDARK_BG_COLOR/GM_setValueto remember preference Browsers: Chrome and FirefoxGM_getValue
返回用户脚本时需包含以下内容:
- 功能说明 - 脚本的作用(1-2句话)
- 完整用户脚本 - 包含所有头部标签的完整代码,放在代码块中
- 安装方法 - "复制粘贴到Tampermonkey控制台" 或 "保存为.user.js文件"
- 可自定义项 - 用户可安全修改的内容(选择器、超时时间等)
- 使用的权限 - 使用了哪些@grant权限及原因
- 浏览器支持 - 是否仅支持Chrome、仅支持Firefox,或全平台兼容
示例返回格式:
该脚本为Example.com添加深色模式切换功能,并记住用户的偏好设置。
javascript
// ==UserScript==
// @name Example.com Dark Mode
// ...
// ==/UserScript==安装方法: 复制粘贴到Tampermonkey控制台 可自定义项: 修改变量调整背景颜色 使用的权限: 使用DARK_BG_COLOR/GM_setValue保存用户偏好 支持浏览器: Chrome和FirefoxGM_getValue
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
核心文档
| File | When to Load | Content |
|---|---|---|
| header-reference.md | Header syntax questions | All @tags with examples |
| url-matching.md | URL pattern questions | @match, @include, @exclude |
| patterns.md | Implementation patterns | Common script patterns |
| sandbox-modes.md | Security/isolation | Execution contexts |
| 文件 | 加载场景 | 内容 |
|---|---|---|
| header-reference.md | 头部语法问题 | 所有@标签及示例 |
| url-matching.md | URL规则问题 | @match、@include、@exclude |
| patterns.md | 实现模式问题 | 常见脚本模式 |
| sandbox-modes.md | 安全/隔离问题 | 执行上下文 |
API Reference
API参考
| File | When to Load | Content |
|---|---|---|
| api-sync.md | GM_* function usage | Sync API documentation |
| api-async.md | GM.* promise usage | Async API documentation |
| api-storage.md | Data persistence | setValue, getValue, listeners |
| http-requests.md | HTTP requests | GM_xmlhttpRequest |
| web-requests.md | Request interception | GM_webRequest (Firefox) |
| api-cookies.md | Cookie manipulation | GM_cookie |
| api-dom-ui.md | DOM/UI manipulation | addElement, addStyle, unsafeWindow |
| api-tabs.md | Tab management | getTab, saveTab, openInTab |
| api-audio.md | Audio control | Mute/unmute tabs |
| 文件 | 加载场景 | 内容 |
|---|---|---|
| api-sync.md | GM_*函数使用问题 | 同步API文档 |
| api-async.md | GM.* promise使用问题 | 异步API文档 |
| api-storage.md | 数据持久化问题 | setValue、getValue、监听器 |
| http-requests.md | HTTP请求问题 | GM_xmlhttpRequest |
| web-requests.md | 请求拦截问题 | GM_webRequest(Firefox) |
| api-cookies.md | Cookie操作问题 | GM_cookie |
| api-dom-ui.md | DOM/UI操作问题 | addElement、addStyle、unsafeWindow |
| api-tabs.md | 标签页管理问题 | getTab、saveTab、openInTab |
| api-audio.md | 音频控制问题 | 标签页静音/取消静音 |
Troubleshooting & Quality
故障排查与质量
| File | When to Load | Content |
|---|---|---|
| common-pitfalls.md | Script issues | What breaks scripts |
| debugging.md | Troubleshooting | How to debug |
| browser-compatibility.md | Cross-browser | Chrome vs Firefox |
| security-checklist.md | Pre-delivery | Security validation |
| version-numbering.md | Version strings | Comparison rules |
| 文件 | 加载场景 | 内容 |
|---|---|---|
| common-pitfalls.md | 脚本问题 | 导致脚本失效的原因 |
| debugging.md | 故障排查 | 调试方法 |
| browser-compatibility.md | 跨浏览器问题 | Chrome与Firefox差异 |
| security-checklist.md | 交付前检查 | 安全验证 |
| version-numbering.md | 版本字符串问题 | 版本比较规则 |