addEventListener с прослушивателем-оболочкой

#javascript

#javascript

Вопрос:

Я пытаюсь запускать пользовательский код всякий раз, когда срабатывает событие щелчка. Это то, что у меня есть до сих пор:

 const origHandler = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function (eventName, eventHandler, options) {
    let handler = eventHandler;
    const target = this;
    origHandler.call(this, eventName, function (e) {
        // Do something with e
        doSomething(e);
        // Run original function
        handler.call(target, e);
    }, options);
};
 

Я также использую этот выпадающий плагин с несколькими вариантами выбора. В приведенном выше коде нажатие на выпадающий элемент ничего не делает, пока я не нажму на него пару раз.
Это прекрасно работает, если я просто сделаю следующее:

     origHandler.call(this, eventName, handler, options);
 

Однако вышесказанное не позволяет мне запускать пользовательский код всякий раз, когда вызывается обработчик. Есть ли что-нибудь, что я могу сделать, чтобы создать оболочку, которая также работает с этими типами плагинов?

Эта проблема не относится конкретно к этому плагину, так как я видел несколько других плагинов в приложении, которые также ломались в результате этого кода.

Ответ №1:

Неполный алгоритм

Опубликованный код вызывает (исходный) addEventListener с анонимным аргументом функции. Это означает, что любой removeEventListener вызывающий код in, который указывает handler в качестве аргумента своей функции, завершится неудачей — он никогда не соответствует анонимной функции.

Чтобы успешно добавить перехват, addEventListener потребуется реализовать дополнительный перехват removeEventListener и дополнительную логику для обеспечения правильного удаления добавленных слушателей.

Это не означает, что конкретные проблемы, с которыми сталкиваются, специально вызваны только исправлением addEventListener , но это гарантированно приведет к сбою кода.

В общем, исправления prototype свойств объекта глобальных функций, вероятно, лучше избегать, если это вообще возможно.

Альтернативное использование Capture

Добавление прослушивателя событий щелчка документа, который использует захват событий, перед включением любых библиотечных сценариев должно позволить проверять каждое событие щелчка перед обработкой чем-либо еще:

 document.addEventListener("click", function(e){
       // do something with event
         console.log("click event type: %s on %s", e.type, e.target.tagName);
    }, {capture:true}); 
 body {background-color: white}
html {background-color: grey} 
 Click me!