zoukankan      html  css  js  c++  java
  • Unable to preventDefault inside passive event listener

    最近做项目经常在 chrome 的控制台看到如下提示:

    Unable to preventDefault inside passive event listener due to target being treated as passive. See https://www.chromestatus.com/features/5093566007214080

    于是 Google 了一番,找到这篇文章,有了详细解释。Making touch scrolling fast by default

    简而言之:

    由于浏览器必须要在执行事件处理函数之后,才能知道有没有掉用过 preventDefault() ,这就导致了浏览器不能及时响应滚动,略有延迟。
    
    所以为了让页面滚动的效果如丝般顺滑,从 chrome56 开始,在 window、document 和 body 上注册的 touchstart 和 touchmove 事件处理函数,会默认为是 passive: true。浏览器忽略 preventDefault() 就可以第一时间滚动了。
    
    举例:
    wnidow.addEventListener('touchmove', func) 效果和下面一句一样
    wnidow.addEventListener('touchmove', func, { passive: true })

    这就导致了一个问题:

    如果在以上这 3 个元素的 touchstart 和 touchmove 事件处理函数中调用 e.preventDefault() ,会被浏览器忽略掉,并不会阻止默认行为。

    测试:

    body {
      margin: 0;
      height: 2000px;
      background: linear-gradient(to bottom, red, green);
    }
    
    // 在 chrome56 中,照样滚动,而且控制台会有提示,blablabla
    window.addEventListener('touchmove', e => e.preventDefault())

    那么如何解决这个问题呢?不让控制台提示,而且 preventDefault() 有效果呢?
    两个方案:
    1、注册处理函数时,用如下方式,明确声明为不是被动的
    window.addEventListener('touchmove', func, { passive: false })

    2、应用 CSS 属性 touch-action: none; 这样任何触摸事件都不会产生默认行为,但是 touch 事件照样触发。
    touch-action 还有很多选项,详细请参考touch-action

    [注]未来可能所有的元素的 touchstart touchmove 事件处理函数都会默认为 passive: true

  • 相关阅读:
    URAL 2046 A
    URAL 2056 Scholarship 水题
    Codeforces Gym 100286I iSharp 水题
    Codeforces Gym H. Hell on the Markets 贪心
    Codeforces Gym 100286G Giant Screen 水题
    Codeforces Gym 100286B Blind Walk DFS
    Codeforces Gym 100286F Problem F. Fibonacci System 数位DP
    Codeforces Gym 100286A. Aerodynamics 计算几何 求二维凸包面积
    Codeforces Gym 100418K Cards 暴力打表
    Codeforces Gym 100418J Lucky tickets 数位DP
  • 原文地址:https://www.cnblogs.com/ecmasea/p/9437660.html
Copyright © 2011-2022 走看看