addEventListener를 사용하여 노드에 연결된 이벤트 리스너 가져 오기


106

나는 이미 다음 질문을 살펴 보았습니다.

그러나 그들 중 어느 것도 이벤트 리스너가 생성되기 전에 프로토 타입 addEventListener을 수정하지 않고를 사용하여 노드에 연결된 이벤트 리스너 목록을 얻는 방법에 대한 대답은 없습니다 addEventListener.

VisualEvent 는 모든 이벤트 리스너 (iphone 특정 항목)를 표시하지 않으며 프로그래밍 방식으로이 작업을 수행하고 싶습니다.



"다소 프로그래밍"하고 있다는 사실 허용 대답 이 질문에 대한이 DevTools로 기능이이 나열된 질문의 중복 있습니다. JS 솔루션을 찾고 사람들을 위해, 대답은 "일이없는"입니다
Nickolay

답변:


135

Chrome DevTools, Safari Inspector 및 Firebug는 getEventListeners (node)를 지원 합니다 .

getEventListeners (문서)


6
getEventListeners 메서드는 Firefox 35 버전을 지원하지 않습니다.
MURATSPLAT 2014

Firefox에서는 작동하지 않을 수 있지만 다시 개발자는 여러 브라우저에서 개발합니다 / 기존 사이트를 수정해야하는 경우 도움이됩니다 ... 많이!
JasonXA

1
아니 그것은 파이어 폭스 69
비탈리 Zdanevich

65

당신은 할 수 없습니다.

노드에 연결된 모든 이벤트 리스너의 목록을 가져 오는 유일한 방법은 리스너 연결 호출을 가로채는 것입니다.

DOM4 addEventListener

말한다

유형, 리스너 및 캡처가 동일한 목록에 이미 이벤트 리스너가없는 경우, 유형이 유형으로, 리스너가 리스너로, 캡처가 캡처로 설정된 이벤트 리스너의 연관된 목록에 이벤트 리스너를 추가하십시오.

이벤트 리스너가 "이벤트 리스너 목록"에 추가됨을 의미합니다. 그게 다야. 이 목록이 무엇이어야하는지, 어떻게 액세스해야하는지에 대한 개념이 없습니다.


12
왜 이런 식으로 작동해야하는지에 대한 정당화 나 추론을 제공 할 가능성이 있습니까? 분명히 브라우저는 모든 리스너가 무엇인지 알고 있습니다.
Darth Egregious

3
@ user973810 : 그가 이것을 어떻게 정당화하기를 원합니까? DOM API는이를 수행 할 방법을 제공하지 않으며 현재 브라우저에서이를 수행하는 비표준 방법도 없습니다. 이것이 왜 그런지에 대해서는 잘 모르겠습니다. 하고 싶은 것이 합리적인 것 같습니다.
Tim Down

이를 위해 DOM에 API를 추가하는 것에 대해 몇 가지 스레드가 거짓말을하는 것을 보았습니다.
Raynos

@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

$ ._ data ($ ( '[selector]') [0], 'events');를 사용하여 모든 jQuery 이벤트를 얻을 수 있습니다. [선택기]를 필요한 것으로 변경하십시오.

eventsReport라는 jQuery에 의해 첨부 된 모든 이벤트를 수집하는 플러그인이 있습니다.

또한 더 나은 형식으로이 작업을 수행하는 자체 플러그인을 작성합니다.

하지만 어쨌든 addEventListener 메소드로 추가 된 이벤트를 수집 할 수없는 것 같습니다. 랩 호출 후 추가 된 이벤트를 저장하기 위해 addEventListener 호출을 랩핑 할 수 있습니다.

개발 도구를 사용하여 요소에 추가 된 이벤트를 보는 가장 좋은 방법 인 것 같습니다.

그러나 거기에서 위임 된 이벤트를 볼 수 없습니다. 그래서 우리는 jQuery eventsReport가 필요합니다.

업데이트 : 이제 addEventListener 메서드에 의해 추가 된 이벤트를 볼 수 있습니다.이 질문에 대한 올바른 답변을 참조하십시오.


이것은 비공개이며 사용되지 않는 인터페이스이며 곧 사라질 수 있으므로 의존하지 마십시오.
mgol 2014

1
네,하지만 제가 대답했을 때 개발자 도구에는 그런 능력이 없었습니다. 그래서 선택할 것이 없었습니다.
Rantiev 2014-06-12

@Rantiev가 더 이상 사용되지 않습니다. 그 대답을 제거 할 수 있습니까?
Julio Marins 2015

2

코드로이 작업을 수행하는 방법을 찾을 수 없지만 Firefox 64 재고에서는 MDN의 Examine Event Listeners 페이지 에 나와 있고이 이미지에 표시된대로 개발자 도구 검사기의 각 HTML 엔터티 옆에 이벤트가 나열됩니다 .

FF Inspector의 스크린 샷

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.