js复制文本到剪切板.md

使用execCommand 和 navigator.clipboard

  最开始做这个需求的时候说可以直接用项目中已有的代码具体代码如下所示。具体就是查看是否支持clipboard,如果不支持使用execCommand。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if (navigator.clipboard && navigator.permissions) {
await navigator.clipboard.writeText(txt)
} else {
const textArea = document.createElement('textArea')
textArea.value = txt
textArea.style.width = 0
textArea.style.position = 'fixed'
textArea.style.left = '-999px'
textArea.style.top = '10px'
textArea.setAttribute('readonly', 'readonly')
document.body.appendChild(textArea)

textArea.select()
document.execCommand('copy')
document.body.removeChild(textArea)
}

  这里具体clipboard和execCommand的差别具体可以查看如下文章JS复制文字到剪切板的极简实现及扩展

  大致解释下就是execCommand兼容性好,但是有如下三个缺点

  • 必须select元素,可能会造成浏览器默认的滚动行为
  • execCommand为同步行为,文本量大时可能会造成卡顿
  • 无法直接访问剪切板内容,如果有修改的话,需要先将内容扔到页面上然后再修改然后再执行复制

  但是提测后马上bug就过来了,ios中无效。后续搜索后发现其实是这边实现问题,本次需求是点击按钮后访问一个接口然后获取结果并复制到剪切板。这个情况就不是用户点击事件中直接使用api,ios会禁止writeText的api访问。

  最终在以下链接找到了方案 navigator.clipboard.writeText fails in Safari。具体就是使用navigator.clipboard.write api

  虽然吧,网上都推荐clipboard js但是实际个人使用下来,clipboardjs一定得指定一个元素,很不爽,所以本次用到的代码封装了一份js放到github,以后还是用自己的。