JS实现复制功能

最近公司项目有一个需求,实现一键复制激活码功能;发现用document的execCommand方法可以实现复制功能,下面上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
<body>
<input type="" name="" id="inp">
<button id='btn' onclick='copytext()'>点击复制</button>
</body>
<script type="text/javascript">
let inp = document.getElementById('inp');
let btn = document.getElementById('btn');
function copytext(){
inp.select();
document.execCommand("copy");
alert("复制成功");
}
</script>

您可以点击这里看示例

进阶篇

直接复制p标签之类的里面的文本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<body>
<p id="text">这是被复制的文本</p>
<input type="text" name="" id="inp" style="display: none">
<button id="btn" onclick='copyText()'>点击复制p标签里面的内容</button>
<textarea placeholder="粘贴到这里试试" rows="10"></textarea>
</body>
<script type="text/javascript">
function copyText(){
let txt = document.getElementById('text').innerText;
let inp = document.getElementById('inp');
inp.value = txt;
inp.select();
document.execCommand('copy');
alert('复制成功');
}
</script>

您可以点击这里看复制p标签的示例

改良篇

利用Range 对象和HTML5的Selection API

1
2
3
4
5
6
7
8
9
10
11
12
function copy(el) {
var range = document.createRange();
var end = el.childNodes.length;
range.setStart(el,0);
range.setEnd(el,end);

var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
document.execCommand("copy",false,null);
selection.removeRange(range);
}

首先是利用**document.createRange()**创建一个 Range 对象 ,然后获取所需复制元素的子元素的长度大小,然后调用Range对象的setStart和setEnd方法设置选择区域的大小。
此时只是设置了选择区域的大小,实际上在window中并没有真正选中,所以还需要调用window.getSelection()生成一个 Selection 对象,在添加选区之前最好先调用selection.removeAllRanges()清除其他的选区,否则浏览器可能会发出下面的警告,然后再调用 Selection 对象的addRange方法,将上一步的 range 作为参数传入,即可将所需复制的元素真正设置为被选择区域。
现在就可以像平时选中文字后调用document.execCommand来实现将被选择区域的文字复制到剪贴板。
最后还需要调用 Selection 对象的removeRange方法将 Range 对象移除,保证被选择区域永远只有一个被选择的元素,否则某些浏览器在下次可能会因为有两个被选择元素而发出警告或者报错。

最终版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
const clipboardWriteText = (copyText) => {
// 判断是否存在clipboard并且是安全的协议
if (navigator.clipboard && window.isSecureContext) {
return new Promise((resolve, reject) => {
navigator.clipboard
.writeText(copyText)
.then(() => {
resolve();
})
.catch(() => {
reject(new Error('复制失败'));
});
});
}
// 否则用被废弃的execCommand
const textArea = document.createElement('textarea');
textArea.value = copyText;
// 使text area不在viewport,同时设置不可见
textArea.style.position = 'absolute';
textArea.style.opacity = '0';
textArea.style.left = '-999999px';
textArea.style.top = '-999999px';
document.body.append(textArea);
textArea.focus();
textArea.select();
return new Promise((resolve, reject) => {
// 执行复制命令并移除文本框
if (document.execCommand('copy')) {
document.execCommand('copy');
resolve();
} else {
reject(new Error('复制失败'));
}
textArea.remove();
});
};

// 使用
clipboardWriteText('balabalabala')
.then(() => {
console.log('复制成功');
})
.catch(() => {
console.log('复制失败');
});

参考链接


JS实现复制功能
https://xypecho.github.io/2018/03/21/JS实现复制功能/
作者
很青的青蛙
发布于
2018年3月21日
许可协议