1. Tampermonkey油猴脚本入门指南
作为浏览器增强工具链中不可或缺的一环,Tampermonkey(俗称油猴)早已成为前端开发者和效率追求者的标配工具。这个拥有超过1000万用户的浏览器扩展,本质上是一个用户脚本管理器,允许你通过注入JavaScript代码来修改任意网页的显示效果或功能逻辑。
我最初接触Tampermonkey是为了解决一个具体问题:某学术网站的文章下载按钮被刻意隐藏,每次都需要手动修改DOM才能显示。在尝试了各种方法后,一个简单的用户脚本完美解决了这个问题——从此我的浏览器里就再没卸载过这个绿色猴子图标。
1.1 核心功能解析
Tampermonkey的核心价值在于它建立了一个用户脚本的生态系统。这些脚本通常以.user.js为后缀,本质上都是JavaScript文件,但遵循特定的元数据格式。当你在Chrome、Edge或Firefox等浏览器中安装Tampermonkey扩展后,它就成为了这些脚本的运行沙箱和管理中心。
典型应用场景包括:
- 去除网页广告/弹窗
- 自动填充表单数据
- 定制化页面布局
- 添加网站快捷功能
- 破解VIP视频限制
- 批量处理页面元素
重要提示:虽然Tampermonkey本身是合法工具,但某些脚本可能违反网站使用条款。建议仅在不涉及数据安全的个人场景使用,商业环境需谨慎评估法律风险。
1.2 安装与基础配置
在Chrome网上应用商店搜索"Tampermonkey"即可找到官方扩展,安装过程与常规插件无异。安装完成后,浏览器右上角会出现一个深色背景的猴子图标,新用户通常会看到数字"0",表示当前没有活跃脚本。
首次使用时建议进行以下配置:
- 点击图标选择"仪表盘"
- 在"设置"标签页中:
- 启用"自动更新脚本"(建议选择"每日")
- 配置脚本同步(支持Google Drive/Dropbox)
- 设置编辑器主题和缩进偏好
- 在"实用工具"标签页导入/导出脚本备份
2. 脚本管理与使用技巧
2.1 脚本安装的三种途径
途径一:官方脚本库
访问Greasy Fork或OpenUserJS等脚本托管平台,搜索目标网站名称或功能关键词。找到合适脚本后点击"安装"按钮,Tampermonkey会自动拦截安装请求并显示预览界面。
途径二:直接导入
对于开发者分享的.user.js文件,可以通过仪表盘的"实用工具"→"导入"功能手动添加。这种方式适合获取非公开脚本或自己编写的脚本。
途径三:新建脚本
点击Tampermonkey图标选择"创建新脚本",会打开内置编辑器。这里已经预置了脚本元数据模板,包括@name、@namespace等必要字段。我习惯先保存这个模板,再逐步添加具体功能代码。
2.2 脚本管理最佳实践
随着使用时间增长,脚本数量可能达到几十个。高效管理的关键在于:
-
分类标签系统:
在脚本编辑器的元数据区添加@description和@include标签javascript复制// @description 自动展开知乎全部回答 // @include https://www.zhihu.com/question/* -
性能监控:
在仪表盘启用"脚本运行时间统计",定期检查哪些脚本拖慢了页面加载 -
冲突排查:
当多个脚本作用于同一页面时,通过临时禁用/启用组合来定位冲突源 -
更新策略:
对关键脚本关闭自动更新,大版本更新前先在本机测试
实测发现:约30%的脚本在网站改版后会失效。建议为每个重要脚本建立本地备份,并在元数据中记录原作者联系方式以便求助。
3. 脚本开发实战指南
3.1 开发环境搭建
虽然Tampermonkey提供内置编辑器,但专业开发更推荐以下方案:
方案A:VS Code + Tampermonkey插件
- 安装"Tampermonkey Snippets"扩展
- 创建.js文件时使用"tm-new"代码片段生成模板
- 配置本地服务器测试脚本(避免file://协议限制)
方案B:浏览器实时调试
- 在Tampermonkey设置启用"允许访问文件网址"
- 使用@require引入本地脚本库
javascript复制// @require file:///Users/me/scripts/utils.js - 配合浏览器开发者工具调试
3.2 核心API详解
Tampermonkey扩展了GM_*系列API,这是与普通网页JS的关键区别:
| API名称 | 功能描述 | 使用示例 |
|---|---|---|
| GM_setValue | 存储持久化数据 | GM_setValue('token',123) |
| GM_getValue | 读取存储数据 | GM_getValue('token') |
| GM_xmlhttpRequest | 跨域请求 | 见下方代码示例 |
| GM_notification | 显示系统通知 | GM_notification('提示') |
| GM_addStyle | 注入CSS样式 | GM_addStyle('body{background:red}') |
跨域请求示例:
javascript复制GM_xmlhttpRequest({
method: "GET",
url: "https://api.example.com/data",
onload: function(response) {
console.log(response.responseText);
}
});
3.3 典型脚本结构剖析
一个完整的用户脚本通常包含以下部分:
javascript复制// ==UserScript==
// @name 示例脚本
// @namespace http://your.homepage/
// @version 0.1
// @description 这是一个示例脚本
// @author You
// @match https://*.example.com/*
// @grant GM_xmlhttpRequest
// ==/UserScript==
(function() {
'use strict';
// 等待目标元素加载
const observer = new MutationObserver(() => {
if (document.querySelector('#target')) {
observer.disconnect();
main();
}
});
observer.observe(document.body, {childList: true, subtree: true});
function main() {
// 主逻辑代码
console.log('脚本已加载');
}
})();
3.4 调试与发布
调试技巧:
- 在脚本开头添加
// @grant none临时禁用沙箱限制 - 使用
// @require https://cdn.jsdelivr.net/npm/eruda注入移动端调试面板 - 通过
GM_log替代console.log避免被网站屏蔽
发布流程:
- 在元数据中添加@updateURL指向版本文件
javascript复制// @updateURL https://example.com/myscript.meta.js - 使用uglify-js等工具压缩代码
- 上传到GitHub等平台并发布到Greasy Fork
4. 高级应用与性能优化
4.1 复杂脚本架构设计
当脚本功能变得复杂时,推荐采用模块化架构:
-
核心加载器:
负责基础环境检测和模块调度javascript复制// 模块注册表 const modules = { utils: 'https://example.com/utils.js', ui: 'https://example.com/ui.js' }; // 动态加载模块 function loadModule(name) { return new Promise((resolve) => { if (window[name]) return resolve(); const script = document.createElement('script'); script.src = modules[name]; script.onload = resolve; document.head.appendChild(script); }); } -
配置系统:
使用GM_*API实现可配置化javascript复制const config = { debug: GM_getValue('debug', false), theme: GM_getValue('theme', 'dark') }; -
UI组件:
通过Shadow DOM创建隔离的界面元素javascript复制class MyWidget extends HTMLElement { constructor() { super(); this.attachShadow({mode: 'open'}); this.shadowRoot.innerHTML = `<style>/* 组件样式 */</style><div>内容</div>`; } } customElements.define('my-widget', MyWidget);
4.2 性能优化策略
策略一:延迟加载
javascript复制window.addEventListener('load', () => {
// 在页面完全加载后执行非关键操作
setTimeout(initSecondaryFeatures, 1000);
});
策略二:智能触发
javascript复制// 只在用户滚动到特定区域时加载内容
const intersectionObserver = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
loadContent();
intersectionObserver.disconnect();
}
});
intersectionObserver.observe(document.querySelector('#target'));
策略三:缓存管理
javascript复制// 使用GM_APIs实现缓存
function fetchWithCache(url, expiry = 3600) {
const cacheKey = `cache_${md5(url)}`;
const cached = GM_getValue(cacheKey);
if (cached && cached.timestamp > Date.now() - expiry*1000) {
return Promise.resolve(cached.data);
}
return fetch(url).then(res => res.json()).then(data => {
GM_setValue(cacheKey, {data, timestamp: Date.now()});
return data;
});
}
5. 安全与维护指南
5.1 安全防护措施
-
脚本审核:
- 检查所有@require引入的外部资源
- 避免使用eval等危险函数
- 对GM_xmlhttpRequest的响应做合法性校验
-
权限控制:
javascript复制// 最小化@grant声明 // @grant GM_xmlhttpRequest // @grant GM_setValue -
沙箱保护:
javascript复制// 使用IIFE避免污染全局命名空间 (function() { 'use strict'; // 脚本代码 })();
5.2 长期维护建议
-
版本管理:
- 使用语义化版本控制(SemVer)
- 在@version字段和代码注释中保持同步
- 建立CHANGELOG.md记录变更
-
兼容性处理:
javascript复制// 检测Tampermonkey特性支持 if (typeof GM === 'undefined') { alert('请使用Tampermonkey运行此脚本'); return; } -
用户反馈系统:
javascript复制// 添加反馈按钮 function addFeedbackButton() { const btn = document.createElement('button'); btn.textContent = '问题反馈'; btn.onclick = () => { GM_xmlhttpRequest({ method: "POST", url: "https://api.example.com/feedback", data: JSON.stringify({issue: "问题描述"}), headers: {"Content-Type": "application/json"} }); }; document.body.appendChild(btn); }
6. 实用脚本推荐与自定义
6.1 效率提升必备脚本
-
网页优化类:
- 移除特定元素(广告、悬浮窗)
- 自动翻页/加载更多内容
- 暗黑模式强制启用
-
表单增强类:
- 密码管理器集成
- 自动填充验证码
- 历史记录记忆
-
媒体控制类:
- 视频速度调节
- 弹幕过滤器
- 画中画增强
6.2 自定义脚本案例
案例:知乎增强脚本
javascript复制// ==UserScript==
// @name 知乎增强
// @namespace https://github.com/yourname/
// @version 1.2
// @description 知乎内容增强与界面优化
// @author YourName
// @match https://www.zhihu.com/*
// @grant GM_addStyle
// ==/UserScript==
GM_addStyle(`
/* 隐藏营销内容 */
.Marketing{ display:none !important; }
/* 调整阅读区域宽度 */
.Post-content{ max-width: 900px !important; }
`);
// 自动展开所有回答
const expandAnswers = () => {
document.querySelectorAll('.ContentItem-expandButton').forEach(btn => {
if(btn.textContent.includes('展开')) btn.click();
});
};
// 监听路由变化
let lastUrl = location.href;
new MutationObserver(() => {
if (location.href !== lastUrl) {
lastUrl = location.href;
setTimeout(expandAnswers, 1000);
}
}).observe(document, {subtree: true, childList: true});
// 初始执行
expandAnswers();
案例:B站视频下载器
javascript复制// ==UserScript==
// @name B站视频下载助手
// @namespace http://tampermonkey.net/
// @version 0.1
// @description 添加B站视频下载按钮
// @author You
// @match https://www.bilibili.com/video/*
// @grant GM_xmlhttpRequest
// ==/UserScript==
function addDownloadButton() {
const btn = document.createElement('button');
btn.style = 'position:fixed; right:20px; bottom:20px; z-index:9999;';
btn.textContent = '下载视频';
btn.onclick = fetchVideoUrl;
document.body.appendChild(btn);
}
function fetchVideoUrl() {
const vid = location.pathname.split('/video/')[1];
GM_xmlhttpRequest({
method: "GET",
url: `https://api.example.com/bilibili?vid=${vid}`,
onload: function(res) {
const data = JSON.parse(res.responseText);
const a = document.createElement('a');
a.href = data.url;
a.download = `${vid}.mp4`;
a.click();
}
});
}
// 等待播放器加载
new MutationObserver((_, observer) => {
if (document.querySelector('.bpx-player-video-wrap')) {
observer.disconnect();
addDownloadButton();
}
}).observe(document.body, {childList: true, subtree: true});
7. 常见问题解决方案
7.1 安装与运行问题
问题1:脚本安装失败
- 检查浏览器扩展权限
- 尝试关闭广告拦截器
- 手动下载.user.js文件后拖入扩展管理页面
问题2:脚本不生效
- 确认@match规则匹配当前URL
- 检查浏览器控制台是否有错误
- 尝试在脚本开头添加debugger语句
7.2 开发调试问题
问题3:GM API未定义
javascript复制// 确保在元数据中声明了对应的@grant
// @grant GM_xmlhttpRequest
问题4:跨域请求被拦截
javascript复制// 添加CORS头声明
GM_xmlhttpRequest({
method: "GET",
url: "https://api.example.com",
headers: {
"Origin": "https://yourdomain.com"
},
// ...
});
7.3 性能与兼容性问题
问题5:脚本导致页面卡顿
- 使用requestIdleCallback分时执行任务
- 对DOM操作进行防抖处理
- 避免在scroll/resize等高频事件中执行复杂逻辑
问题6:网站更新后脚本失效
- 使用更宽松的选择器(如属性选择器)
- 添加MutationObserver监听DOM变化
- 建立脚本失效自动通知机制
javascript复制// 失效检测示例
function checkFeature() {
if (!document.querySelector('#old-feature')) {
GM_notification({
title: '脚本可能已失效',
text: '检测到页面结构变化',
timeout: 5000
});
}
}
8. 扩展知识与进阶资源
8.1 相关工具链
-
脚本仓库:
- Greasy Fork(最活跃的中文社区)
- OpenUserJS(历史最悠久的仓库)
- GitHub(搜索.user.js文件)
-
开发辅助:
- Violentmonkey(Tampermonkey替代品)
- Webpack Tampermonkey Plugin(工程化支持)
- ESLint Plugin for Userscripts(代码检查)
-
调试工具:
- Tampermonkey Editor(VS Code扩展)
- Eruda(移动端调试)
- LiveServer(本地开发服务器)
8.2 学习资源推荐
入门教程:
- 官方文档(含中文)
- Greasy Fork编写指南
- MDN Web API参考
进阶书籍:
- 《JavaScript高级程序设计》(用户脚本基础)
- 《深入浅出GM脚本开发》(绝版,可找电子版)
- 《Web扩展开发权威指南》(相关技术)
视频课程:
- B站"油猴脚本开发从入门到精通"
- YouTube"Tampermonkey Master Class"
- Udemy"Automate with UserScripts"
在实际项目中,我逐渐形成了自己的脚本开发工作流:先在Greasy Fork寻找现有解决方案,若无满足则自行开发,完成后先在本地测试环境验证,再发布到私有GitHub仓库,最后视情况决定是否公开分享。这种模式既保证了开发效率,又能持续积累可复用的脚本库。
