[JavaScript]移动端/解决scroll和touch事件的冲突/冒泡

发布时间 2023-08-30 22:36:32作者: mingruqi

假设有一个抽屉式菜单,根据手指的touch是会跟着动的,在面板任何地方右拉都会触发抽屉菜单的出现。

菜单隐藏的时候右边的内容是overflow:scroll的

这个时候滑动sroll的同时手指向右都会唤醒抽屉菜单,但是是不允许的。

其实按理来说右侧的面板内容如果一直不跳出文档流,也可能不需要额外处理,但是事实上由于嵌套各种position,导致尼玛一直冒泡,滚动松手只要有右滑迹象就会冒泡到深处把菜单唤醒……

原理:

第一个point就是在滚动的时候禁止touchmove的冒泡,注意是冒泡而不是preventdefalut,阻止默认事件会导致整个监听器在下次触发不可用【why??】而冒泡是每次触发都会冒泡的,这个时候可以设置一个flag,scroll事件之后的那个touchmove停止冒泡不触发,每次touchstart都要清零所有东西

第二个point就是手指触摸时间太短也是会触发冒泡把菜单拖出来……无语了,所以要设置一个时间间隔,间隔太短就不要冒泡了

代码

preventTouch() {
    let flag = false; // 是否滚动
    const main = document.getElementById('main');//有滚动的面板
    const cur = this;
    let dur = 0; // 触摸时间,太短不触发
    let date_start, date_end;
 
    main.addEventListener('touchstart', handler, { passive: false });
    main.addEventListener('touchmove', handler, { passive: false });
    main.addEventListener('scroll', handler, { passive: false });
 
    function handler(e) {
      switch (e.type) {
        case 'touchstart':
          flag = false;
          date_start = new Date();
          break;
        case 'touchmove':
          date_end = new Date();
          dur = date_end - date_start;
          if (flag || dur < 300) {//表示是滚动完成后的那个touch不触发/间隔太短
            e.stopImmediatePropagation(); // 阻止冒泡
          }
          break;
        case 'scroll':
          if (!flag) {
            flag = true;
          }
          break;
      }
 
    }
 
  }

 


————————————————
版权声明:本文为CSDN博主「帕尼尼270」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_38277033/article/details/94552814