【问题标题】:Added non-passive event listener to a scroll-blocking 'touchstart' event向阻止滚动的“touchstart”事件添加了非被动事件侦听器
【发布时间】:2018-02-16 02:34:19
【问题描述】:

今天突然间,我开始在我们网站的每个页面上都看到这个

Added non-passive event listener to a scroll-blocking 'touchstart' event.
Consider marking event handler as 'passive' to make the page more responsive

而且它不仅仅是一次或两次......它就像成千上万的......

他们疯了。

阻止违规泛滥的唯一方法是注释掉这一行

  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js" type="text/javascript"></script>

我阅读了其他关于此违规含义的帖子,但我真的看不出我在两个小时前和现在之间做了什么不同(我做了一个完整的回滚只是为了看看它是否有帮助)

这几乎就像有人在 jquery.min.js 中放了一个错误,但我严重怀疑这一点,因为这样每个人都会得到它。

有什么想法吗?我尝试了所有可以调试的东西,但我仍然不知道是什么原因造成的?!?

更新

我用&lt;button data-toggle="tooltip" title="text"&gt;&lt;/button&gt; 替换了所有&lt;button&gt;&lt;md-tooltip&gt;text&lt;/md-tooltip&gt;&lt;/button&gt;,这消除了所有违规行为的99%。

【问题讨论】:

  • 您的旧版本仍然可以使用吗?因为这很可能是添加了这个的浏览器更新......
  • 嗯,好问题......我今天所做的只是将Speed Dial 2 - New tab 2.2.1 添加为 chrome 浏览器扩展(让您控制空白页面快捷方式) - 但我卸载了它以防万一造成问题。
  • 尝试在 firefox 上运行页面,这里 jquery 在缩小代码的深处进入无限循环。
  • 好的。尝试用未压缩的版本替换您的 jQuery 文件。查看错误时,您会有更好的想法。

标签: javascript jquery


【解决方案1】:

这解决了我的问题:

jQuery.event.special.touchstart = {
  setup: function( _, ns, handle ){
    if ( ns.includes("noPreventDefault") ) {
      this.addEventListener("touchstart", handle, { passive: false });
    } else {
      this.addEventListener("touchstart", handle, { passive: true });
    }
  }
};

【讨论】:

  • 我应该在哪里添加这个?在 JS 中还是在 JS 后包含?
  • 它对我有用,我只需要复制此代码即可抑制有关touchmove 的警告(只需将每个touchstart 替换为touchmove)。正如我从这个 jsbin (jsbin.com/bupesajoza/edit?html,js,output) 中了解到的,noPreventDefault 部分的目的是可以不使用“被动”侦听器。
  • if/else 块的内容应该交换:如果命名空间包含 noPreventDefault 那么被动应该有一个 default 值,即 真的
  • 另一个注意事项是 IE11 不支持“includes()”。它导致了一个错误,阻止了所有产品页面在我们的网站上显示。您可以在此处找到有关 polyfill 或替代实现的更多信息:stackoverflow.com/questions/31340868/…
  • ie 11 兼容版本:jQuery.event.special.touchstart = { setup: function( _, ns, handle ){ if ((ns.indexOf('noPreventDefault') > -1)) { this.addEventListener("touchstart", handle, {passive: false }); } else { this.addEventListener("touchstart", handle, { passive: true }); } } };
【解决方案2】:

我正在使用各种事件,这似乎解决了我的用例

(function () {
    if (typeof EventTarget !== "undefined") {
        let func = EventTarget.prototype.addEventListener;
        EventTarget.prototype.addEventListener = function (type, fn, capture) {
            this.func = func;
            if(typeof capture !== "boolean"){
                capture = capture || {};
                capture.passive = false;
            }
            this.func(type, fn, capture);
        };
    };
}());

【讨论】:

  • 好电话,这对我有用。我将此添加到我的 jQuery 文件的底部,称为 jquery.custom.min.js 并缩小它。像魅力一样工作。
  • 在 Internet Explorer 中 EventTarget 似乎未定义。所以我建议在 var func =` 行之前添加if (typeof EventTarget !== 'undefined') {
  • 我更喜欢这个解决方案,但是我在控制台[Violation] Added synchronous DOM mutation listener to a 'DOMNodeRemoved' event. Consider using MutationObserver to make the page more responsive. 中遇到了这个错误,还没有弄清楚如何使用 Mutation Observers 重写它。请帮忙?
  • 我在为 Google 地图标记设置动画时遇到了主题启动器的问题。此解决方案有效。
【解决方案3】:

好吧,再挖掘一下,这不是一个新行为,前段时间已经报道过,jQuery 仍然没有修复它。

问题在于,对于要成为passive 的处理程序,它必须确定永远不会调用preventDefault(),但jQuery 事先并不知道...

我能给您的唯一提示是更改控制台日志记录级别并删除“详细”。关注this issue 以获得解决此问题的想法。

【讨论】:

  • 问题是违规的数量会减慢网站的速度,我们在几个页面中 jQuery 进入无限循环并吐出多达 10,000 个违规(在我设法关闭浏览器之前)。如果我注释掉 jQuery,那么一切都很好。那么我们如何将处理程序设置为passive
  • Ok Salketer - 发现了一些东西...&lt;md-tooltip&gt;testing&lt;/md-tooltip&gt; 是导致这种违规的一件事,因为我使用了很多这些我得到了很多错误。我仍在检查原因,我确定有移动的东西导致它。
  • 还发现&lt;input type="date" ng-model="vm.date.checkin"&gt; 导致了很多这样的问题:[Violation] Added non-passive event listener to a scroll-blocking 'wheel' event. 但仅在您使用 ng-model 时才发生。
  • 仅凭这些 sn-ps,我无法为您提供更多帮助。但基本上,所有导致滚动的事件(滚轮、触摸、滚动)都会抛出这个,因为 jQuery 事件处理可能会阻止它们。因此,请尝试在您的输入中删除该轮事件,这非常奇怪......并查看其他事件。您还可以通过使用事件委托来减少处理程序的数量。
  • 现在我替换了所有 &lt;button&gt;&lt;md-tooltip&gt;text&lt;/md-tooltip&gt;&lt;/button&gt; 宽度 &lt;button data-toggle="tooltip" title="text"&gt;&lt;/button&gt; 这删除了 ​​99% 的违规行为。
【解决方案4】:

Sergio 的回答是正确的,将它添加到底部的 jquery 脚本中。如果 touchstart 和 touchmove 有问题,只需添加相同的代码并将 touchstart 替换为 touchmove,如下所示:

jQuery.event.special.touchstart = {
  setup: function( _, ns, handle ){
    if ( ns.includes("noPreventDefault") ) {
      this.addEventListener("touchstart", handle, { passive: false });
    } else {
      this.addEventListener("touchstart", handle, { passive: true });
    }
  }
};
jQuery.event.special.touchmove = {
  setup: function( _, ns, handle ){
    if ( ns.includes("noPreventDefault") ) {
      this.addEventListener("touchmove", handle, { passive: false });
    } else {
      this.addEventListener("touchmove", handle, { passive: true });
    }
  }
};

【讨论】:

    【解决方案5】:

    我认为,除了基于触摸的事件之外,您还可以添加基于滚动的修复,以防止 google 页面得分将其标记为桌面与移动:

    jQuery.event.special.wheel = {
        setup: function( _, ns, handle ){
            this.addEventListener("wheel", handle, { passive: true });
        }
    };
    jQuery.event.special.mousewheel = {
        setup: function( _, ns, handle ){
            this.addEventListener("mousewheel", handle, { passive: true });
        }
    };
    

    【讨论】:

      猜你喜欢
      • 2018-03-14
      • 2018-12-01
      • 2019-11-08
      • 1970-01-01
      • 2018-02-18
      • 2020-07-25
      • 1970-01-01
      • 1970-01-01
      • 2017-06-25
      相关资源
      最近更新 更多