最近在项目中遇到一个在【移动端网页中复制内容到剪切板】的需求,首先想到 H5 新的 API 似乎增加了 Clipboard 的支持,先来看看兼容情况,这一看真是老泪纵横啊,时隔多年浏览器的支持竟然还这么的差。
01.png这条路只能放弃,同事找到了一个第三方库-clipboardjs ,测试了一下可以完全兼容手机和 PC 。很好奇它是怎么做到的,拜读了源码,原来是重点是 document.execCommand 。曾经在做富文本编辑器的时候使用过这个 API,竟然没有想起来,真是惭愧。再来看一下它的兼容性:
02.png看着这片绿色就让人心情好,我们利用 document.execCommand 先来自己写一个小demo:
var randomStr = Math.random().toString(16);
var sourceDOM = document.getElementById('sourceDOM'),
messageDOM = document.getElementById('messageDOM'),
copyBtn = document.getElementById('copyBtn');
sourceDOM.value = randomStr;
copyBtn.onclick = function() {
copyTextToClipboard();
};
function copyTextToClipboard() {
sourceDOM.select();
sourceDOM.setSelectionRange(0, sourceDOM.value.length);
var flag = false;
try {
flag = document.execCommand('copy');
} catch (err) {
}
if (flag) {
messageDOM.innerText = '复制成功!';
sourceDOM.blur();
} else {
messageDOM.innerText = '复制失败!';
}
setTimeout(function () {
messageDOM.innerText = '';
}, 2000);
}
https://codepen.io/xbl/pen/pLGeGB
这里的 demo 只有30行的 js 代码,就可以完成对 Textarea
标签的内容进行复制,需要注意的一点,移动端中只有通过事件触发才可以选中文本。当然,这还不够,我们需要更复杂的功能,能够复制所有元素的文本,我们再对 demo 改进一下:
var messageDOM = document.getElementById('messageDOM');
// 实现一个简单的委托,简化绑定事件代码
document.addEventListener('click', function (event) {
var copyBtn = event.srcElement;
if (copyBtn.className !== 'copyBtn')
return ;
var sourceDOM = document.getElementById(copyBtn.getAttribute('source-element'));
var text = getElementText(sourceDOM);
if (copyTextToClipboard(text)) {
messageDOM.innerText = '复制成功!';
} else {
messageDOM.innerText = '复制失败!';
}
document.body.removeChild(textArea);
setTimeout(function () {
messageDOM.innerText = '';
}, 2000);
}, false);
function getElementText(element) {
var nodeName = element.nodeName,
text = '';
switch(nodeName) {
case 'SELECT':
case 'INPUT':
case 'TEXTAREA':
text = element.value;
break;
default:
text = element.innerText;
}
return text;
};
function copyTextToClipboard(text) {
var textArea = document.createElement('textarea');
textArea.style.position = 'fixed';
textArea.style.top = '-9999px';
textArea.style.left = '-9999px';
textArea.style.zIndex = -9999;
textArea.value = text;
textArea.setAttribute('readonly', '');
document.body.appendChild(textArea)
textArea.select();
textArea.setSelectionRange(0, textArea.value.length);
var flag = false;
try {
flag = document.execCommand('copy');
} catch (err) {
}
return flag;
}
https://codepen.io/xbl/pen/pLGrEO
增加了20几行的代码,来讲一下思路:点击【Copy】时先获得元素的文本,再动态创建了一个 Textarea
标签,将元素的文本赋值给 Textarea
然后选中,执行 document.execCommand('copy')
复制到剪切板,之后删除 Textarea
标签,是不是 So Easy!
网友评论