考虑将事件处理程序标记为“被动”以使页面更具响应性

IT技术 javascript jquery angularjs touch hammer.js
2021-02-03 04:44:58

我正在使用锤子进行拖动,并且在加载其他东西时它变得断断续续,因为这条警告消息告诉我。

由于主线程忙,“touchstart”输入事件的处理延迟了 X 毫秒。考虑将事件处理程序标记为“被动”以使页面更具响应性。

所以我试着像这样给听众添加“被动”

Hammer(element[0]).on("touchstart", function(ev) {
  // stuff
}, {
  passive: true
});

但我仍然收到此警告。

6个回答

对于那些第一次收到此警告的人来说,这是由于最近(2016 年夏季)在浏览器中实现了一种称为被动事件侦听器的前沿功能https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md

被动事件侦听器是 DOM 规范中的一项新功能,通过消除滚动阻止触摸和滚轮事件侦听器的需要,开发人员可以选择加入以获得更好的滚动性能。开发人员可以使用 {passive: true} 注释触摸和滚轮侦听器,以表明他们永远不会调用 preventDefault。此功能在 Chrome 51、Firefox 49 中提供,并在 WebKit 中登陆。有关完整的官方解释,请在此处阅读更多内容。

另请参阅:什么是被动事件侦听器?

您可能需要等待 .js 库实现支持。

如果您通过 JavaScript 库间接处理事件,您可能会受制于该特定库对该功能的支持。截至 2019 年 12 月,似乎没有任何主要图书馆实施支持。一些例子:

Google Maps JavaScript API 版本 3 也会生成这些警告。正在issuetracker.google.com/issues/63211698跟踪问题(有点讽刺,考虑到谷歌浏览器正在警告谷歌地图 JavaScript API 生成的违规行为。)
2021-03-27 04:44:58
要抑制此警告,您可以` addEventListener('touchstart', this.callPassedFuntion, {passive: false })`
2021-04-02 04:44:58
我正在打电话preventDefault()- 是否可以取消此警告?
2021-04-04 04:44:58
离子库呢?
2021-04-09 04:44:58
2021-04-14 04:44:58

这将隐藏警告消息:

jQuery.event.special.touchstart = {
  setup: function( _, ns, handle ) {
      this.addEventListener("touchstart", handle, { passive: !ns.includes("noPreventDefault") });
  }
};
当然是伊万!是的。嘿,现在我很好奇……我正在使用 d3 插件,但我收到了 2300 次违规。也许您的代码会有所帮助!我会及时向大家发布!
2021-03-17 04:44:58
目标不是阻止实际事件吗?在处理问题之前,我不想隐藏消息。
2021-03-18 04:44:58
我认为这是一个 jquery 库问题。我认为开发人员必须修复它。但如果你能得到它,请告诉我如何去做。太感谢了。
2021-03-22 04:44:58
@yardpenalty.com,不,停止活动不是目标!警告指出您已放置侦听器,但未指定它是否会阻止事件的默认行为。如果您有要调用的情况preventDefault(),则应指定passive: false. 如果没有,请指定passive: true如果您没有指定任何一个,您只会收到警告。如果您指定passive: truepreventDefault()被调用,它导致一个错误,而不是防止违约。passive在这里指定不是黑客。这就是解决方案这就是警告所要求的!
2021-03-26 04:44:58
@tao 感谢评论。已经过去几年了,但我将来肯定会记住解决方案!
2021-04-01 04:44:58

对于带有 jquery-ui-touch-punch 的 jquery-ui-dragable,我修复了它类似于 Iván Rodríguez,但还有一个用于 touchmove 的事件覆盖:

jQuery.event.special.touchstart = {
    setup: function( _, ns, handle ) {
        this.addEventListener('touchstart', handle, { passive: !ns.includes('noPreventDefault') });
    }
};
jQuery.event.special.touchmove = {
    setup: function( _, ns, handle ) {
        this.addEventListener('touchmove', handle, { passive: !ns.includes('noPreventDefault') });
    }
};

在 Laravel 的 select2 下拉插件中也会遇到这个。按照 Alfred Wallace 的建议更改值

this.element.addEventListener(t, e, !1)

this.element.addEventListener(t, e, { passive: true} )

解决了这个问题。为什么他投反对票,我不知道,但这对我有用。

谢谢兄弟,这很好用 - 用 JQuery 3.5.1 测试过
2021-03-15 04:44:58

以下库解决了该问题。
只需将此代码添加到您的项目中即可。

<script type="text/javascript" src="https://unpkg.com/default-passive-events"></script>

如果您需要更多信息,请访问该图书馆