รับฟังเหตุการณ์ที่แนบมากับโหนดโดยใช้ addEventListener


107

ฉันได้ดูคำถามเหล่านี้แล้ว:

อย่างไรก็ตามไม่มีใครตอบได้ว่าจะรับรายชื่อผู้ฟังเหตุการณ์ที่เชื่อมต่อกับโหนดได้addEventListenerอย่างไรโดยไม่ต้องแก้ไขaddEventListenerต้นแบบก่อนที่จะสร้างตัวฟังเหตุการณ์

VisualEventไม่แสดงตัวฟังเหตุการณ์ทั้งหมด (เฉพาะสำหรับ iPhone) และฉันต้องการทำสิ่งนี้ (ค่อนข้าง) โดยใช้โปรแกรม



"ค่อนข้างเป็นโปรแกรม" และข้อเท็จจริงที่ว่าคำตอบที่ได้รับการยอมรับสำหรับคำถามนี้เป็นคุณลักษณะของเครื่องมือพัฒนาทำให้สิ่งนี้ซ้ำกับคำถามที่ระบุไว้ สำหรับผู้ที่กำลังมองหาโซลูชัน JS คำตอบคือ "ไม่มีเลย"
Nickolay

คำตอบ:


137

โครเมี่ยม DevTools, Safari และสารวัตร Firebug สนับสนุนgetEventListeners (โหนด)

getEventListeners (เอกสาร)


6
ฉันต้องการทราบว่าเมธอด getEventListeners ไม่รองรับเวอร์ชัน Firefox 35
MURATSPLAT

มันอาจไม่ทำงานบน Firefox แต่จากนั้นก็พัฒนาอีกครั้งบนเบราว์เซอร์หลายตัว / สิ่งนี้ช่วยได้แน่นอนหากต้องการแก้ไขไซต์ที่มีอยู่ ... เยอะมาก!
JasonXA

1
ไม่ใช่ Firefox 69.
Vitaly Zdanevich

65

คุณทำไม่ได้

วิธีเดียวที่จะรับรายชื่อผู้ฟังเหตุการณ์ทั้งหมดที่เชื่อมต่อกับโหนดคือการดักฟังการเรียกสิ่งที่แนบมาของผู้ฟัง

DOM4 addEventListener

กล่าวว่า

ผนวกตัวฟังเหตุการณ์เข้ากับรายชื่อผู้ฟังเหตุการณ์ที่เกี่ยวข้องโดยตั้งค่าประเภทเป็นประเภทผู้ฟังตั้งค่าเป็นผู้ฟังและตั้งค่าการจับภาพเพื่อจับภาพเว้นแต่จะมีผู้ฟังเหตุการณ์อยู่ในรายการที่เป็นประเภทเดียวกันผู้ฟังและการบันทึก

หมายความว่ามีการเพิ่มผู้ฟังเหตุการณ์ใน "รายชื่อผู้ฟังเหตุการณ์" นั่นคือทั้งหมด ไม่มีความคิดว่ารายการนี้ควรเป็นอย่างไรและคุณควรเข้าถึงได้อย่างไร


12
มีโอกาสที่จะให้เหตุผลหรือเหตุผลว่าทำไมจึงต้องทำงานในลักษณะนี้? เห็นได้ชัดว่าเบราว์เซอร์รู้ว่าผู้ฟังทั้งหมดเป็นอย่างไร
Darth Egregious

3
@ user973810: คุณต้องการให้เขาแก้ตัวเรื่องนี้อย่างไร? DOM API ไม่มีวิธีดำเนินการและไม่มีวิธีที่ไม่ได้มาตรฐานในการทำในเบราว์เซอร์ปัจจุบัน เหตุใดจึงเป็นเช่นนี้ฉันไม่ทราบจริงๆ ดูเหมือนเป็นสิ่งที่สมเหตุสมผลที่อยากจะทำ
Tim Down

ฉันเคยเห็นเธรดสองสามรายการเกี่ยวกับการเพิ่ม API ไปยัง DOM สำหรับสิ่งนี้
Raynos

@TimDown การแก้ไขช่วย เมื่อเห็นว่าไม่มีข้อกำหนดสำหรับบางสิ่งบางอย่างเช่น "getEventListeners" แสดงเหตุผลว่าทำไมไม่มีสิ่งนั้น
Darth Egregious

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 ทั้งหมดโดยใช้ $ ._ data ($ ('[selector]') [0], 'events'); เปลี่ยน [ตัวเลือก] ตามที่คุณต้องการ

มีปลั๊กอินที่รวบรวมเหตุการณ์ทั้งหมดที่แนบมาโดย jQuery เรียกว่า eventsReport

นอกจากนี้ฉันยังเขียนปลั๊กอินของตัวเองซึ่งทำได้ด้วยการจัดรูปแบบที่ดีกว่า

แต่อย่างไรก็ตามดูเหมือนว่าเราไม่สามารถรวบรวมเหตุการณ์ที่เพิ่มโดยวิธี addEventListener ได้ อาจเป็นไปได้ว่าเราสามารถตัดการเรียก addEventListener เพื่อจัดเก็บกิจกรรมที่เพิ่มหลังจากการโทรสรุปของเรา

ดูเหมือนเป็นวิธีที่ดีที่สุดในการดูเหตุการณ์ที่เพิ่มลงในองค์ประกอบด้วยเครื่องมือ dev

แต่คุณจะไม่เห็นกิจกรรมที่ได้รับมอบหมายที่นั่น ดังนั้นเราจึงต้องการ jQuery eventsReport

อัปเดต: ตอนนี้เราสามารถเห็นเหตุการณ์ที่เพิ่มโดยเมธอด addEventListener ดูคำตอบที่ถูกต้องสำหรับคำถามนี้


นี่เป็นอินเทอร์เฟซส่วนตัวและเลิกใช้งานแล้วและอาจหายไปในไม่ช้าดังนั้นอย่าพึ่งใช้สิ่งนั้น
mgol

1
ใช่ แต่เวลาที่ฉันตอบไม่มีความสามารถดังกล่าวในเครื่องมือ Dev ดังนั้นจึงไม่มีอะไรให้เลือก
Rantiev

เลิกใช้แล้ว @Rantiev คุณสามารถลบคำตอบนั้นได้หรือไม่?
Julio Marins

2

ฉันไม่สามารถหาวิธีดำเนินการกับโค้ดได้ แต่ในสต็อก Firefox 64 เหตุการณ์จะแสดงรายการถัดจากเอนทิตี HTML แต่ละรายการในตัวตรวจสอบเครื่องมือสำหรับนักพัฒนาตามที่ระบุไว้ในหน้าตรวจสอบผู้ฟังเหตุการณ์ของ MDN และดังที่แสดงในภาพนี้:

ภาพหน้าจอของ FF Inspector

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.