前言
想要实现长按复制首先需要需要实现“长按事件”
我们知道前端不像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。