1.PC端的click是点击事件,移动端的lick会存在300ms延迟
移动端的click是单击事件,单击事件:第一次点击后,监测300ms, 看是否有第二次点击操作,如果有就是单击,如果有就是双击。
如何解决:
单手指事件模型: touch模拟!!!touchstart,touchmove,touchend
要在React中模拟双击事件,可以使用浏览器本身的touchstart
和touchend
事件,配合setTimeout
来实现。
具体的实现思路如下:
-
监听
touchstart
事件,并记录下当前的时间戳timestamp1和点击的坐标coordinate1。 -
监听
touchend
事件,并在其中记录下当前的时间戳timestamp2和离开的坐标coordinate2。 -
判断
timestamp2 - timestamp1
是否在一定的时间范围内,比如500毫秒。 -
判断
coordinate1
和coordinate2
之间的距离是否在一定的范围内,比如20像素。 -
如果以上两个条件都满足,则视为一次双击事件,并执行相应的逻辑。
下面是一个示例代码,可以放在组件的componentDidMount
或者使用钩子函数进行挂载。
let lastTap = null;
let touchEndListener = null;
function handleTouchStart(e) {
const currentTime = new Date().getTime();
const tapLength = lastTap ? currentTime - lastTap : Infinity; // 两次触摸事件相隔的时间
lastTap = currentTime;
if (tapLength < 500 && tapLength > 0) { // 判断是否为双击事件
touchEndListener && clearTimeout(touchEndListener); // 清除touchend事件监听器
console.log('Double Tap detected'); // 输出双击事件信息
} else { // 否则,重新设置touchend事件监听器
touchEndListener = setTimeout(() => {
touchEndListener = null;
console.log('Single Tap detected'); // 输出单击事件信息
}, 500);
}
// 记录当前的触摸坐标
const { pageX, pageY } = e.touches[0];
this.touchStartPosition = { x: pageX, y: pageY };
}
function handleTouchEnd(e) {
const { pageX, pageY } = e.changedTouches[0];
const deltaX = pageX - this.touchStartPosition.x;
const deltaY = pageY - this.touchStartPosition.y;
// 判断当前的触摸距离是否在有效的双击范围内,比如20像素
if (Math.abs(deltaX) < 20 && Math.abs(deltaY) < 20) {
e.preventDefault(); // 阻止默认事件
}
}
在以上代码中,我们设置了一个lastTap
变量来记录上一次的触摸事件的时间戳,以判断当前的触摸事件是否为双击事件。在handleTouchStart
函数中,我们记录了当前触摸事件的时间戳和坐标,用来在后续计算双击事件是否有效。在handleTouchEnd
函数中,我们计算了当前的触摸坐标和起始坐标之间的位移,并判断是否在一定的范围内,以确定当前的触摸事件是否有效。如果有效,则使用e.preventDefault()
来阻止默认事件的触发。
2.在React中,我们给循环「创建」的元素做"循环事件绑定",好还是不好?
按照常理来讲,此类需求用事件委托处理是组好的! ! !但是在react中本身就是通过事件委托来做的,这种循环并没有给每个span绑定,而是给每一个渲染出来的span加了一个属性。以后点击某个span都是传递到root上,然后去通知对应span上那个onclick去执行