「这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战」。
使用高德地图时,鼠标只要一移上去,就有无数个报错,滑动一下,成百上千个报错,非常影响心情.
Unable to preventDefault inside passive event listener invocation. 从控制台报错跟踪到代码,发现是鼠标移动这个事件的报错。 passive
这个报错是高德地图本身的报错,我们无法修改代码,可以考虑从动态原型入手。
passive的英文意思是被动的,就是被动事件。报错翻译过来的意思是不能在被动事件监听器调用中调用preventDefault函数去阻止浏览器默认行为。 这里先来了解一个概念 ,EventTarget,事件目标, elment也就是dom元素,都是 EventTarget对象的实例。
EventTarget.addEventListener(key, handler, options)参数说明如下:
- 参数options规定了事件的特性
- 比如capture 规定是在事件的捕获阶段执行事件处理器还是在事件的冒泡阶段执行。
- 比如passive,如果设置为true,表示handler执行时不应执行preventDefault,如果执行了,控制台就会报错。 所谓被动事件,就是你不能直接改变浏览器的默认行为,你只能接受它,因此,定义了passive为true而又调用了preventDefault,就会出现报错了 至于为什么会有passive,读者可自行查阅一下【chrome的线程化渲染框架的两个线程】
因此 要想解决这个问题 有如下两个方案: 1.绑定事件时 不要在被动事件里调用preventDefault(但是这个调用都是写在第三方调用 所以 这个方案被pass了) 2.既然无法阻止代码对于preventDefault的调用,可以考虑将passive设置为false
基于原型的原理 我们知道 如果我们改变了EventTarget的原型 那么EventTarget对象的实例也会受到影响 因此我们只需要在addEventListener时,强制使passive为false 代码如下
const oldAddEventListener = EventTarget.prototype.addEventListener
EventTarget.prototype.addEventListener = function(key, funcs, options = {}) {
oldAddEventListener.call(this,key, funcs, { passive: false })
}
如果只想指定的事件或指定的页面强制使passive为false 只需要在addEventListener的重写里增加判断逻辑。
通常来说,直接改变浏览器对象的原型是不提倡的。 ,本文仅提供一个解决思路,并不是最优解,如果读者有其他更好的办法,可以在下方留言,或者将你的智慧分享给大家,写出来并发布它,感谢阅读,如有异议,欢迎评论点赞。