Отримайте слухачів подій, приєднаних до вузла за допомогою addEventListener


106

Я вже розглянув ці питання:

однак жоден з них не відповідає, як отримати список слухачів подій, приєднаних до вузла за допомогою addEventListener, не змінюючи addEventListenerпрототип до створення слухачів подій.

VisualEvent не відображає всіх слухачів подій (конкретні для iphone), і я хочу це зробити (дещо) програмно.



"дещо програмно", і те, що прийнята відповідь на це питання є функцією devtools, робить це дублікатом перерахованого питання. Для тих, хто шукає рішення JS, відповідь «немає такого»
Миколай

Відповіді:


135

Підтримка Chrome DevTools, Safari Inspector та Firebug getEventListeners (вузол) .

getEventListeners (документ)


6
Хочу зазначити, що метод getEventListeners не підтримує Firefox 35 версії.
MURATSPLAT

Це може не працювати на Firefox, але потім знову розробляються розробники на декількох браузерах / Це впевнено, ДОПОМОГАЄ, якщо потрібно змінити існуючий сайт ... МНОГО!
JasonXA

1
Не це Firefox 69.
Віталій Зданевич

65

Ви не можете.

Єдиний спосіб отримати список усіх слухачів подій, приєднаних до вузла, - перехопити виклик прихильності слухача.

DOM4 addEventListener

Каже

Додайте слухача подій до пов’язаного списку слухачів подій з типом, встановленим на тип, слухачем, призначеним для слухача, і набором для захоплення, якщо тільки в цьому списку вже немає слухача подій з тим самим типом, слухачем та захопленням.

Це означає, що слухач подій додається до "списку слухачів подій". Це все. Не існує поняття, яким повинен бути цей список, і як ви маєте доступ до нього.


12
Будь-який шанс надати певне обґрунтування чи аргументацію, чому він повинен працювати саме так? Очевидно, що браузер знає, що таке всі слухачі.
Дарт Егрегійний

3
@ user973810: Як ти хочеш, щоб він це виправдав? API DOM не забезпечує цього способу, і не існує нестандартних способів це зробити в поточних браузерах. А чому це так, я насправді не знаю. Здається, це хочеться зробити розумним.
Tim Down

Я бачив декілька потоків навколо додавання API для DOM для цього.
Райнос

@TimDown редагування допомагає. Бачачи, що немає специфікації для чогось типу "getEventListeners", виправдовує, чому такого немає.
Дарт Егрегійний

24

Оскільки для цього немає рідного способу, тут я знайшов менш нав'язливе рішення (не додайте жодних "старих" методів-прототипів):

var ListenerTracker=new function(){
    var is_active=false;
    // listener tracking datas
    var _elements_  =[];
    var _listeners_ =[];
    this.init=function(){
        if(!is_active){//avoid duplicate call
            intercep_events_listeners();
        }
        is_active=true;
    };
    // register individual element an returns its corresponding listeners
    var register_element=function(element){
        if(_elements_.indexOf(element)==-1){
            // NB : split by useCapture to make listener easier to find when removing
            var elt_listeners=[{/*useCapture=false*/},{/*useCapture=true*/}];
            _elements_.push(element);
            _listeners_.push(elt_listeners);
        }
        return _listeners_[_elements_.indexOf(element)];
    };
    var intercep_events_listeners = function(){
        // backup overrided methods
        var _super_={
            "addEventListener"      : HTMLElement.prototype.addEventListener,
            "removeEventListener"   : HTMLElement.prototype.removeEventListener
        };

        Element.prototype["addEventListener"]=function(type, listener, useCapture){
            var listeners=register_element(this);
            // add event before to avoid registering if an error is thrown
            _super_["addEventListener"].apply(this,arguments);
            // adapt to 'elt_listeners' index
            useCapture=useCapture?1:0;

            if(!listeners[useCapture][type])listeners[useCapture][type]=[];
            listeners[useCapture][type].push(listener);
        };
        Element.prototype["removeEventListener"]=function(type, listener, useCapture){
            var listeners=register_element(this);
            // add event before to avoid registering if an error is thrown
            _super_["removeEventListener"].apply(this,arguments);
            // adapt to 'elt_listeners' index
            useCapture=useCapture?1:0;
            if(!listeners[useCapture][type])return;
            var lid = listeners[useCapture][type].indexOf(listener);
            if(lid>-1)listeners[useCapture][type].splice(lid,1);
        };
        Element.prototype["getEventListeners"]=function(type){
            var listeners=register_element(this);
            // convert to listener datas list
            var result=[];
            for(var useCapture=0,list;list=listeners[useCapture];useCapture++){
                if(typeof(type)=="string"){// filtered by type
                    if(list[type]){
                        for(var id in list[type]){
                            result.push({"type":type,"listener":list[type][id],"useCapture":!!useCapture});
                        }
                    }
                }else{// all
                    for(var _type in list){
                        for(var id in list[_type]){
                            result.push({"type":_type,"listener":list[_type][id],"useCapture":!!useCapture});
                        }
                    }
                }
            }
            return result;
        };
    };
}();
ListenerTracker.init();

Ви також повинні змусити його перехоплювати слухачів віконних подій. Крім цього, це чудово працює!

2

Ви можете отримати всі події jQuery, використовуючи дані $ ._ ($ ('[селектор]') [0], 'події'); змініть [селектор] на те, що вам потрібно.

Існує плагін, який збирає всі події, додані jQuery під назвою eventsReport.

Також я пишу свій плагін, який роблять це з кращим форматуванням.

Але все одно здається, що ми не можемо зібрати події, додані методом addEventListener. Можливо, ми можемо завершити виклик addEventListener, щоб зберігати події, додані після нашого виклику.

Здається, найкращий спосіб бачити події, додані до елемента за допомогою інструментів розробки.

Але делегованих подій там ви не побачите. Тож нам потрібні jQuery eventsReport.

ОНОВЛЕННЯ: ЗАРАЗ Ми можемо бачити події, додані методом addEventListener. ВИДІТЬ ПРАВИЙ ВІДПОВІДЬ НА ЦЕ ЗАПИТАННЯ.


Це приватний і застарілий інтерфейс, і він може скоро піти, тому не покладайтеся на це.
мгдол

1
Так, але час, коли я відповів, у інструментах Dev не було такої здатності. Отже, нічого було вибрати.
Рантьєв

@Rantiev це застаріле, ви можете видалити цю відповідь?
Хуліо Марін

2

Я не можу знайти спосіб зробити це за допомогою коду, але на складі Firefox 64 події перераховані поруч із кожною сутністю HTML у Інспекторі інструментів розробника, як зазначено на сторінці Опитування подій MDN та як показано на цьому зображенні:

знімок екрана FF Inspector

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.