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

ShadowRoot中onpaste事件未取消:Chrome扩展禁用粘贴失效问题

解决Chrome扩展content-script在ShadowRoot中禁用粘贴失效的问题

问题情况

我通过Chrome扩展的content-script在bing.com上禁用用户粘贴功能,使用的代码如下:

document.onpaste = (event) => {
  event.preventDefault();
  return false;
};

这段代码在bing.com主搜索页面的输入框中可正常生效,但进入以ShadowRoot形式打开的聊天选项后,粘贴函数虽被调用,内容仍会粘贴到聊天文本框中。而我实现的禁用复制功能在主DOM和ShadowRoot中均能正常工作:

document.addEventListener(
    "copy",
    (evt) => {
        evt.clipboardData.setData(
            "text/plain",
            "Copy is disabled"
        );
        evt.preventDefault();
    },
    false
);

问题原因

document.onpaste是绑定在全局document上的事件,但ShadowRoot内部元素的事件会先被其内部的监听器处理,且默认情况下事件不会冒泡到主document(除非设置composed: true),所以全局监听器无法阻止ShadowRoot内的粘贴操作。而copy事件能生效,是因为它默认支持冒泡且composed属性为true,能传递到主document层面。

解决方案

1. 定义通用的粘贴禁用函数

function disablePaste(event) {
  event.preventDefault();
  return false;
}

2. 给主document和已存在的ShadowRoot绑定事件

// 给主document绑定捕获阶段的paste事件
document.addEventListener('paste', disablePaste, true);

// 遍历并绑定所有已存在的ShadowRoot
function bindShadowRootPaste(root) {
  root.querySelectorAll('*').forEach(el => {
    if (el.shadowRoot) {
      // 给ShadowRoot绑定捕获阶段的paste事件
      el.shadowRoot.addEventListener('paste', disablePaste, true);
      // 递归处理ShadowRoot内部的嵌套ShadowRoot
      bindShadowRootPaste(el.shadowRoot);
    }
  });
}

// 初始化绑定页面已有的ShadowRoot
bindShadowRootPaste(document);

3. 监听动态生成的ShadowRoot

页面可能会动态创建新的ShadowRoot,需要用MutationObserver监听节点新增,及时绑定事件:

const observer = new MutationObserver(mutations => {
  mutations.forEach(mutation => {
    mutation.addedNodes.forEach(node => {
      if (node.nodeType === Node.ELEMENT_NODE) {
        // 检查当前节点是否带有ShadowRoot
        if (node.shadowRoot) {
          node.shadowRoot.addEventListener('paste', disablePaste, true);
          bindShadowRootPaste(node.shadowRoot);
        }
        // 检查子节点中的ShadowRoot
        bindShadowRootPaste(node);
      }
    });
  });
});

// 启动观察者,监听整个页面的节点新增
observer.observe(document.body, {
  childList: true,
  subtree: true
});

关键说明

  • 使用addEventListener的第三个参数true,让事件在捕获阶段触发,这样能优先于ShadowRoot内部的事件监听器执行,确保阻止操作生效。
  • 递归遍历所有ShadowRoot,避免嵌套的ShadowRoot被遗漏。
  • MutationObserver用于覆盖页面后续动态生成的元素,保证新增的ShadowRoot也能被处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 16:20:06