此文记录一下楼主遇到的坑
内容都是实际运行过的 请放心使用
1、实现JS环境中复制文字到剪贴板
主要应用场景为方便用户复制内容 提升用户体验(比如订单号?git clone的地址?等)
去度娘一搜 好家伙 一大堆 然后时间一看 好家伙 排到前面的都是2014年的回答,大部分回答都还一样???
经过MDN 等多方查证,现总结如下
let tx = document.getElementById('copycon') 或者 tx = this.$refs.copycon (vue环境)
// 创建select对象与range对象
const selection = window.getSelection()
const range = document.createRange()
// 从当前selection对象中移除所有的range对象,
// 取消所有的选择只 留下anchorNode 和focusNode属性并将其设置为null。
// 这里没弄明白为什么需要先remove一下, 也没有太多资料查证 没有这句会复制失败
if(selection.rangeCount > 0) selection.removeAllRanges()
// 使 Range 包含某个节点的内容 使用这个 或者下面的selectNode都可以
// range.selectNodeContents(tx)
// 使 Range 包含某个节点及其内容
range.selectNode(tx)
// 向选区(Selection)中添加一个区域(Range)
selection.addRange(range)
// 已复制文字
// console.log('selectedText', selection.toString())
// 执行浏览器复制命令
document.execCommand('copy')


点击后即可选中,并将div里的内容复制到剪贴板,使用时直接ctrl + v 即可
但是这种方法楼主没有找到复制多个的方法,即假如我现在有2个div的内容是需要复制的 无法重复添加 只能去先一步获取并拼接(dom.innerHTML)
贴一下mdn上的循环添加获取 楼主去撸了一遍代码 发现并不能实现

循环无法实现 只能复制到第一个dom的内容 (3年后更新文章再想想可能是以前自己太菜了 没搞明白逻辑,MDN大佬是不可能会出错的)
2、实现input / textarea中的复制
后来我又发现使用input / textarea进行复制操作 这种方式更加简单 因为二者有一个select() 函数能够便捷的复制而不需要去创建select对象与range对象
如下
let input = document.createElement('input')
input.setAttribute('readonly', 'readonly') // 防止手机上弹出软键盘
input.setAttribute('value', txval) // txval 为所需复制的值 变量 或者 写死
document.body.appendChild(input)
input.select()
document.execCommand('copy')
document.body.removeChild(input)
这里动态创建一个input 然后再最后remove就好,而不需要在html中硬性使用input / textarea去展示,更加优雅
但是此处注意 当你的txval为多个值拼接 并需要在剪贴板换行时 使用input标签无法满足
比如你需要这种格式(log打印已经换行了)

但是实际复制再粘贴测试是一行

要实现换行需使用textarea标签
let that = this
let txa = document.createElement('textarea')
let txval = 'SN:' + that.sn1 + '\n' + 'MAC:' + that.mac1 + '\n' + 'IMEI:' + that.imei1 + '\n' + 'PORT:' + that.port1
// console.log('copy val:', txval)
txa.value = txval
document.body.appendChild(txa)
txa.select()
let res = document.execCommand('copy')
document.body.removeChild(txa)
console.log('copy success')
3、现代方法 navigator.clipboard.writeText()
先上一张兼容截图
然后直接上代码,兼容一下旧版复制(因为遇到个奇葩问题,同事更新了chrome 130版本 但是不支持 navigator.clipboard ! 我甚至怀疑他装了个山寨版)
const text = this.entName + '\n邀请您访问链接成为内部合作司机\n链接: ' + this.codeUrl
if ('clipboard' in navigator) {
console.log('clipboard API可用')
navigator.clipboard.writeText(text).then(
() => {
this.$message.success('复制成功')
},
err => {
console.error('复制失败', err)
}
)
} else {
// 剪贴板API不可用
console.log('clipboard API不可用')
const textarea = document.createElement('textarea');
textarea.value = text;
document.body.appendChild(textarea);
textarea.focus();
textarea.select();
try {
document.execCommand('copy');
this.$message.success('复制成功')
} catch (err) {
console.error('Failed to copy text: ', err);
}
document.body.removeChild(textarea);
}