Javascript 使用 addEventListener 获取附加到节点的事件侦听器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9046741/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 08:29:16  来源:igfitidea点击:

Get event listeners attached to node using addEventListener

javascriptdom-events

提问by Tyilo

I have already looked at these questions:

我已经看过这些问题:

however none of them answers how to get a list of event listeners attached to a node using addEventListener, without modifying the addEventListenerprototype before the event listeners are created.

然而,他们都没有回答如何使用 获取附加到节点的事件侦听器列表addEventListener,而无需addEventListener在创建事件侦听器之前修改原型。

VisualEventdoesn't display all event listener (iphone specific ones) and I want to do this (somewhat) programmatically.

VisualEvent不显示所有事件侦听器(特定于 iPhone 的事件侦听器),我想以编程方式(在某种程度上)执行此操作。

回答by NVI

Chrome DevTools, Safari Inspector and Firebug support getEventListeners(node).

Chrome DevTools、Safari Inspector 和 Firebug 支持getEventListeners(node)

getEventListeners(document)

getEventListeners(文档)

回答by Raynos

You can't.

你不能。

The only way to get a list of all event listeners attached to a node is to intercept the listener attachment call.

获取附加到节点的所有事件侦听器列表的唯一方法是拦截侦听器附件调用。

DOM4 addEventListener

DOM4 添加事件监听器

Says

Append an event listener to the associated list of event listeners with type set to type, listener set to listener, and capture set to capture, unless there already is an event listener in that list with the same type, listener, and capture.

将事件侦听器附加到关联的事件侦听器列表,其中类型设置为 type、侦听器设置为侦听器、捕获设置为捕获,除非该列表中已存在具有相同类型、侦听器和捕获的事件侦听器。

Meaning that an event listener is added to the "list of event listeners". That's all. There is no notion of what this list should be nor how you should access it.

这意味着将事件侦听器添加到“事件侦听器列表”中。就这样。没有关于该列表应该是什么以及您应该如何访问它的概念。

回答by yorg

Since there is no native way to do this ,Here is less intrusive solution i found (dont add any 'old' prototype methods):

由于没有本地方法可以执行此操作,因此我找到了侵入性较小的解决方案(不要添加任何“旧”原型方法):

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();

回答by Adam Katz

I can't find a way to do this with code, but in stock Firefox 64, events are listed next to each HTML entity in the Developer Tools Inspector as noted on MDN's Examine Event Listenerspage and as demonstrated in this image:

我找不到使用代码执行此操作的方法,但在 Firefox 64 中,开发者工具检查器中每个 HTML 实体旁边都列出了事件,如 MDN 的检查事件侦听器页面上所述,如下图所示:

screen shot of FF Inspector

FF 检查员的屏幕截图

回答by Rantiev

You can obtain all jQuery events using $._data($('[selector]')[0],'events'); change [selector] to what you need.

您可以使用 $._data($('[selector]')[0],'events'); 获取所有 jQuery 事件。将 [选择器] 更改为您需要的。

There is a plugin that gather all events attached by jQuery called eventsReport.

有一个插件可以收集 jQuery 附加的所有事件,称为 eventsReport。

Also i write my own plugin that do this with better formatting.

我也写了我自己的插件,用更好的格式来做到这一点。

But anyway it seems we can't gather events added by addEventListener method. May be we can wrap addEventListener call to store events added after our wrap call.

但无论如何,我们似乎无法收集由 addEventListener 方法添加的事件。也许我们可以包装 addEventListener 调用来存储在我们的包装调用之后添加的事件。

It seems the best way to see events added to an element with dev tools.

这似乎是使用开发工具查看添加到元素的事件的最佳方式。

But you will not see delegated events there. So there we need jQuery eventsReport.

但是您不会在那里看到委派的事件。所以我们需要jQuery eventsReport。

UPDATE: NOW We CAN see events added by addEventListener method SEE RIGHT ANSWER TO THIS QUESTION.

更新:现在我们可以看到 addEventListener 方法添加的事件,请参阅此问题的正确答案。