[JavaScript] 對同一個 DOM 元素同時加入數個 Event Listener

本文介紹對同一個 DOM 元素一次加入相同處理函式的做法。

假設我們在網頁中有一個名為 txtInput 的 DOM 元素, 針對這個元素, 我們若要加入相同的事件處理函式, 應該怎麼做呢?

最簡單直覺的做法, 當然就是先寫好處理方法 (例如 handler()), 然後一個一個綁上去。這我就不舉例子了。

如果你使用 jQuery 的話, 它提供一個簡單的寫法可以這樣做:

// 程式一

$('#txtInput').on('keyup keypress blur change', () => {
    console.log($('#txtInput').val());
});

這樣就可以一次將 keyup keypress blur change 這些 events 通通綁上去。

但如果你不使用 jQuery 的話, 應該如何僅使用 JavaScript 做到這件事?

// 程式二

HTMLElement.prototype.addMultiHandlers = 
    HTMLElement.prototype.addMultiHandlers || function(events, handler, options, callback) {
        events.forEach(e =>
            this.addEventListener(e, handler, options, callback))
    };

用法如下:

// 程式三

document.getElementById('txtInput').
    addMultiHandlers(['keyup', 'keypress', 'blur', 'change'], null, () => 
    	{ console.log(this.value); });

我在程式二中對 HTMLElement 物件覆寫了一個名為 addMultiHandlers 的方法, 然後所有的 HTMLElement 物件就自動多了這個方法可用 (參考程式三)。當然, 這只對單獨一個 node 有效, 如果你 query 到一整個 nodelist, 那麼你還是必須個別去呼叫它。

在程式三中那個 options 參數可以省略, 變成如下的樣子:

// 程式四

HTMLElement.prototype.addMultiHandlers = 
    HTMLElement.prototype.addMultiHandlers || function(events, handler, callback) {
        events.forEach(e =>
            this.addEventListener(e, handler, callback))
    };

這樣的話, 程式中的那個 null 參數也就不必加了。

不過, 由於 HTMLElement 差不多等於所有的 DOM 元素了; 為防呆起見, 我們最好再加入一道防呆指令, 以避免不必要的呆。加入 nodeName 篩檢之後, 它只對 INPUT 元素有效, 如程式五:

// 程式五

HTMLElement.prototype.addMultiHandlers = 
    HTMLElement.prototype.addMultiHandlers || function(events, handler, callback) {
        if (this.nodeName == 'INPUT')
            events.forEach(e =>
                this.addEventListener(e, handler, callback))
    };

可以使用 jQuery 的人, 請採用程式一的寫法, 不想使用 jQuery 的人, 請採用程式五+程式三。


Dev 2Share @ 點部落