调用剪贴板触发DOMException:Document is not focused问题求助
问题解决:无默认邮件客户端时复制邮箱到剪贴板的焦点异常
问题分析
你遇到的Document is not focused异常,是因为confirm弹窗会夺走页面焦点,而navigator.clipboard.writeText要求文档必须处于激活焦点状态才能调用,同时这个API是异步方法,之前的写法没处理异步逻辑,导致焦点未恢复就执行复制。
修改后的代码
verifyEmailHandler() { let t; window.addEventListener('blur', () => clearTimeout(t)); t = setTimeout(async () => { const confirmed = confirm( `无法启动邮件客户端,请手动发送邮件给该用户。\n点击"确定"将"${this.userInfo.email}"复制到剪贴板。` ); if (confirmed) { // 确保页面重新获得焦点 window.focus(); try { // 异步执行剪贴板复制,处理Promise await navigator.clipboard.writeText(this.userInfo.email); alert('邮箱地址已复制到剪贴板'); } catch (err) { // 剪贴板API失败时,用兼容方案降级 const tempInput = document.createElement('input'); tempInput.value = this.userInfo.email; document.body.appendChild(tempInput); tempInput.select(); document.execCommand('copy'); document.body.removeChild(tempInput); alert('邮箱地址已通过兼容方式复制到剪贴板'); } } }, 500); },
关键修改点
- 用
async/await处理navigator.clipboard.writeText的异步逻辑,确保复制操作在焦点恢复后执行。 - 添加
try/catch捕获异常,当剪贴板API因权限或焦点问题失败时,使用传统的临时input复制方案作为降级,这个方案对焦点的限制更宽松,只要是用户交互触发就能生效。 - 移除了无用的
let confirmed = false变量,直接在setTimeout内定义const confirmed,避免作用域混乱。 - 弹窗关闭后先执行
window.focus(),强制页面重新获取焦点,再执行复制操作。
内容的提问来源于stack exchange,提问作者Agård
相关产品推荐
相关产品推荐

