浏览器中实现剪切板复制内容的功能
优先使用浏览器自带API
navigator.clipboard.writeText(text)
浏览器不支持
navigator.clipboard.writeText(text)
时:- 自建一个html元素,将要复制的值设置为元素内容
- 设置元素的用户选择相关的CSS
whiteSpace: 'pre', 'userSelect': all
,将元素添加到页面上 - 使用
window.getSelection()
window.document.createRange()
API来选中元素 - 执行
window.document.execCommand('copy')
来复制页面中已选中的内容
代码实现(clipboard-copy源码):
js
/*! clipboard-copy. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
/* global DOMException */
module.exports = clipboardCopy
function makeError () {
return new DOMException('The request is not allowed', 'NotAllowedError')
}
async function copyClipboardApi (text) {
// 可用时使用浏览器剪贴板API
if (!navigator.clipboard) {
throw makeError()
}
return navigator.clipboard.writeText(text)
}
async function copyExecCommand (text) {
// 将要复制的文本放入 <span>
const span = document.createElement('span')
span.textContent = text
// 保留连续的空格和换行符
span.style.whiteSpace = 'pre'
span.style.webkitUserSelect = 'auto'
span.style.userSelect = 'all'
// 将 <span> 添加到页面
document.body.appendChild(span)
// 创建一个代表用户选择的文本范围的选择对象
const selection = window.getSelection()
const range = window.document.createRange()
selection.removeAllRanges()
range.selectNode(span)
selection.addRange(range)
// 将文本复制到剪贴板
let success = false
try {
// window.document.execCommand('copy') 表示复制页面上已选中的内容
success = window.document.execCommand('copy')
} finally {
// 清除选择
selection.removeAllRanges()
window.document.body.removeChild(span)
}
if (!success) throw makeError()
}
async function clipboardCopy (text) {
try {
// 先使用自带API
await copyClipboardApi(text)
} catch (err) {
// 再尝试创建元素
try {
await copyExecCommand(text)
} catch (err2) {
throw (err2 || err || makeError())
}
}
}