前言
想要實現長按復制首先需要需要實現“長按事件”
我們知道前端不像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。
