许多库和框架默认添加了非被动事件监听器。你无法做太多事情。相反,建议使用高度灵活和可配置的 passive-events-support 包来调试和使事件监听器变为被动,而无需触及第三方源代码。
首先,在安装该包后,调试触摸和滚动事件监听器及其参数:
import { passiveSupport } from 'passive-events-support/src/utils'
passiveSupport({ debug: true })
这应该会在控制台记录所有事件监听器
[Passive Events Support] Non-passive Event Listener
element: div.some-element
event: 'touchstart'
handler:
fn: ƒ (e)
fnArgument: 'e'
fnContent: 'console.log(e)'
fnPrevented: false
arguments: false
注意 arguments
参数,如果它是 false
、undefined
或者没有 passive
参数的对象,这个事件会导致你的浏览器抛出一个警告并影响滚动的性能。
要修复它,只需使用该软件包和记录的信息将此事件侦听器转换为被动模式:
import { passiveSupport } from 'passive-events-support/src/utils'
passiveSupport({
debug: false,
// add this one
listeners: [
{
element: 'div.some-element',
event: 'touchstart'
}
]
})
请注意,调用 preventDefault()
的事件监听器不应被标记为"passive",但是为了修复警告,仍应将passive
参数的值设为false
。
默认情况下,该包会检查是否从处理程序本身阻止它,但是如果事件监听器是从处理程序内部调用的方法中阻止的,则该包会失去追踪。 若要强制分配 passive: false
,只需将 prevented: true
参数传递给 listeners
项:
passiveSupport({
//...
listeners: [
{
element: 'div.some-element',
event: 'touchstart',
prevented: true
}
]
})
对我来说,这个包修复了由Materialize和jQuery引起的所有警告。希望它也能对你有所帮助。
React不支持被动事件监听器。你需要做的是获取真实DOM的ref,并使用{passive:true}作为选项附加事件监听器。在销毁组件之前(实际上在componentWillUnmount中)别忘了分离事件监听器。
您可以查看 GitHub 分支(问题#20)以获取详细信息,了解如何修复问题,以下是其操作:
修改 sidenav.js 的第 132、134 和 136 行。
从以下内容进行更改:
this.dragTarget.addEventListener('touchmove', this._handleDragTargetDragBound);
this._overlay.addEventListener('touchmove', this._handleCloseDragBound);
this.el.addEventListener('touchmove', this._handleCloseDragBound);
到:
this.dragTarget.addEventListener('touchmove', this._handleDragTargetDragBound, { passive: true});
this._overlay.addEventListener('touchmove', this._handleCloseDragBound, { passive: true});
this.el.addEventListener('touchmove', this._handleCloseDragBound, { passive: true});