泡面最近在做一个基于Vue的组件,之间要用到通过addEventListener绑定鼠标事件,但遇到一个比较恶心的问题。就是
需要在绑定匿名函数时候传递参数,当然,这个很容易,但是当你要动态移除掉这个匿名函数时就很麻烦了。
起因
有如下代码:
// bind event
element.addEventListener('click', _bindEventHandler)
// unbind event
element.removeEventListener('click', _bindEventHandler)
我如果在使用具名函数传递参数呢? 当然可以这样:
element.addEventListener('click', function() {
_bindEventHandler(param1, param2)
})
但,这样有个问题就是,我如果再想同步的移除该绑定事件,那就无法移除了,因为没有函数名称,我们在移除的时候无法直接进行通过removeEventListener
进行移除。那有没有什么办法可以让我即能顺利移除它,还能不使用匿名函数传参数呢?
分析与解决
So,泡面这里想到了一个曲线救国的办法,那就是将参数直接绑定在element
上,因为我们在使用具名函数时,addEventListener
会静默将事件的event
传递给函数。因此当我们再想找回这些参数,我们就可以直接通过event.target
来获取。
// 设置参数
element._params = { param1, param2 }
// 绑定事件
element.addEventListener('click', _bindEventHandler)
// 在函数中获取参数
function _bindEventHandler(event) {
const params = event.target._params
// ...do sth after
}
OK,这样我们就实现了参数的传递, 同时也可以很方便的移除绑定事件了! 是不是很开心?
one more thing
有个问题,当我绑定的element
事件遇到事件委托
时,就需要额外处理一下。例如我们在绑定一个有层级结构的按钮或者DOM时,
当点击内部的DOM,我们会无法获取到在实际绑定事件的DOM上设置的参数。
这里我们就需要通过遍历事件绑定的对象来获取参数了。
我们可以通过
event.path(event.composedPath())
来获取Dom上的参数