jQuery ค้นหาตัวจัดการเหตุการณ์ที่ลงทะเบียนกับวัตถุ


555

ฉันต้องการค้นหาตัวจัดการเหตุการณ์ที่ลงทะเบียนกับวัตถุ

ตัวอย่างเช่น:

$("#el").click(function() {...});
$("#el").mouseover(function() {...});

$("#el")ได้คลิกและลงทะเบียนmouseoverแล้ว

มีฟังก์ชั่นเพื่อค้นหาสิ่งนั้นและอาจย้ำไปที่ตัวจัดการเหตุการณ์หรือไม่?

ถ้ามันเป็นไปไม่ได้บนวัตถุ jQuery ด้วยวิธีการที่เหมาะสมมันเป็นไปได้ในวัตถุ DOM ธรรมดาหรือไม่?


5
น่าเสียดายที่ตอนนี้: bugs.jquery.com/ticket/10589
Skylar Saveland

2
สนับสนุนทั้ง jQuery ก่อนและโพสต์ 1.8:var events = (jQuery._data || jQuery.data)(elem, 'events');
oriadam

2
โปรดทราบว่าคุณสามารถใช้เครื่องมือ FF และ Chrome (F12) เพื่อดูผู้ฟังเหตุการณ์เหล่านี้ ดูDevelopers.google.com/web/tools/chrome-devtools/debug/ …และdeveloper.mozilla.org/en-US/docs/Tools/Page_Inspector/How_to/
......

คำตอบ:


691

ตั้งแต่ jQuery 1.8 ข้อมูลเหตุการณ์ไม่สามารถใช้งานได้จาก "public API" สำหรับข้อมูลอีกต่อไป อ่านโพสต์บล็อก jQueryนี้ ตอนนี้คุณควรใช้สิ่งนี้แทน:

jQuery._data( elem, "events" );

elem ควรเป็นองค์ประกอบ HTML ไม่ใช่วัตถุ jQuery หรือตัวเลือก

โปรดทราบว่านี่เป็นโครงสร้างภายใน 'ส่วนตัว' และไม่ควรแก้ไข ใช้สิ่งนี้เพื่อการดีบักเท่านั้น

ใน jQuery เวอร์ชันเก่าคุณอาจต้องใช้วิธีเก่าซึ่งก็คือ:

jQuery( elem ).data( "events" );

222
แต่คุณยังสามารถใช้งานได้ $._data($(elem).get(0), "events")
bullgare

10
blog.jquery.com/2011/11/08/building-a-slimmer-jquery .data (“ events”): jQuery เก็บข้อมูลที่เกี่ยวข้องกับเหตุการณ์ไว้ในวัตถุข้อมูลชื่อ (รอ) ในแต่ละองค์ประกอบ นี่คือโครงสร้างข้อมูลภายในดังนั้นใน 1.8 นี้จะถูกลบออกจากพื้นที่ชื่อข้อมูลผู้ใช้ดังนั้นมันจะไม่ขัดแย้งกับรายการที่มีชื่อเดียวกัน ข้อมูลเหตุการณ์ของ jQuery ยังสามารถเข้าถึงได้ผ่านทาง jQuery._data (องค์ประกอบ "เหตุการณ์") แต่ทราบว่านี้เป็นโครงสร้างข้อมูลภายในที่ไม่มีเอกสารและไม่ควรได้รับการแก้ไข
Sam Greenhalgh

ฉันใช้วิธีนี้เพื่อลองค้นหาเหตุการณ์คลิกของปุ่ม ในคอนโซล Chrome มันแสดงhandler: function () {ภายในคุณสมบัติคลิก ฉันต้องดับเบิลคลิกที่ส่วนของฟังก์ชั่นเพื่อขยายและแสดงเนื้อหาทั้งหมดของฟังก์ชั่น
Jim

@ Jim yeaaah, ดับเบิลคลิกคือคำตอบ
Adib Aroui

2
สนับสนุนตัวเลือกทั้งสองอย่างต่อเนื่อง:var events = (jQuery._data || jQuery.data)(elem, 'events');
oriadam

84

คุณสามารถทำได้โดยการรวบรวมข้อมูลเหตุการณ์ (ตั้งแต่ jQuery 1.8+) เช่นนี้

$.each($._data($("#id")[0], "events"), function(i, event) {
  // i is the event type, like "click"
  $.each(event, function(j, h) {
    // h.handler is the function being called
  });
});

นี่คือตัวอย่างที่คุณสามารถเล่นกับ:

$(function() {
  $("#el").click(function(){ alert("click"); });
  $("#el").mouseover(function(){ alert("mouseover"); });

  $.each($._data($("#el")[0], "events"), function(i, event) {
    output(i);
    $.each(event, function(j, h) {
        output("- " + h.handler);
    });
  });
});

function output(text) {
    $("#output").html(function(i, h) {
        return h + text + "<br />";
    });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="el">Test</div>
<code>
    <span id="output"></span>
</code>


2
นี่คือคำตอบที่ถูกต้อง บิตที่สำคัญคือครึ่งหลัง สิ่งนี้ช่วยให้ฉันพบปัญหาภายในไม่กี่นาทีซึ่งอาจใช้เวลามากกว่าหนึ่งชั่วโมงถ้าฉันต้องค้นหารหัสทั้งหมด ขอบคุณ!
Andrew Ensley

2
ทำงานร่วมกับ 1.4 แต่ไม่ได้อยู่ใน jQuery 1.8.2
Timo Kähkönen

15
สำหรับ jQuery 1.8+ คุณจะต้องใช้วิธีการ 'ข้อมูลส่วนตัว: jQuery._data( jQuery("#el")[0], "events" );แทนของวิธีการ jQuery("#el").data("events")'ข้อมูลสาธารณะ': eventsวัตถุจริงไม่ได้ถูกเก็บไว้ใน.data()เป็นเวลานานเราตัดแต่งไม่กี่ไบต์ของรหัสที่ออกโดยการลบนี้ "ร็อกซี่" จาก "ประชาชน API"
gnarf

36

สำหรับ jQuery 1.8+ สิ่งนี้จะไม่ทำงานอีกต่อไปเนื่องจากข้อมูลภายในถูกวางไว้ในวัตถุอื่น

ล่าสุดทางการ (แต่ทำงานในรุ่นก่อนหน้าเช่นกันอย่างน้อยใน 1.7.2) วิธีการทำตอนนี้คือ - $._data(element, "events")

ขีดล่าง ("_") คือสิ่งที่สร้างความแตกต่างได้ที่นี่ ภายในจะเรียก$.data(element, name, null, true)พารามิเตอร์สุดท้าย (ที่สี่) เป็นหนึ่งภายใน ("pvt")


$ ._ data ("body", "events") ไม่ได้กำหนด $ (). jquery; "1.7.1" (พยายาม 1.7.2 และ 1.8.1 ตลอดเวลา "ไม่ได้กำหนด")
Mars Robertson

2
@Michal - api.jquery.com/jQuery.dataกล่าวว่ามันยอมรับองค์ประกอบไม่ใช่ตัวเลือก
PhistucK

1
ตอนนี้ใช้งานได้ดี: $ ._ data ($ ("body"). รับ (0), "events") หรือดีกว่า: $ ("body"). data ("events")!
Mars Robertson

2
FWIW - ชี้ให้เห็นว่ามัน 'เรียกภายใน' ฟังก์ชั่นข้อมูลอื่นที่มีพารามิเตอร์ที่เราไม่ได้เอกสารโดยเฉพาะอาจไม่จำเป็น แต่ใช่jQuery._data( element, "events" )เป็นวิธีที่ 'ถูกต้อง' เพื่อรับข้อมูลนี้ในขณะนี้
แคระ

34

ปลั๊กไร้ยางอาย แต่คุณสามารถใช้findHandlerJS

หากต้องการใช้คุณต้องรวมfindHandlersJS (หรือคัดลอกและวางรหัสจาวาสคริปต์ดิบไปที่หน้าต่างคอนโซลของ chrome) และระบุประเภทเหตุการณ์และตัวเลือก jquery สำหรับองค์ประกอบที่คุณสนใจ

สำหรับตัวอย่างของคุณคุณสามารถค้นหาตัวจัดการเหตุการณ์ที่คุณพูดถึงได้อย่างรวดเร็ว

findEventHandlers("click", "#el")
findEventHandlers("mouseover", "#el")

นี่คือสิ่งที่ได้รับคืน:

  • องค์ประกอบองค์ประกอบ
    จริงที่จัดการเหตุการณ์ที่ลงทะเบียน
  • เหตุการณ์
    อาร์เรย์ที่มีข้อมูลเกี่ยวกับการจัดการเหตุการณ์ jQuery สำหรับประเภทกรณีที่เรามีความสนใจใน (เช่นคลิกเปลี่ยนแปลง ฯลฯ )
    • ตัวจัดการ
      เหตุการณ์จริงวิธีจัดการที่คุณสามารถดูได้โดยคลิกขวาและเลือกแสดงความหมายฟังก์ชั่น
    • selector ตัว
      เลือกที่มีให้สำหรับเหตุการณ์ที่มอบหมาย มันจะว่างเปล่าสำหรับเหตุการณ์โดยตรง

    • รายการเป้าหมายที่มีองค์ประกอบที่ตัวจัดการเหตุการณ์เป้าหมาย ตัวอย่างเช่นสำหรับตัวจัดการเหตุการณ์ที่มอบหมายที่ลงทะเบียนในวัตถุเอกสารและกำหนดเป้าหมายปุ่มทั้งหมดในหน้าคุณสมบัตินี้จะแสดงรายการปุ่มทั้งหมดในหน้า คุณสามารถโฮเวอร์พวกเขาและเห็นพวกเขาเน้นในโครเมี่ยม

คุณสามารถลองได้ที่นี่


ฉันคิดว่าควรเป็นคำตอบที่ยอมรับได้ นั่นเป็นสิ่งเดียวที่เหมาะกับฉันเช่นกัน เป็นอย่างละเอียดมากตั้งแต่ผ่านองค์ประกอบทั้งหมดที่ค้นหากิจกรรม
Marquinho Peli

12

ฉันใช้ปลั๊กอินeventbugเพื่อ firebug เพื่อจุดประสงค์นี้


ขอบคุณเคล็ดลับที่ดี ส่วนขยายจะเพิ่มแท็บใน Firebug ("กิจกรรม") ที่แสดงกิจกรรมของหน้าเพื่อให้คุณสามารถ expore ได้อย่างง่ายดาย
Gruber

11
นอกจากนี้เครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ของ Chrome มี "ผู้ฟังเหตุการณ์" ภายใต้แท็บ "องค์ประกอบ" และ "จุดพักการฟังเหตุการณ์" ใต้แท็บ "แหล่งที่มา"
clayzermk1

10

ฉันได้รวมโซลูชันทั้งสองจาก @jps เข้ากับฟังก์ชันเดียว:

jQuery.fn.getEvents = function() {
    if (typeof(jQuery._data) === 'function') {
        return jQuery._data(this.get(0), 'events') || {};
    }

    // jQuery version < 1.7.?
    if (typeof(this.data) === 'function') {
        return this.data('events') || {};
    }

    return {};
};

แต่ระวังฟังก์ชั่นนี้สามารถส่งคืนเหตุการณ์ที่ตั้งค่าโดยใช้ jQuery เท่านั้น


5

ตั้งแต่ 1.9 ไม่มีวิธีจัดทำเอกสารเพื่อเรียกคืนเหตุการณ์นอกเหนือจากการใช้ปลั๊กอินโอนย้ายเพื่อกู้คืนพฤติกรรมเก่า คุณสามารถใช้เมธอด _.data () เป็น jps กล่าวถึง แต่นั่นเป็นวิธีการภายใน ดังนั้นเพียงแค่ทำสิ่งที่ถูกต้องและใช้ปลั๊กอินโยกย้ายหากคุณต้องการฟังก์ชั่นนี้

จากเอกสาร jQuery บน .data("events")

ก่อนหน้า 1.9, .data ("events") สามารถใช้เพื่อดึงโครงสร้างข้อมูลเหตุการณ์ภายในที่ไม่ได้จัดทำของ jQuery สำหรับองค์ประกอบหากไม่มีรหัสอื่นที่กำหนดองค์ประกอบข้อมูลที่มีชื่อ "events" กรณีพิเศษนี้ถูกลบใน 1.9 ไม่มีส่วนต่อประสานสาธารณะในการเรียกคืนโครงสร้างข้อมูลภายในนี้และยังคงไม่มีเอกสาร อย่างไรก็ตามปลั๊กอิน jQuery Migration จะเรียกคืนพฤติกรรมนี้สำหรับโค้ดที่ขึ้นอยู่กับมัน


คำตอบที่ได้รับการยอมรับนอกจากนี้ยังแสดงให้เห็นชัดเจนใหม่ที่ถูกต้องวิธีที่จะได้รับมันสำหรับรุ่นล่าสุด: jQuery._data( elem, "events" );...
เอียน

2
ส่วนตัว, วิธีที่ไม่มีเอกสารจะไม่เป็นที่ถูกต้องวิธี วิธีที่ถูกต้อง - หมายถึงเอกสารเป็นสาธารณะและมีจุดประสงค์ - คือใช้ปลั๊กอินโอนย้าย
oligofren

3
ดูเหมือนว่าคุณเข้าใจผิดเกี่ยวกับจุดโยกย้ายปลั๊กอิน jQuery ลบฟีเจอร์ที่เลิกใช้แล้วและปลั๊กอินโอนย้ายคือช่วยโอนย้ายโค้ดของนักพัฒนาไปเป็นเวอร์ชันที่ใหม่กว่าเพื่อให้สามารถใช้ประโยชน์จากฟีเจอร์และการปรับปรุงใหม่ได้ทันที แต่ไม่สูญเสียฟังก์ชันการทำงาน มันมีไว้เพื่อช่วยให้ผู้เข้ารหัสเห็นสิ่งที่พวกเขาต้องทำเพื่อเริ่มต้นอย่างถูกต้องโดยใช้ jQuery เวอร์ชันใหม่ คุณไม่ควรใช้ในการผลิตเพื่อกู้คืนฟีเจอร์ นอกจากนี้ยังมีหลายสิ่งหลายอย่างจะไม่ไว้และถึงวันที่ในเอกสาร jQuery - พวกเขาได้ชี้ออกมาก่อนดังนั้นนั่นไม่ใช่เหตุผล
เอียน

นอกจากนี้หากมีการรวมไว้เป็นข้อเสนอแนะในบล็อก jQuery ฉันจะใช้มัน: blog.jquery.com/2012/08/09/jquery-1-8-released
Ian

การใช้เหตุผลของคุณในการย้ายข้อมูลปลั๊กอินดูเหมือนว่าสมเหตุสมผล ตกลงถ้าฉันลบคำตอบ?
oligofren

5

วิธีตรวจสอบเหตุการณ์ในองค์ประกอบ:

var events = $._data(element, "events")

โปรดทราบว่าสิ่งนี้จะใช้ได้กับตัวจัดการเหตุการณ์โดยตรงเท่านั้นหากคุณใช้ $ (เอกสาร) .on ("event-name", "jq-selector", function () {// logic}) คุณจะต้องการดู ฟังก์ชัน getEvents ที่ด้านล่างของคำตอบนี้

ตัวอย่างเช่น:

 var events = $._data(document.getElementById("myElemId"), "events")

หรือ

 var events = $._data($("#myElemId")[0], "events")

ตัวอย่างเต็มรูปแบบ:

<html>
    <head>
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js" type="text/javascript"></script>
        <script>
            $(function() {
                $("#textDiv").click(function() {
                    //Event Handling
                });
                var events = $._data(document.getElementById('textDiv'), "events");
                var hasEvents = (events != null);
            });
        </script>
    </head>
    <body>
        <div id="textDiv">Text</div>
    </body>
</html>

วิธีตรวจสอบที่สมบูรณ์ยิ่งขึ้นซึ่งรวมถึงฟังแบบไดนามิกติดตั้งด้วย $ (เอกสาร) .on

function getEvents(element) {
    var elemEvents = $._data(element, "events");
    var allDocEvnts = $._data(document, "events");
    for(var evntType in allDocEvnts) {
        if(allDocEvnts.hasOwnProperty(evntType)) {
            var evts = allDocEvnts[evntType];
            for(var i = 0; i < evts.length; i++) {
                if($(element).is(evts[i].selector)) {
                    if(elemEvents == null) {
                        elemEvents = {};
                    }
                    if(!elemEvents.hasOwnProperty(evntType)) {
                        elemEvents[evntType] = [];
                    }
                    elemEvents[evntType].push(evts[i]);
                }
            }
        }
    }
    return elemEvents;
}

ตัวอย่างการใช้งาน:

getEvents($('#myElemId')[0])

getEventsวิธีนี้เป็นวิธีที่ยอดเยี่ยมมาก แต่สิ่งนี้คือให้รายการที่ซ้ำกันใน IE11 (ฉันรู้ว่า IE อีกครั้ง แต่องค์กรต้องการมัน ... ) แก้ไข: ข้อมูล $ ._ มีกิจกรรมที่ซ้ำกันสำหรับองค์ประกอบแม้ว่าใน FF จะไม่มี ... Weird IE world แต่สิ่งสำคัญคือต้องระวังความเป็นไปได้ที่จะมีเหตุการณ์ที่ซ้ำกันนี้
Dominik Szymański

โอ้ทอมเป็นรหัสของคุณที่คูณเหตุการณ์ด้วยการประมวลผลวิธีนี้แต่ละครั้ง ไม่ดี.
Dominik Szymański

4

ฉันสร้างตัวเลือก jQuery แบบกำหนดเองที่ตรวจสอบกับทั้งแคชของ jQuery ของตัวจัดการเหตุการณ์ที่กำหนดรวมถึงองค์ประกอบที่ใช้วิธีเนทีฟสำหรับเพิ่ม:

(function($){

    $.find.selectors[":"].event = function(el, pos, match) {

        var search = (function(str){
            if (str.substring(0,2) === "on") {str = str.substring(2);}
            return str;
        })(String(match[3]).trim().toLowerCase());

        if (search) {
            var events = $._data(el, "events");
            return ((events && events.hasOwnProperty(search)) || el["on"+search]);
        }

        return false;

    };

})(jQuery);

ตัวอย่าง:

$(":event(click)")

นี่จะส่งคืนองค์ประกอบที่มีตัวจัดการการคลิกแนบอยู่


2

ในเบราว์เซอร์ที่ทันสมัยด้วย ECMAScript 5.1 / Array.prototype.mapคุณสามารถใช้

jQuery._data(DOCUMENTELEMENT,'events')["EVENT_NAME"].map(function(elem){return elem.handler;});

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


jQuery._data('ct100_ContentPlaceHolder1_lcsSection','events')["EVENT_NAME"].map(function(elem){return elem.handler;}); Uncaught TypeError: ไม่สามารถอ่านคุณสมบัติ 'EVENT_NAME' จากไม่ได้กำหนดที่ <anonymous>: 1: 62
Mike W

'ct100_ContentPlaceHolder1_lcsSection'เป็นสตริงไม่ใช่องค์ประกอบ DOM
Jesan Fafon

2

สามารถเรียกคืนกิจกรรมโดยใช้:

jQuery(elem).data('events');

หรือ jQuery 1.8+:

jQuery._data(elem, 'events');

หมายเหตุ: เหตุการณ์ที่ล้อมรอบโดยใช้$('selector').live('event', handler) สามารถเรียกคืนได้โดยใช้:

jQuery(document).data('events')

2
jQuery (document) .data ('events') ทำให้ฉันไม่ได้กำหนด
Mike W

1

ฉันต้องบอกว่าคำตอบมากมายน่าสนใจ แต่เมื่อเร็ว ๆ นี้ฉันมีปัญหาที่คล้ายกันและวิธีการแก้ปัญหาก็ง่ายมากโดยไปที่ DOM มันแตกต่างกันเพราะคุณไม่ได้ทำซ้ำ แต่มุ่งตรงไปที่เหตุการณ์ที่คุณต้องการ แต่ด้านล่างฉันจะให้คำตอบทั่วไปมากขึ้น

ฉันมีภาพซ้อนกัน:

<table>
  <td><tr><img class="folder" /></tr><tr>...</tr></td>
</table>

และภาพนั้นมีตัวจัดการเหตุการณ์คลิกติดอยู่:

imageNode.click(function () { ... });

ความตั้งใจของฉันคือการขยายพื้นที่ที่สามารถคลิกได้ไปยังแถวทั้งหมดดังนั้นฉันจึงได้ภาพและแถวที่เกี่ยวข้องทั้งหมด:

tableNode.find("img.folder").each(function () {
  var tr;

  tr = $(this).closest("tr");
  // <-- actual answer
});

ตอนนี้ในบรรทัดanwer จริงฉันเพิ่งทำดังนี้ให้คำตอบสำหรับคำถามเดิม:

tr.click(this.onclick);

ดังนั้นฉันจึงดึงตัวจัดการเหตุการณ์โดยตรงจากองค์ประกอบ DOM และใส่ลงในตัวจัดการเหตุการณ์การคลิก jQuery ทำงานเหมือนจับใจ

ตอนนี้กับกรณีทั่วไป ใน pre-jQuery วันเก่าที่คุณจะได้รับทุกเหตุการณ์ที่แนบมากับวัตถุที่มีสองที่เรียบง่ายและทำงานที่มีประสิทธิภาพพรสวรรค์ที่เราปุถุชนโดยดักลาส Crockford :

function walkTheDOM(node, func)
{
  func(node);
  node = node.firstChild;
  while (node)
  {
    walkTheDOM(node, func);
    node = node.nextSibling;
  }
}

function purgeEventHandlers(node)
{
  walkTheDOM(node, function (n) {
    var f;

    for (f in n)
    {
      if (typeof n[f] === "function")
      {
        n[f] = null;
      }
    }
  });
}


0

อีกวิธีในการทำก็เพียงแค่ใช้ jQuery เพื่อดึงองค์ประกอบจากนั้นไปที่ Javascript จริงเพื่อรับและตั้งค่าและเล่นกับตัวจัดการเหตุการณ์ ตัวอย่างเช่น

var oldEventHandler = $('#element')[0].onclick;
// Remove event handler
$('#element')[0].onclick = null;
// Switch it back
$('#element')[0].onclick = oldEventHandler;

1
ฉันคิดว่า jQuery ทำการจัดการการเพิ่มประสิทธิภาพที่ฉันคิดว่าถูกหลีกเลี่ยงโดยโค้ดของคุณที่นี่
Emile Bergeron

ขอบคุณใช่ฉันมีความรู้สึกว่านี่เป็นเรื่องแฮ็ค - ลิงก์ใด ๆ ที่ดีในการเรียนรู้เพิ่มเติมเกี่ยวกับการเพิ่มประสิทธิภาพนั้น
tempranova

0

ฉันได้รวมคำตอบบางส่วนไว้ด้านบนและสร้างสคริปต์ที่ดูบ้าคลั่ง แต่ใช้งานได้ซึ่งแสดงรายการหวังว่าผู้ฟังเหตุการณ์ส่วนใหญ่ในองค์ประกอบที่กำหนด อย่าลังเลที่จะเพิ่มประสิทธิภาพได้ที่นี่

var element = $("#some-element");

// sample event handlers
element.on("mouseover", function () {
  alert("foo");
});

$(".parent-element").on("mousedown", "span", function () {
  alert("bar");
});

$(document).on("click", "span", function () {
  alert("xyz");
});

var collection = element.parents()
  .add(element)
  .add($(document));
collection.each(function() {
  var currentEl = $(this) ? $(this) : $(document);
  var tagName = $(this)[0].tagName ? $(this)[0].tagName : "DOCUMENT";
  var events = $._data($(this)[0], "events");
  var isItself = $(this)[0] === element[0]
  if (!events) return;
  $.each(events, function(i, event) {
    if (!event) return;
    $.each(event, function(j, h) {
      var found = false;        
      if (h.selector && h.selector.length > 0) {
        currentEl.find(h.selector).each(function () {
          if ($(this)[0] === element[0]) {
            found = true;
          }
        });
      } else if (!h.selector && isItself) {
        found = true;
      }

      if (found) {
        console.log("################ " + tagName);
        console.log("event: " + i);
        console.log("selector: '" + h.selector + "'");
        console.log(h.handler);
      }
    });
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="parent-element">
  <span id="some-element"></span>
</div>


0

jQuery ไม่ได้ให้คุณเพียงแค่เข้าถึงกิจกรรมสำหรับองค์ประกอบที่กำหนด คุณสามารถเข้าถึงได้โดยใช้วิธีการภายในที่ไม่มีเอกสาร

$._data(element, "events")

แต่มันจะไม่ให้เหตุการณ์ทั้งหมดแก่คุณเพื่อความแม่นยำจะไม่แสดงกิจกรรมที่คุณมอบหมาย

$([selector|element]).on()

เหตุการณ์เหล่านี้ถูกเก็บไว้ในเอกสารดังนั้นคุณสามารถดึงข้อมูลได้โดยการเรียกดู

$._data(document, "events")

แต่นั่นเป็นงานที่ยากเนื่องจากมีกิจกรรมสำหรับหน้าเว็บทั้งหมด

Tom G ด้านบนสร้างฟังก์ชันที่กรองเอกสารสำหรับเหตุการณ์เฉพาะขององค์ประกอบที่กำหนดและผสานเอาท์พุทของทั้งสองวิธี แต่มีข้อบกพร่องของการทำซ้ำเหตุการณ์ในผลลัพธ์ (และมีประสิทธิภาพในรายการเหตุการณ์ภายใน jQuery องค์ประกอบขององค์ประกอบ ฉันแก้ไขข้อบกพร่องนั้นแล้วคุณจะพบรหัสด้านล่าง เพียงแค่วางลงในคอนโซล dev ของคุณหรือลงในรหัสแอปของคุณและดำเนินการเมื่อจำเป็นเพื่อรับรายการกิจกรรมทั้งหมดสำหรับองค์ประกอบที่กำหนด

สิ่งสำคัญคือการสังเกตองค์ประกอบเป็นจริง HTMLElement ไม่ใช่วัตถุ jQuery

function getEvents(element) {
    var elemEvents = $._data(element, "events");
    var allDocEvnts = $._data(document, "events");
    function equalEvents(evt1, evt2)
    {
        return evt1.guid === evt2.guid;
    }

    for(var evntType in allDocEvnts) {
        if(allDocEvnts.hasOwnProperty(evntType)) {
            var evts = allDocEvnts[evntType];
            for(var i = 0; i < evts.length; i++) {
                if($(element).is(evts[i].selector)) {
                    if(elemEvents == null) {
                        elemEvents = {};
                    }
                    if(!elemEvents.hasOwnProperty(evntType)) {
                        elemEvents[evntType] = [];
                    }
                    if(!elemEvents[evntType].some(function(evt) { return equalEvents(evt, evts[i]); })) {
                        elemEvents[evntType].push(evts[i]);
                    }
                }
            }
        }
    }
    return elemEvents;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.