前言
想要实现长按复制首先需要需要实现“长按事件”
我们知道前端不像app原生,app原生有长按的api,前端却没有
所以我们需要模拟“长按事件”
如何模拟长按事件
pc端:使用mousedown mouseup mousemove模拟长按事件
<script>
var timeout;//用于存储定时器的变量
//#moveLeft 表示需要监听长按事件的元素
$("#moveLeft").mousedown(function() {
timeout= setTimeout(function() {
alert(2)
}, 500);//鼠标按下0.5秒后发生alert事件
});
$("#moveLeft").mouseup(function() {
clearTimeout(timeout);//清理掉定时器
});
$("#moveLeft").mouseout(function() {
clearTimeout(timeout);//清理掉定时器
});
</script>
移动端:使用touchstart、touchend、touchmove模拟长按事件
$("#target").on({
touchstart: function(e) {
// 长按事件触发
timeOutEvent = setTimeout(function() {
timeOutEvent = 0;
alert('你长按了');
}, 400);
//长按400毫秒
// e.preventDefault();
},
touchmove: function() {
clearTimeout(timeOutEvent);
timeOutEvent = 0;
},
touchend: function() {
clearTimeout(timeOutEvent);
if (timeOutEvent != 0) {
// 点击事件
// location.href = '/a/live-rooms.html';
alert('你点击了');
}
return false;
}
})
如何实现复制
// 复制函数 _getCopy: function(copyData) { var that = this; if (typeof document.execCommand == "function") { console.log('execCommand'); var transfer = document.createElement('textarea'); // 修改文本框的内容 transfer.value = copyData; //消除默认样式,避免个别手机白块 transfer.style.width = '0px'; transfer.style.height = '0px'; $("body").prepend(transfer); if (that.isIphone) { transfer.disabled = "true"; transfer.readonly="readonly"; } // 选中文本 transfer.focus(); transfer.select(); transfer.setSelectionRange(0, transfer.value.length); console.log(transfer.value); // 执行浏览器复制命令 document.execCommand('copy'); transfer.blur(); document.body.removeChild(transfer); Ariel.Components.PopWithIcon.show('复制成功','',500); } else { Ariel.Components.PopWithIcon.show('复制失败','',500); } }
如何实现长按复制
pc端
var timeout;//用于存储定时器的变量 //#moveLeft 表示需要监听长按事件的元素 $("#moveLeft").mousedown(function() { timeout= setTimeout(function() { _getCopy(copyData) }, 500);//鼠标按下0.5秒后发生alert事件 }); $("#moveLeft").mouseup(function() { clearTimeout(timeout);//清理掉定时器 }); $("#moveLeft").mouseout(function() { clearTimeout(timeout);//清理掉定时器 }); // 复制函数 function _getCopy(copyData) { var that = this; if (typeof document.execCommand == "function") { console.log('execCommand'); var transfer = document.createElement('textarea'); // 修改文本框的内容 transfer.value = copyData; //消除默认样式,避免个别手机白块 transfer.style.width = '0px'; transfer.style.height = '0px'; $("body").prepend(transfer); if (that.isIphone) { transfer.disabled = "true"; transfer.readonly="readonly"; } // 选中文本 transfer.focus(); transfer.select(); transfer.setSelectionRange(0, transfer.value.length); console.log(transfer.value); // 执行浏览器复制命令 document.execCommand('copy'); transfer.blur(); document.body.removeChild(transfer); Ariel.Components.PopWithIcon.show('复制成功','',500); } else { Ariel.Components.PopWithIcon.show('复制失败','',500); } }
移动端
$("#target").on({
touchstart: function(e) {
// 长按事件触发
timeOutEvent = setTimeout(function() {
timeOutEvent = 0;
_getCopy(copyData);
}, 400);
//长按400毫秒
// e.preventDefault();
},
touchmove: function() {
clearTimeout(timeOutEvent);
timeOutEvent = 0;
},
touchend: function() {
clearTimeout(timeOutEvent);
if (timeOutEvent != 0) {
// 点击事件
// location.href = '/a/live-rooms.html';
alert('你点击了');
}
return false;
}
})
// 复制函数
function _getCopy(copyData) {
var that = this;
if (typeof document.execCommand == "function") {
console.log('execCommand');
var transfer = document.createElement('textarea');
// 修改文本框的内容
transfer.value = copyData;
//消除默认样式,避免个别手机白块
transfer.style.width = '0px';
transfer.style.height = '0px';
$("body").prepend(transfer);
if (that.isIphone) {
transfer.disabled = "true";
transfer.readonly="readonly";
}
// 选中文本
transfer.focus();
transfer.select();
transfer.setSelectionRange(0, transfer.value.length);
console.log(transfer.value);
// 执行浏览器复制命令
document.execCommand('copy');
transfer.blur();
document.body.removeChild(transfer);
Ariel.Components.PopWithIcon.show('复制成功','',500);
} else {
Ariel.Components.PopWithIcon.show('复制失败','',500);
}
}
本以为这样就可以了,结果在移动端各种尝试发现都不行。。。。。
打日志发现 document.execCommand('copy') 一直返回false!!!
原因
经过调查发现以下几点
-
window.execCommand()方法不支持异步,像setTimeout,ajax异步中去执行都会返回false。
-
input框不能设置display:none; 0;,IOS下contentEditable属性必须为true,readOnly不能为false。
-
不能通过js直接去执行window.exeCommand()方法,例如把复制事件绑定到一个元素的点击事件,然后通过执行click()方法来触发复制事件,这样的结果放回的是也是false。
-
将复制事件绑定到document.body上,然后用户点击任意地方来触发复制事件,这样做在Android上是可行,但是IOS上不行,估计是安全策略方面的原因。
-
不能通过touchstart, touchmove, touchend事件来触发复制事件,返回的都是false。