Touch事件实战总结那些年我踩过的坑和解决之道

Mc.佳妮 优化 阅读 532
赞 23 收藏
二维码
手机扫码查看
反馈

又踩坑了,touchmove滚动失效

今天在做一个移动端的项目时,遇到一个特别头疼的问题:touchmove事件突然不灵了。我之前用的好好的,也不知道怎么就出问题了。

Touch事件实战总结那些年我踩过的坑和解决之道

一开始我以为是代码出了什么错,检查了好几遍也没发现什么问题。后来试了下其他浏览器,发现只有在某些特定版本的安卓手机上才会有这个问题。这下我就懵了,到底是什么原因呢?

排查过程折腾了半天

首先,我怀疑是不是CSS有什么问题,毕竟有时候一些不起眼的样式就能导致这种奇怪的问题。我把相关CSS代码翻了个底朝天,没发现问题。然后我又检查了一下HTML结构,也没什么问题。

接着,我开始怀疑是不是JavaScript代码的问题。我注释掉了所有的事件监听器,一个个重新加上去测试,结果还是不行。这时候我已经有点绝望了,心想这到底是哪里出错了。

最后,我在网上搜了一圈,发现有人提到可能是由于默认的触摸行为被阻止了。我一想,对啊,我之前为了防止页面滚动,加了一个touchmove事件,并且在里面调用了event.preventDefault()。会不会是这个原因呢?

核心代码就这几行

找到了问题所在,接下来就是解决它了。其实很简单,只需要在touchmove事件中判断一下当前元素是否可以滚动,如果是的话就不阻止默认行为。具体代码如下:

document.addEventListener('touchmove', function(event) {
  if (event.target.closest('.scrollable')) {
    return;
  }
  event.preventDefault();
}, { passive: false });

这里的关键在于event.target.closest('.scrollable'),它会找到最近的一个带有.scrollable类的父元素。如果找到了,说明当前元素是可以滚动的,那么就返回不做任何处理;否则就阻止默认行为。

技术细节和原理

这个解决方案的核心在于理解touchmove事件和preventDefault()方法的作用。touchmove事件会在用户触摸屏幕并移动手指时触发,而preventDefault()方法则会阻止默认的行为(比如页面滚动)。如果我们不加区分地阻止所有touchmove事件,就会导致整个页面无法滚动。

通过event.target.closest('.scrollable'),我们可以判断当前元素是否在一个可以滚动的容器内。如果是的话,就让事件继续传递,不要阻止默认行为。这样既达到了阻止整个页面滚动的目的,又不影响滚动容器的正常工作。

踩坑提醒:这三点一定注意

1. **不要盲目阻止所有touchmove事件**:有些情况下我们确实需要阻止默认行为,但一定要确保这样做不会影响到其他功能。

2. **使用passive: false选项**:在添加touchmove事件监听器时,记得加上{ passive: false }选项,这样才能在事件处理函数中调用event.preventDefault()

3. **测试多种设备和浏览器**:移动端开发尤其要注意这一点,不同的设备和浏览器可能会有不同的表现。多测试几种情况,确保你的代码在各种环境下都能正常工作。

总结

以上是我这次踩坑后的总结,希望对你有帮助。如果你有更好的解决方案或者遇到类似问题,欢迎在评论区交流。前端开发就是这样,总是充满了各种坑,但只要我们不断学习和实践,总能找到解决问题的方法。

本文章不代表JZTHEME立场,仅为作者个人观点 / 研究心得 / 经验分享,旨在交流探讨,供读者参考。
发表评论

暂无评论