前言
想要實現長按復制首先需要需要實現“長按事件”
我們知道前端不像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;width: 0;,IOS下contentEditable屬性必須為true,readOnly不能為false。
-
不能通過js直接去執行window.exeCommand()方法,例如把復制事件綁定到一個元素的點擊事件,然后通過執行click()方法來觸發復制事件,這樣的結果放回的是也是false。
-
將復制事件綁定到document.body上,然后用戶點擊任意地方來觸發復制事件,這樣做在Android上是可行,但是IOS上不行,估計是安全策略方面的原因。
-
不能通過touchstart, touchmove, touchend事件來觸發復制事件,返回的都是false。