考虑将事件处理程序标记为“被动”以使页面更具响应性
Posted
技术标签:
【中文标题】考虑将事件处理程序标记为“被动”以使页面更具响应性【英文标题】:Consider marking event handler as 'passive' to make the page more responsive 【发布时间】:2017-01-02 08:01:21 【问题描述】:我正在使用锤子进行拖动,并且在加载其他内容时它变得不稳定,正如此警告消息所告诉我的那样。
“touchstart”输入事件的处理延迟了 X 毫秒,原因是 主线程忙。考虑将事件处理程序标记为“被动”以 使页面更具响应性。
所以我尝试像这样向听众添加“被动”
Hammer(element[0]).on("touchstart", function(ev)
// stuff
,
passive: true
);
但我仍然收到此警告。
【问题讨论】:
【参考方案1】:对于第一次收到此警告的用户,这是由于最近(2016 年夏季)在浏览器中实施的称为被动事件侦听器 的前沿功能。来自https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md:
被动事件侦听器是 DOM 规范中的一项新功能,它启用 开发人员通过消除 需要滚动以阻止触摸和滚轮事件侦听器。 开发人员可以使用 passive: true 注释触摸和滚轮侦听器 表示他们永远不会调用 preventDefault。这项特征 在 Chrome 51、Firefox 49 中发布并登陆 WebKit。 For full official explanation read more here.
另见:What are passive event listeners?
您可能需要等待 .js 库实现支持。
如果您通过 javascript 库间接处理事件,您可能会受制于该特定库对该功能的支持。截至 2019 年 12 月,似乎没有任何主要库已实现支持。一些例子:
jQuery.js - 持续问题:https://github.com/jquery/jquery/issues/2871 React.js - 持续问题:https://github.com/facebook/react/issues/6436 Hammer.js - 由于没有跟进而关闭:https://github.com/hammerjs/hammer.js/pull/987 完美滚动条 - 关闭: https://github.com/noraesae/perfect-scrollbar/issues/560 AngularJS - 由于无法修复而关闭:https://github.com/angular/angular.js/issues/15901【讨论】:
离子库怎么样? 我正在打电话给preventDefault()
- 是否可以取消此警告?
@maja no - ***.com/questions/44060131/…
Google Maps JavaScript API 版本 3 也会生成这些警告。正在issuetracker.google.com/issues/63211698 跟踪问题。 (有点讽刺,考虑到 Google Chrome 会警告 Google Maps JavaScript API 生成的违规行为。)
要抑制这个警告,你可以` addEventListener('touchstart', this.callPassedFuntion, passive: false )`【参考方案2】:
这会隐藏警告消息:
jQuery.event.special.touchstart =
setup: function( _, ns, handle )
this.addEventListener("touchstart", handle, passive: !ns.includes("noPreventDefault") );
;
【讨论】:
目标不是停止实际事件吗?在处理完问题之前,我不想隐藏消息。 我认为这是一个 jquery 库问题。我认为开发人员必须修复它。但如果你能得到它,请告诉我该怎么做。非常感谢。 当然是伊万!是的。嘿,现在我很好奇......我正在使用 d3 插件,我得到了 2300 次违规。也许您的代码会有所帮助!我会及时通知你的! @yardpenalty.com,不,停止活动不是目标!警告指出您已放置侦听器,但未指定它是否会阻止事件的默认行为。如果您有需要调用preventDefault()
的情况,则应指定passive: false
。如果不是,请指定passive: true
。如果您不指定任何一个,您只会收到警告。如果您指定passive: true
并调用preventDefault()
,则会导致错误并且不会阻止默认设置。在这里指定passive
并不是一个技巧。这是解决方案。这就是警告所要求的!
@tao 感谢您的评论。已经好几年了,但我一定会记住未来的解决方案!【参考方案3】:
以下库解决了该问题。 只需将此代码添加到您的项目中即可。
<script type="text/javascript" src="https://unpkg.com/default-passive-events"></script>
如果您需要更多信息,请访问此library。
【讨论】:
【参考方案4】:对于那些遇到遗留问题的人,找到引发错误的行并添加passive: true
- 例如:
this.element.addEventListener(t, e, !1)
变成
this.element.addEventListener(t, e, passive: true )
【讨论】:
【参考方案5】:对于带有 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') );
;
【讨论】:
【参考方案6】:在 Laravel 的 select2 下拉插件中也会遇到这种情况。按照 Alfred Wallace 的建议从
更改值this.element.addEventListener(t, e, !1)
到
this.element.addEventListener(t, e, passive: true )
解决了这个问题。为什么他投了反对票,我不知道,但这对我有用。
【讨论】:
谢谢兄弟,这很好用 - 用 JQuery 3.5.1 测试 你为什么只是复制/粘贴另一个答案??【参考方案7】:我认为除了基于触摸的事件之外,您还可以添加基于滚动的修复,以防止 google 页面得分将其标记为桌面与移动:
// 被动事件监听器(设置标志的两个细微差别)
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") );
;
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 );
;
【讨论】:
【参考方案8】:我找到了一个适用于jQuery 3.4.1 slim的解决方案
解压缩后,在第 1567 行的 addEventListener 函数中添加 passive: true
,如下所示:
t.addEventListener(p, a, passive: true))
没有任何问题,灯塔审计不会抱怨听众。
【讨论】:
永远不要更改库的源代码;你应该改写它。 如何在jquery中实现对事件监听器的覆盖? 对,绝对同意不改库……就说解决办法以上是关于考虑将事件处理程序标记为“被动”以使页面更具响应性的主要内容,如果未能解决你的问题,请参考以下文章
如何让我的 CSS @media 代码在移动设备上运行以使我的网站具有响应性?