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

如何确保网站获得焦点以实现剪贴板复制功能?

问题原因分析

报错Uncaught (in promise) DOMException: Document is not focused的核心原因是浏览器剪贴板API的安全限制:

  • navigator.clipboard.writeText()要求操作必须在用户交互触发的上下文中,且当前文档处于聚焦状态。
  • 从地址栏调用书签小工具时,浏览器刚从地址栏切换回页面,文档尚未完全获得焦点;confirm弹窗关闭后直接执行剪贴操作,此时文档焦点可能仍未恢复,导致API调用被安全机制拦截。
  • 控制台能正常运行是因为控制台执行环境的安全限制被放宽,且此时文档已经处于聚焦状态;偶尔成功的情况是页面刚好在剪贴操作前自动恢复了焦点。
修复方案

核心思路是确保剪贴板操作前文档已聚焦,且操作处于用户交互的上下文内,修改后的代码如下:

!function () { 
    // 获取页面目标元素
    let n = document.querySelector("span.flipper"), 
        e = n.querySelectorAll("span.OptionLabel"), 
        o = e.length; 

    // 拼接要复制的文本,移除末尾多余符号
    let t = "";
    for (let r = 0; r < o; r++) {
        t += e[r].textContent + ", "; 
    }
    t = t.trim().replace(/,$/, "");

    // 封装剪贴板写入逻辑,确保文档聚焦
    async function copyToClipboard(text) {
        // 强制让文档获得焦点
        document.body.focus();
        try {
            await navigator.clipboard.writeText(text);
            alert("已成功复制到剪贴板!");
        } catch (err) {
            alert("复制失败:" + err.message);
            console.error(err);
        }
    }

    // 仅在用户确认后执行复制,用requestAnimationFrame确保焦点切换完成
    if (confirm(`点击"确定"复制列表到剪贴板\n\n共${o}项:\n${t}`)) {
        requestAnimationFrame(() => copyToClipboard(t));
    }
}();
关键改动说明
  • 主动调用document.body.focus():强制让页面文档获得焦点,满足剪贴板API的聚焦要求。
  • 使用requestAnimationFrame延迟执行:给浏览器足够时间完成从弹窗到页面的焦点切换,确保操作处于有效交互上下文。
  • 优化文本拼接:移除末尾多余的逗号和空格,提升复制内容的整洁度。
  • 添加错误捕获:复制失败时给用户明确提示,方便排查问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 20:52:40