最近看很多B站UP主在視頻開始or結束都會請求觀衆來個一鍵三連,具體操做就是用戶長按點贊按鈕,一段時間後會觸發某個事件,一次性完成點贊、投幣和收藏操做。下面將從前端工程師的角度,來分析一下這個過程,並給出個人實現方式~javascript
首先來講,實現一鍵三連須要同時知足兩個必要條件,一是「點擊」點贊按鈕,二是須要長按。上面的「點擊」我用引號進行了標記,是由於用戶感知的「點擊」行爲是比較抽象的,而在前端工程師眼裏觸發click
事件會經歷一個有序觸發相關事件的過程。css
首先在PC端,前端工程師眼裏觸發click
事件會先依次觸發mousedown
和mouseup
事件。而在移動端,觸發click
事件會先依次觸發touchstart
和touchend
事件。html
根據click
事件規範,咱們知道在PC端鼠標按下任意鍵並釋放該鍵以後會觸發click
,「按下」和「釋放」對應mousedown
和mouseup
事件。移動端由於頁面滾動等操做須要手指觸摸屏幕來完成,所以觸發click
事件以前,會先依次觸發touchstart
和touchend
事件。基於上述理解可知mouseup/touchend
事件和click
事件之間的時間間隔很小,要實現「長按」操做,最優選擇是在mousedown/touchstart
和mouseup/touchend
事件之間執行相關操做。下面將實現一種一鍵三連的效果前端
長按3秒點贊,一鍵三連;長按時間少於1s則視爲僅點贊;長按時間在1s至3s之間,視爲一鍵三連失敗,不作任何操做。java
在mousedown/touchstart
事件觸發時,記錄觸發時間,同時經過setTimeout
設置定時器前端工程師
在mouseup/touchend
事件觸發時,計算當前時間和mousedown/touchstart
事件觸發時的時間差,根據時間差決定進一步操做。ui
//html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="viewport" content="user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style> #clickBtn { width: 60px; height: 40px; background: red; } </style>
</head>
<body>
<div id="clickBtn"></div>
<p id="timeText"></p>
</body>
</html>
複製代碼
//點贊、一鍵三連方法
function like(){
console.log("點贊");
}
function longPress(){
console.log("一鍵三連");
}
function getTime() {
const now = new Date().getTime();
timeText.innerText = (now - start) / 1000;
}
複製代碼
let timer, startTime, setTimeText;
let start = new Date().getTime();
const clickBtn = document.getElementById("clickBtn");
const timeText = document.getElementById("timeText");
timeText.innerText = "";
clickBtn.addEventListener("mousedown",function(){
startTime = new Date().getTime();//獲取mousedown觸發時間
setTimeText = setInterval(getTime, 100);
timer = setTimeout(longPress, 3000);//設置定時器
});
clickBtn.addEventListener("mouseup",function(){
const now = new Date().getTime(); //獲取mouseup觸發時間
clearInterval(setTimeText);
if (now - startTime < 1000) { //點按僅觸發點贊
like();
clearTimeout(timer);
} else if (now - startTime < 3000) { //長按時間不足,不觸發任何操做
clearTimeout(timer);
}
});
複製代碼
移動端實現只須要將對應事件替換爲touchstart
和touchend
便可~spa