复制按钮别再用 execCommand 了:用 Clipboard API 做一键复制

举报
静水流深-云海 发表于 2026/09/12 20:30:51 2026/09/12
【摘要】 用 Clipboard API 的 navigator.clipboard.writeText 做一键复制按钮,替代已废弃的 execCommand,含 try/catch 兜底、点击回调中调用、富文本/图片用 ClipboardItem、https/localhost 安全上下文限制与老浏览器降级等注意点。

博客里的"复制代码"、文档里的"复制命令"、卡片上的"复制邀请链接",都是很常见的按钮。早年的标准写法是 document.execCommand(‘copy’),选中内容再执行。但这个 API 早被标记为废弃(deprecated),而且行为各浏览器不一致,有些环境下还会吞掉选中状态。现在浏览器有原生的 Clipboard API,navigator.clipboard.writeText 一行把文本写进剪贴板,干净可靠,新项目直接用它。

一、最小实现

async function copy(text) {
  await navigator.clipboard.writeText(text)
  tip.textContent = "已复制"
}
btn.addEventListener("click", () => copy(codeEl.textContent))

点击按钮,把要复制的文本交给 writeText,浏览器自己处理写入剪贴板。writeText 返回 Promise:成功 resolve 表示复制好了,失败 reject。比 execCommand 返回布尔值、还得先 select 再 copy 直观得多。codeEl.textContent 就是要复制的源码文本,从 DOM 里直接取。

二、给个反馈、失败兜底

复制不一定每次都成功(比如页面不在前台、权限被拒),所以加 try/catch,失败给提示让用户手动选,别悄悄没反应:

async function copy(text) {
  try {
    await navigator.clipboard.writeText(text)
    showTip("已复制")
  } catch (e) {
    showTip("复制失败,请手动选择")
  }
}

showTip 可以是个轻提示,几秒后消失。这样用户知道结果,体验完整。

三、复制富文本和图片

writeText 只管纯文本。要复制带格式的内容(比如一段 HTML)或图片,用更通用的 navigator.clipboard.write,配合 ClipboardItem:

const item = new ClipboardItem({
  "text/html": new Blob([htmlString], { type: "text/html" }),
})
await navigator.clipboard.write([item])

ClipboardItem 的键是 MIME 类型,值是 Blob。纯文本场景用不到这个,writeText 足够。

四、几个要注意的点

第一,Clipboard API 要求"安全上下文":页面必须是 https 或 localhost,http 环境下调 writeText 会直接 reject,本地开发用 localhost 没事。第二,浏览器通常在"用户手势"里才允许复制(点击、按键),放在定时器或异步回调里可能被拦,所以复制逻辑放点击回调最稳。第三,读剪贴板用 readText,同样要安全上下文和权限,别随便读用户剪贴板,会被浏览器拦。第四,老浏览器不支持 clipboard 时降级回 execCommand,用 ‘clipboard’ in navigator 判断有没有原生 API,没有再走老路。第五,移动端部分浏览器对 Clipboard API 支持参差,真要做跨端的产品建议同时保留降级方案并测一遍。

五、小结

一键复制用 navigator.clipboard.writeText 最干净:一行把文本写进剪贴板,比废弃的 execCommand 可靠,也不用先 select。放在点击回调里调用、用 try/catch 兜底给反馈,留意只能 https/localhost 用。要复制富文本或图片换 ClipboardItem + write。老环境用 ‘clipboard’ in navigator 判断后降级回 execCommand,移动端记得测。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。