You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

油猴脚本监听popover渲染追加元素 移除disconnect致页面卡死如何解决

问题原因

移除this.disconnect()后页面卡顿是两个逻辑错误导致的:

  • 回调中执行appendChild修改DOM的操作,会再次触发MutationObserver回调,形成无限触发的死循环,直接占满JS主线程导致页面挂起。
  • 没有做已处理元素的去重判断,同一个元素被多次扫描到时会重复执行DOM操作,产生无意义的性能开销。
修复方案

只需要两处调整即可实现持续监听所有动态弹出的popover,同时不会造成卡顿:

  1. 删除this.disconnect()语句,保持监听器持续运行
  2. 给已经添加过Teams按钮的元素增加自定义标记,处理节点前先校验标记,跳过已处理元素,从根源避免重复操作和死循环。

修改后的完整代码如下:

// ==UserScript==
// @name         ms_teams_integration
// @match        https://example.com/*
// @version      1.1
// @grant        none
// @run-at       document-start
// @require      第三方setMutationHandler库依赖地址
// ==/UserScript==

var teamsIcon = ""; // 此处填写svg格式的图标内容

setMutationHandler(document, '#user-hover-email', function(nodes) {
    nodes.forEach(function(n) {
        // 跳过已经添加过按钮的元素
        if (n.dataset.teamsBtnAdded) return;
        // 打上已处理标记
        n.dataset.teamsBtnAdded = "1";

        var emailLink = n.getElementsByTagName("a").item(0);
        var teamsLink = emailLink.cloneNode(true);
        teamsLink.setAttribute(
            "href", 
            teamsLink.getAttribute("href")
                .replace("mailto:", "https://teams.microsoft.com/l/chat/0/0?users="));
        teamsLink.setAttribute("target", "_blank");
        teamsLink.innerHTML = teamsIcon;
        n.appendChild(teamsLink);
    });
});
可选性能优化

如果页面DOM变动非常频繁,建议放弃第三方依赖库,直接用原生MutationObserver实现,手动关闭不需要的监听项,只监听节点新增事件,完全忽略属性修改、文本修改这类无关变动,性能会更稳定,哪怕页面操作频繁也不会卡顿:

// ==UserScript==
// @name         ms_teams_integration
// @match        https://example.com/*
// @version      1.1
// @grant        none
// @run-at       document-start
// ==/UserScript==

var teamsIcon = ""; // 此处填写svg格式的图标内容
const TARGET_SELECTOR = '#user-hover-email';

function addTeamsButton(container) {
    const emailLink = container.getElementsByTagName("a").item(0);
    const teamsLink = emailLink.cloneNode(true);
    teamsLink.setAttribute(
        "href", 
        teamsLink.getAttribute("href")
            .replace("mailto:", "https://teams.microsoft.com/l/chat/0/0?users=")
    );
    teamsLink.setAttribute("target", "_blank");
    teamsLink.innerHTML = teamsIcon;
    container.appendChild(teamsLink);
}

function processNode(node) {
    if (node.nodeType !== Node.ELEMENT_NODE) return;
    // 处理当前节点本身就是目标元素的情况
    if (node.matches(TARGET_SELECTOR)) {
        if (node.dataset.teamsBtnAdded) return;
        node.dataset.teamsBtnAdded = "1";
        addTeamsButton(node);
    }
    // 处理当前节点内部包含目标元素的情况
    node.querySelectorAll(TARGET_SELECTOR).forEach(el => {
        if (el.dataset.teamsBtnAdded) return;
        el.dataset.teamsBtnAdded = "1";
        addTeamsButton(el);
    });
}

const observer = new MutationObserver(mutations => {
    for (const mutation of mutations) {
        mutation.addedNodes.forEach(processNode);
    }
});

observer.observe(document.documentElement, {
    childList: true,
    subtree: true,
    attributes: false,
    characterData: false
});

内容的提问来源于stack exchange,提问作者craystern

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 08:21:18