網站搜尋

javascript - 我如何使用帶有事件參數和參數的函數來添加和移除事件監聽器?


例如,我有以下函數在 mouseup 事件發生時執行。

const listener = (element: HTMLElement, e: MouseEvent): void => {
    if (e.target instanceof Element && element && !element.contains(e.target)) {
        element.style.backgroundColor = 'red';
    }
}

然後我正在嘗試找出如何向 listener 添加額外參數 element,以及在不再需要時將其移除。

function addEventListener (element: HTMLElement) => {
    window.document.addEventListener('mouseup', (e) => listener(element, e));
}

function removeEventListener (element: HTMLElement) => {
    window.document.removeEventListener('mouseup', ?? );
}

我該如何解決這個問題?

我嘗試像下面這樣使用 bind,但 MouseEvent 無法在 addEventListener 之前綁定。

let callback;

function addEventListener (element: HTMLElement) => {
    // how can I bind `MouseEvent`?
    callback = listener.bind(this, element, ??);
    window.document.addEventListener('mouseup', callback);
}

function removeEventListener (element: HTMLElement) => {
    window.document.removeEventListener('mouseup', callback);
}

我應該像下面這樣使用閉包嗎?

function createListener(element: HTMLElement) {
    return (e: MouseEvent) => {
        listener(element, e);
    }
}

let callback;

function addEventListener (element: HTMLElement) {
    callback = createListener(account);
    window.document.addEventListener('mouseup', callback);
}

function removeEventListener (element: HTMLElement) => {
    window.document.removeEventListener('mouseup', callback);
}

答案#1

就像你平常移除事件監聽器的方式一樣,但存儲一個將 HTMLElement 對應到函數的 Map(字典):

const callbacks = new Map<HTMLElement, (e: MouseEvent) => void>();

function addEventListener (element: HTMLElement) => {
    const callback = (e) => listener(element, e);
    callbacks.set(element, callback);
    window.document.addEventListener('mouseup', callback);
}

function removeEventListener (element: HTMLElement) => {
    const callback = callbacks.get(element);
    if(callback)
    {
        window.document.removeEventListener('mouseup', callback);
        delete callback;
    }
}