在addEventListener時為具名函式傳遞引數,同時還能移除它
泡麵最近在做一個基於Vue的元件,之間要用到通過addEventListener繫結滑鼠事件,但遇到一個問題。就是 需要在繫結匿名函式時候傳遞引數,當然,這個很容易,但是當你要動態移除掉這個匿名函式時就很麻煩了。那有沒有一種我即不使用匿名函式也能傳遞引數,這樣我就能很方便的在後期使用removeEventListener移除掉它。當然有!
問題
有如下程式碼:
// 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上的引數