最近在实现点击复制标签文本内容时,踩了一点小坑,记录下来分享给大家,如何实现一键点击复制功能,以及避免踩坑。
方法介绍
第一种是document.execCommand()。
exeCommand方法是document提供的API,该命令允许运行命令来操作可编辑内容区域的元素,我们使用到的命令是copy
具体代码如下:
function copyTextByExecCommand (text) {
let textArea = document.createElement('textArea')
textArea.value = text
textArea.style.display = "none"
document.body.appendChild(textArea)
textArea.focus()
textArea.select()
try {
let success = document.execCommand('copy')
let msg = success ? '已复制文本到剪切板' : '复制文本失败'
alert(msg)
} catch (err) {
alert(`复制文本时出现异常: ${err}`)
}
document.body.removeChild(textArea)
}
第二种方法是navigator.clipboard。
navigator.clipboard是浏览器提供的API,在用户授予权限下,能够提供系统剪贴板的读写访问。因此我们可以使用navigator.clipboard.writeText()方法将文本写入到操作系统的剪贴板(另外navigator.clipboard.write()可以写入任意数据到剪贴板中)。
代码如下:
function copyTextByClipboard (text) {
navigator.clipboard.writeText(text)
.then(() => {
alert('已复制文本到剪切板')
})
}
但这样使用此API,会有拷贝失败的风险。 原因是此API要求用户授予相应权限之后,或要求网站具有一定的安全性,如HTTPS或localhost。 以上代码,在https或localhost下能够成功复制,在http下却无法复制。
建议结合方法一,对http进行兼容。因为在HTTP协议下使用获取授权的方法来使用API,会直接得到拒绝,而不是弹出预期的弹窗,来询问用户授权。
获取授权的方法如下:
navigator.permissions.query({ name: 'clipboard-write' })
.then((result) => {
// 可能是 'granted', 'denied' or 'prompt'
if (result.state === 'granted') {
copyTextByClipboard(text)
} else if (result.state === 'prompt') {
console.log('prompt')
} else {
console.log('reject')
}
})
运行结果:
使用execCommand进行兼容,代码实现如下:
function copyText (text) {
if (typeof(navigator.clipboard) == 'undefined') {
copyTextByExecCommand(text)
return
}
copyTextByClipboard(text)
}