现代浏览器推荐使用 navigator.clipboard.writeText() 复制文本,需在用户点击等手势事件中同步调用并用 try/catch 捕获错误;旧浏览器可降级使用 document.execCommand('copy') 配合临时 textarea;不可依赖 copy 事件判断 JS 写入结果。
navigator.clipboard.writeText() 复制文本现代浏览器(Chrome 66+、Firefox 63+、Edge 79+、Safari 13.1+)原生支持 navigator.clipboard.writeText(),这是目前最可靠、无需依赖 Flash 或第三方库的方案。它返回 Promise,成功时无返回值,失败时抛出 DOMException。
关键点在于:该 API 必须在用户手势(如 click、keydown)触发的上下文中调用,不能放在异步回调(如 setTimeout、fetch.then)里直接调用,否则会报错 "Permission denied" or "clipboard-write permission denied"。
click 事件监听器,且在该监听器内同步调用 writeText()
async 函数中 await 后再调用——只要调用发生在用户点击之后、且未脱离事件循环栈即可file:// 协议下可能完全不可用复制操作不是 100% 成功的:用户可能禁用剪贴板权限、浏览器不支持、或处于隐私浏览模式。不能只靠 console.log 静默吞掉错误。
try/catch 捕获 writeText() 的 Promise rejection"NotAllowedError"(权限被拒)、"SecurityError"(非安全上下文)、"NotFoundError"(API 不存在)button.addEventListener('click', async () => { try { await navigator.clipboard.writeText('Hello World'); button.textContent = '已复制!'; setTimeout(() => { button.textContent = '复制'; }, 2000); } catch (err) { console.error('复制失败:', err.name, err.message); alert('复制失败,请检查浏览器设置'); }});
document.execCommand('copy')
IE11 和部分老版 Android 浏览器不支持 navigator.clipboard,需回退到已废弃但广泛兼容的 document.execCommand('copy')。它要求目标文本必须是真实 DOM 元素(如 <textarea>)中的选中内容。
立即学习“前端免费学习笔记(深入)”;
<textarea>,设 value,然后 select() 并执行命令<textarea> 添加进 DOM(哪怕 opacity: 0 或 position: absolute; left: -9999px),否则 Safari 不认execCommand 已被标记为废弃,Chrome 90+ 在非用户手势中调用会警告,但目前仍可用copy 事件监听器来确认复制结果?有人试图监听 document.addEventListener('copy', handler) 来判断是否复制成功——这其实行不通。该事件只在用户主动触发系统复制(Ctrl+C / Cmd+C)时触发,和 writeText() 或 execCommand 无关,也无法反映 JS 主动写入剪贴板的结果。
真正能验证写入成功的唯一方式,就是捕获 API 调用本身的 Promise 结果或 execCommand 返回值(它返回布尔值)。别被 copy 事件名误导,它和“JS 写剪贴板”是两条互不交集的路径。
跨浏览器稳定复制的关键,是把权限检查、异常捕获、DOM 临时节点管理和用户反馈串成闭环——漏掉任意一环,都可能在某个设备上静默失败。