背景
目前小程序项目想要做到类似于抖音视频中,双击点赞,单击暂停的效果,但是小程序原生并没有双击事件,所以需要自己实现双击效果。现把实现过程记录如下:
0. 前置
页面绑定方法如下:
// 全局变量
let lastClickTimeStamp = 0; // 用户最后一次点击的时间戳
let isDouble = false;
let nClickNum = 0;
<view
bind:touchstart="touchStart"
bind:touchend="touchEnd"
>
</view>
1. 使用简单时间戳
1.1 实现思路
记录用户每次点击的时间戳,单击和双击的判断主要是上一次点击的时间 和 本次点击的时间 间隔时长进行判断,如果在定义的间隔时间内多次触发了点击,则判断为双击,否则认定为单击。这个思路是网上大多数人的实现思路。
实现代码如下:
isDoubleClick() {
let currentTime = Date.now();
let timeInterval = currentTime - lastClickTimeStamp;
if (timeInterval && timeInterval < 1500) {
return true; // 如果间隔在1500ms内就是快速重复点击
}
lastClickTimeStamp = currentTime;
return false; // 单击事件
},
touchEnd(){
if(this.isDoubleClick()){
// 双击
}else{
// 单击
}
}
演示如下:
存在问题:每次点击的时候,即使是双击,也会触发一次单击事件,这个是有问题的,但是如何如何记录第一次用户按下事件呢?
2. 使用时间戳和标志位
touchStart() {
let currentTime = Date.now()
if (currentTime - lastClickTimeStamp > 0 && currentTime - lastClickTimeStamp < 150) {
// 多次点击,每次点击间隔不超过150ms的,视为双击
console.log("双击")
this.clearTimeout()
isDouble = true
//在用户发生点击后,继续监听1500ms内所有的点击事件,并视为同一批事件,超时恢复标志位
setTimeout(() => {
isDouble = false
}, 1500)
}
},
touchEnd() {
this.clearTimeout();
// 当用户按下之后,先停止150ms,监听用户后续操作
if (!isDouble) {
timer = setTimeout(() => {
// 单击
console.log("单击")
isDouble = false // 初始化双击标志位
}, 150)
}
let currentTime = Date.now()
lastClickTimeStamp = currentTime
},
clearTimeout(){
if (timer) {
clearTimeout(timer)
}
},
在用户按下按钮后,先不进行任何操作,只更新lastClickTimeStamp
, 等待150ms,监听用户是否再次按下按钮。缺点是需要限定重置标志位的时间(在这里是1500ms), 如果用户一直点击,最后一次点击刚好标志位被重置的话,会额外触发一次单击事件。
演示如下:
3. 使用时间戳和点击次数
touchStart() {
++nClickNum;
},
touchEnd() {
if (nClickNum === 1) // 第一次点击
{
setTimeout(() => {
if (nClickNum >= 2) {
console.log("双击")
}
else {
console.log("单击")
}
nClickNum = 0 // 一旦定时到期就重新来过
}, 1000)// 监听1s内用户的点击操作
}
},
在用户按下后开始计数,第一次抬起的时候开启一个定时器,在一定时间内监听用户点击的次数,用来区分是单击还是快速连续点击。
演示如下:
总结
三种不同的技术方案,在没有原生双击事件支持的情况下,通过编程技巧实现类似功能。每种方法都有其优缺点,开发者可以根据具体需求选择适合的实现方式。
感谢身边所有人。