向阻止滚动的“touchstart”事件添加了非被动事件侦听器
Posted
技术标签:
【中文标题】向阻止滚动的“touchstart”事件添加了非被动事件侦听器【英文标题】:Added non-passive event listener to a scroll-blocking 'touchstart' event 【发布时间】: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 中放了一个错误,但我严重怀疑这一点,因为这样每个人都会得到它。
有什么想法吗?我尝试了所有可以调试的东西,但我仍然不知道是什么原因造成的?!?
更新
我用<button data-toggle="tooltip" title="text"></button>
替换了所有<button><md-tooltip>text</md-tooltip></button>
,这消除了所有违规行为的99%。
【问题讨论】:
您的旧版本仍然可以使用吗?因为这很可能是添加了这个的浏览器更新...... 嗯,好问题......我今天所做的只是将Speed Dial 2 - New tab 2.2.1
添加为 chrome 浏览器扩展(让您控制空白页面快捷方式) - 但我卸载了它以防万一造成问题。
尝试在 firefox 上运行页面,这里 jquery 在缩小代码的深处进入无限循环。
好的。尝试用未压缩的版本替换您的 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 或替代实现的更多信息:***.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 - 发现了一些东西...<md-tooltip>testing</md-tooltip>
是导致这种违规的一件事,因为我使用了很多这些我得到了很多错误。我仍在检查原因,我确定有移动的东西导致它。
还发现<input type="date" ng-model="vm.date.checkin">
导致了很多这样的问题:[Violation] Added non-passive event listener to a scroll-blocking 'wheel' event.
但仅在您使用 ng-model 时才发生。
仅凭这些 sn-ps,我无法为您提供更多帮助。但基本上,所有导致滚动的事件(滚轮、触摸、滚动)都会抛出这个,因为 jQuery 事件处理可能会阻止它们。因此,请尝试在您的输入中删除该轮事件,这非常奇怪......并查看其他事件。您还可以通过使用事件委托来减少处理程序的数量。
现在我替换了所有 <button><md-tooltip>text</md-tooltip></button>
宽度 <button data-toggle="tooltip" title="text"></button>
这删除了 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 );
;
【讨论】:
以上是关于向阻止滚动的“touchstart”事件添加了非被动事件侦听器的主要内容,如果未能解决你的问题,请参考以下文章
iPad - touchStart() 事件被 div 文本阻止
警告:添加非被动事件侦听器到滚动阻塞'touchstart'事件(Added non-passive event listener to a scroll-blocking '