
本文介绍使用 MutationObserver 监听 元素的 href 属性变化,从而精准捕获 favicon 更新事件,并在 Tampermonkey 用户脚本中自动触发自定义函数。
本文介绍使用 mutationobserver 监听 `` 元素的 `href` 属性变化,从而精准捕获 favicon 更新事件,并在 tampermonkey 用户脚本中自动触发自定义函数。
在开发 Tampermonkey 用户脚本时,若需响应页面 favicon 的动态变更(例如单页应用中通过 JavaScript 动态切换图标),直接劫持 DOM 属性或使用 Proxy 并不可靠——因为页面脚本通常直接操作原生元素(如 linkEl.href = newUrl),而 Proxy 仅对代理对象本身生效,无法拦截外部对原始 DOM 节点的修改。
推荐方案是采用 MutationObserver:它专为监听 DOM 变化而设计,轻量、标准、兼容性好(现代浏览器及 Chromium/Firefox/Edge 均支持),且能精确捕获属性更新事件。
以下是一个完整、健壮的实现示例:
// ✅ 安全获取 favicon link 元素(兼容多种 rel 值)
const faviconLink = document.querySelector(
'link[rel="shortcut icon"], link[rel="icon"], link[rel="mask-icon"]'
);
if (!faviconLink) {
console.warn('No favicon <link> element found. Skipping favicon change detection.');
return;
}
// ✅ 自定义回调函数(请替换为你自己的逻辑)
function myFunction() {
console.log('✅ Favicon has changed:', faviconLink.href);
// 在此处添加你的业务逻辑,例如:
// - 发送分析事件
// - 更新 UI 状态栏图标
// - 触发通知等
}
// ✅ 创建并配置 MutationObserver
const observer = new MutationObserver((mutations) => {
for (const mutation of mutations) {
// 仅响应 href 属性变更(favicon 实际变化的核心标识)
if (mutation.type === 'attributes' && mutation.attributeName === 'href') {
myFunction();
}
}
});
// ✅ 开始观察:监听属性变化(不需子节点或字符数据)
observer.observe(faviconLink, {
attributes: true, // 必须启用
attributeFilter: ['href'] // 可选优化:仅关注 href,减少无关触发
});
? 关键注意事项:
-
元素必须存在才可观察:建议在
document.head加载完成后执行(Tampermonkey 中推荐@run-at document-idle或手动加DOMContentLoaded钩子); -
多 favicon 场景:部分站点会同时声明多个
rel="icon"(如不同尺寸、SVG、mask-icon),上述选择器已覆盖常见情况;若需监听全部,可改为遍历document.querySelectorAll('link[rel*="icon"]')并为每个元素单独 observe; -
首次加载不触发:
MutationObserver默认不触发初始值,仅响应后续变更——这正符合“变化检测”需求;如需初始化时也调用myFunction(),可在observe()前手动执行一次; -
内存管理:若脚本长期运行于 SPA 页面,无需手动断开(除非明确卸载逻辑),但可封装
observer.disconnect()以备扩展。
该方案已在真实 Tampermonkey 环境中验证有效,相比轮询(setInterval)更高效、无性能损耗,也比 Proxy 更符合 Web 标准与实际 DOM 行为。










