本文详细介绍油猴(Tampermonkey)脚本的编写流程、元数据配置、外部编辑器(VS Code)开发流以及浏览器控制台调试技巧。
油猴(Tampermonkey)脚本怎么写?JS编辑工具与调试技巧
时间:2026-10-30
浏览:107
文章目录
编写油猴(Tampermonkey)脚本本质上是为特定网页编写注入运行的 JavaScript 代码,核心包含三大要素:声明执行环境与权限的 Userscript 元数据头、编写操作 DOM 或调用网络接口的业务代码,以及借助现代编辑器与浏览器控制台进行高效排错。掌握这套流程后,读者可以快速定制网页功能、自动化日常操作或提取页面数据。
一、油猴脚本的运行机制与开发流程
油猴插件作为用户脚本管理器,在浏览器完成网页加载(或指定阶段)时,读取脚本开头的元数据块(Metadata Block),判断当前访问的 URL 是否匹配设定规则。如果匹配,插件就会在隔离的沙箱或宿主页面环境中注入并执行该脚本。
编写一个油猴脚本的标准流程通常包括以下四个阶段:在浏览器中新建脚本模板、配置基础元数据声明、编写页面逻辑代码,最后通过控制台进行排错验证。
二、理解元数据块(Metadata Block)与基础语法
元数据块位于脚本的最上方,由 // ==UserScript== 开始,到 // ==/UserScript== 结束。浏览器插件通过这些特殊注释来识别脚本的属性与运行权限。以下是常用的元数据指令:
@name:脚本在管理面板中显示的名称。@version:脚本版本号,用于更新检测。@match:定义脚本生效的目标网址。支持通配符*,例如https://example.com/*。@run-at:定义脚本的注入时机。常用值包括document-start(DOM 构建前注入)、document-end(DOM 树就绪后注入)以及document-idle(默认值,浏览器空闲时注入)。@grant:声明请求的油猴专有 API 权限。若不需要特殊 API,必须声明为none以获得原生性能并避免沙箱代理开销。
下面是一个完整的最小可运行脚本示例,该脚本在匹配的网页底部添加一个固定的提示工具条:
// ==UserScript==
// @name 网页阅读工具条演示
// @namespace http://tampermonkey.net/
// @version 1.0.0
// @description 在指定测试页面右下角增加便捷控制栏
// @match https://example.com/*
// @grant none
// @run-at document-idle
// ==/UserScript==
(function() {
'use strict';
// 创建容器元素
const toolbar = document.createElement('div');
toolbar.id = 'my-custom-toolbar';
toolbar.textContent = '油猴工具条已加载';
// 设置基础样式
Object.assign(toolbar.style, {
position: 'fixed',
bottom: '20px',
right: '20px',
padding: '10px 16px',
backgroundColor: '#456581',
color: '#ffffff',
borderRadius: '6px',
zIndex: '999999',
fontSize: '14px',
boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',
cursor: 'pointer'
});
// 绑定交互事件
toolbar.addEventListener('click', () => {
alert('工具条按钮被点击!');
});
document.body.appendChild(toolbar);
console.log('[Userscript] 工具条初始化完成。');
})();
注意:使用 'use strict'; 严格模式包裹自执行函数(IIFE),可以有效防止脚本内定义的全局变量污染目标网页的原生上下文,避免与页面已有的 JavaScript 发生变量冲突。
三、选择适合的 JS 编辑工具与外部联调
油猴自带的网页版编辑器适合编写数十行的简易脚本,但当代码量增加或需要引入模块化开发时,其代码补全、格式化与版本控制能力就会受限。主流的开发方式是采用 VS Code 等外部编辑器进行本地开发,并将其连接到浏览器中实时生效。
常见方案对比与配置方法
| 方案类型 | 实现方式 | 适用场景 | 配置门槛 |
|---|---|---|---|
| 内置 Web 编辑器 | 直接在油猴插件弹出页内编辑保存 | 临时修改、百行以内的短脚本 | 零配置,即开即用 |
| 文件协议直连 (file://) | 使用 @require file:///path/to/script.js |
单人纯原生 JS 开发,秒级反馈 | 需在浏览器扩展设置中开启“允许访问文件网址” |
| 本地构建工具流 (Vite/Webpack) | 配合 vite-plugin-monkey 打包输出 |
大型脚本、需引入 TypeScript、Vue/React 等组件 | 需掌握 Node.js 与构建工具 |
以文件直连模式为例的配置步骤:
- 打开浏览器的扩展管理中心(如
chrome://extensions),找到 Tampermonkey,点击“详细信息”,勾选“允许访问文件网址(Allow access to file URLs)”。 - 在 VS Code 中创建工作目录并新建
dev.user.js文件。 - 在油猴管理面板新建一个脚本,仅保留元数据头,并使用
@require指向本地绝对路径:// ==UserScript== // @name 本地开发代理 // @match https://example.com/* // @grant none // @require file:///Users/username/project/dev.user.js // ==/UserScript== - 此后在 VS Code 中保存修改,直接在浏览器中刷新网页,无需再次复制粘贴代码。
四、油猴脚本调试实用技巧
调试油猴脚本主要依托 Chrome 或 Firefox 内置的开发者工具(F12),结合控制台输出、代码断点和沙箱上下文切换。
技巧一:使用前缀日志快速过滤
现代网页自身的日志通常非常冗杂。为了在控制台中一目了然地看到自己的脚本输出,建议定义一个通用的日志打印助手,加上唯一标识:
const log = (...args) => console.log('%c[MyScript]', 'color: #438a80; font-weight: bold;', ...args);
log('目标元素已找到,准备开始处理');
在 DevTools 控制台过滤栏输入 [MyScript],即可屏蔽宿主页面的杂乱输出。
技巧二:利用 debugger 语句精确定位
由于油猴脚本可能运行在单独的动态脚本文件中(在 Sources 面板中常表现为 userscript.html?id=...),在庞大的文件树中手动打断点往往较为繁琐。在可疑逻辑前直接写入 debugger;:
function handleDataExtract() {
const list = document.querySelectorAll('.item-box');
if (list.length === 0) {
// 目标节点未找到时自动暂停,进入调试模式
debugger;
}
// 处理提取逻辑
}
当浏览器执行到该语句且控制台处于打开状态时,会自动暂停,并自动跳转展开对应的源码位置,方便单步执行。
技巧三:切换 Console 执行上下文(Context)
当脚本声明了 @grant GM_xmlhttpRequest 等油猴特有 API 时,脚本会运行在隔离的沙箱上下文中。在控制台直接输入脚本中定义的函数名可能会报错 ReferenceError。此时,点击控制台左上角的上下文下拉框(默认显示为 top),选择带有 Tampermonkey 或该脚本扩展 ID 的选项,即可直接在控制台中访问脚本作用域内部的变量与函数。
五、异步页面与动态内容加载的应对方案
许多现代网页采用单页应用(SPA)架构或滚动懒加载,油猴脚本执行时目标 DOM 元素可能尚未渲染完成。如果直接调用 document.querySelector,极易返回 null。
常规的解决方式是结合 MutationObserver 监听 DOM 树变化,或编写一个返回 Promise 的通用等待函数:
/**
* 等待指定选择器的元素渲染完成
* @param {string} selector CSS选择器
* @param {number} timeout 超时时间(毫秒)
* @returns {Promise<Element>}
*/
function waitForElement(selector, timeout = 10000) {
return new Promise((resolve, reject) => {
const el = document.querySelector(selector);
if (el) return resolve(el);
const observer = new MutationObserver(() => {
const target = document.querySelector(selector);
if (target) {
observer.disconnect();
clearTimeout(timer);
resolve(target);
}
});
observer.observe(document.body, { childList: true, subtree: true });
const timer = setTimeout(() => {
observer.disconnect();
reject(new Error('等待元素超时: ' + selector));
}, timeout);
});
}
// 使用示例
waitForElement('.dynamic-article-content')
.then(container => {
console.log('目标动态容器已就绪', container);
})
.catch(err => console.error(err));
六、总结与开发避坑清单
油猴脚本开发难度较低,但要保持稳定可维护,需要注意元数据配置的严谨性、执行环境的隔离机制以及针对动态 DOM 的容错处理。以下是开发与调试时的核心对照表:
按照上述结构组织开发,读者可以在不频繁切换窗口和手动复制的情况下,利用现代前端工具流高效完成从简单页面修饰到复杂数据交互的各种脚本需求。
实用工具推荐
绿化、压缩、噪点和虚拟水印,自由调节做旧程度。
选择画质和输出格式,预览压缩前后的大小。