# 优化复制功能
# 背景
最近遇到个复制的需求,在项目中找了下,发现存在写好的功能,于是直接调用,发现在chrome下居然是弹窗让我手动复制,于是看了下源码,居然是兼容古老的浏览器写法,在现在这个环境下已经失去了意义,所以动手优化一下。
# 实现
为了不影响之前的功能,只能用兼容的写法,在之前的一堆if-else的倒数第二处加个自己的判断。
if (window.clipboardData) {
xxx
} else if (navigator.userAgent.indexOf('Opera') != -1) {
xxx
} else if (window.netscape) {
xxx
} else if ($clipboard(content)) {
在这里
} else {
xxx
}
复制的逻辑主要参考了vue-clipboard2。
其主要原理就是创建一个textarea,将需要复制的值赋给textarea,然后选中,再执行复制操作document.execCommand('copy')
即完成了操作。
注意下环境的兼容,ios设备上需要专门去选中textarea,才可以复制。
复制完将创建的内容都清了,避免内存泄漏。
主要改动在成功或失败都得返回结果告知上层函数,在失败时能走向最终的逻辑,也就是弹窗手动复制。
源码贴上
var $clipboard = function(input) {
var value;
var success = false;
if (typeof input !== 'string') {
try {
value = JSON.stringify(input);
} catch (e) {
return false;
}
} else {
value = input;
}
var textarea = document.createElement('textarea');
textarea.value = value;
textarea.setAttribute('readonly', '');
textarea.style.cssText = 'position:fixed;pointer-events:none;z-index:-9999;opacity:0;';
document.body.appendChild(textarea);
if (navigator.userAgent.match(/ipad|ipod|iphone/i)) {
textarea.contentEditable = true;
textarea.readOnly = true;
var range = document.createRange();
range.selectNodeContents(textarea);
var selection = window.getSelection();
selection.removeAllRanges();
// 让window选中textarea
selection.addRange(range);
// 设置textarea的光标选中位置为大致全部
textarea.setSelectionRange(0, 999999);
} else {
textarea.select();
}
try {
success = document.execCommand('copy');
} catch (err) {
console.warn(err);
}
document.body.removeChild(textarea);
return success;
};