AddEventListener में useCapture पैरामीटर समझने में असमर्थ


290

मैंने https://developer.mozilla.org/en/DOM/element.addEventListener पर लेख पढ़ा है लेकिन useCaptureविशेषता को समझने में असमर्थ है । परिभाषा है:

यदि सही है, तो useCapture इंगित करता है कि उपयोगकर्ता कैप्चर आरंभ करना चाहता है। कैप्चर शुरू करने के बाद, निर्दिष्ट प्रकार की सभी घटनाओं को डोम ट्री में किसी भी ईवेंटटार्ग के नीचे भेजे जाने से पहले पंजीकृत श्रोता के पास भेजा जाएगा। पेड़ के माध्यम से ऊपर की ओर बुदबुदाने वाली घटनाएं कब्जा करने के लिए नामित श्रोता को ट्रिगर नहीं करेंगी।

इस कोड में माता-पिता की घटना बच्चे से पहले शुरू होती है, इसलिए मैं इसके व्यवहार को समझ नहीं पा रहा हूं। मित्रता ऑब्जेक्ट में usecapture सही है और चाइल्ड डिव में usecapture सेट गलत है और डॉक्यूमेंट usecapture का पालन किया जाता है। इसलिए दस्तावेज़ संपत्ति बच्चे पर क्यों पसंद की जाती है।

function load() {
  document.addEventListener("click", function() {
    alert("parent event");
  }, true);

  document.getElementById("div1").addEventListener("click", function() {
    alert("child event");
  }, false);
}
<body onload="load()">
  <div id="div1">click me</div>
</body>

जवाबों:


350

घटनाओं को दो अवसरों पर सक्रिय किया जा सकता है: शुरुआत में ("कब्जा"), और अंत में ("बुलबुला")। ईवेंट परिभाषित किए जाने के क्रम में निष्पादित किए जाते हैं। कहें, आप 4 ईवेंट श्रोताओं को परिभाषित करते हैं:

window.addEventListener("click", function(){console.log(1)}, false);
window.addEventListener("click", function(){console.log(2)}, true);
window.addEventListener("click", function(){console.log(3)}, false);
window.addEventListener("click", function(){console.log(4)}, true);

इस क्रम में लॉग संदेश दिखाई देंगे:

  • 2(पहले परिभाषित, प्रयोग capture=true)
  • 4(परिभाषित दूसरा प्रयोग capture=true)
  • 1(पहले परिभाषित घटना capture=false)
  • 3(दूसरी परिभाषित घटना capture=false)

49
निष्पादन के आदेश है इसकी गारंटी नहीं : no specification is made as to the order in which they will receive the event with regards to the other EventListeners on the EventTarget। मैंने सभी ब्राउज़रों का परीक्षण नहीं किया है, इसलिए वे सभी इसे उसी तरह लागू करने के लिए हो सकते हैं। हालाँकि, कैप्चरिंग ईवेंट्स गैर-कैप्चरिंग इवेंट्स से पहले किए जाएंगे।
बीटगैमिट

47
@tjameson निष्पादन के आदेश है Dom2 कल्पना के उत्तराधिकारी में गारंटी, DOM3 घटनाओं : "कार्यान्वयन वर्तमान लक्ष्य का निर्धारण करना चाहिए उम्मीदवार घटना श्रोताओं यह सब घटना श्रोताओं को में वर्तमान लक्ष्य पर पंजीकृत किया गया की सूची में होना चाहिए उनके। पंजीकरण का आदेश। "
रॉब डब्ल्यू

1
इसलिए यह मूल रूप से घटना क्रम के साथ मुझे लगता है
18

1
@ सामान्य, हाँ, जिस क्रम में एक ही घटना के लिए कई हैंडलर निष्पादित किए जाते हैं।
JMD

6
पता नहीं क्यों यह स्वीकार किए जाते हैं उत्तर के बाद से afaik, कैप्चरिंग और बुदबुदाहट प्रचार व्यवहार के बारे में बात करती है और कई, आसन्न घटना संचालकों के लिए निष्पादन के आदेश को
निर्धारित

272

मुझे लगता है कि यह चित्र कैप्चर / टारगेट / बबल चरणों को समझने के लिए बहुत उपयोगी है: http://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events.phases

नीचे, लिंक से निकाली गई सामग्री।

के चरण

घटना को पेड़ की जड़ से इस लक्ष्य नोड तक एक पथ के बाद भेजा जाता है। फिर इसे स्थानीय स्तर पर लक्ष्य नोड स्तर पर या पेड़ में उच्चतर किसी भी लक्ष्य के पूर्वजों से नियंत्रित किया जा सकता है। प्रेषण घटना (जिसे ईवेंट प्रचार भी कहा जाता है) तीन चरणों और निम्न क्रम में होती है:

  1. कब्जा चरण: घटना को पेड़ की जड़ से लक्ष्य नोड के प्रत्यक्ष माता-पिता को लक्ष्य के पूर्वजों को भेज दिया जाता है।
  2. लक्ष्य चरण: घटना को लक्ष्य नोड के लिए भेजा जाता है।
  3. बुदबुदाहट चरण: घटना को लक्ष्य नोड के प्रत्यक्ष माता-पिता से पेड़ की जड़ तक लक्ष्य के पूर्वजों को भेज दिया जाता है।

DOM घटना प्रवाह का उपयोग करके DOM ट्री में भेजे गए ईवेंट का चित्रमय प्रतिनिधित्व

लक्ष्य के पूर्वजों को घटना के प्रारंभिक प्रेषण से पहले निर्धारित किया जाता है। यदि प्रेषण के दौरान लक्ष्य नोड को हटा दिया जाता है, या किसी लक्ष्य के पूर्वज को जोड़ या हटा दिया जाता है, तो ईवेंट प्रचार हमेशा लक्ष्य नोड और प्रेषण से पहले निर्धारित लक्ष्य के पूर्वजों पर आधारित होगा।

कुछ घटनाएँ आवश्यक रूप से DOM घटना प्रवाह के तीन चरणों को पूरा नहीं कर सकती हैं, जैसे कि घटना को केवल एक या दो चरणों के लिए परिभाषित किया जा सकता है। एक उदाहरण के रूप में, इस विनिर्देश में परिभाषित घटनाएं हमेशा कैप्चर और टारगेट चरणों को पूरा करेंगी, लेकिन कुछ बबलिंग चरण ("बब्लिंग इवेंट्स" बनाम "नॉन-बबलिंग इवेंट्स" को पूरा नहीं करेंगी, इवेंट भी देखें। बुलबुले की विशेषता)।


1
बहुत अच्छा चित्र!
एलेक्स

1
लक्ष्य नोड के बच्चों के बारे में कैसे? उन्हें घटना कब मिलती है?
औरिमास

क्या पेड़ की जड़ वास्तव में है Window, इसके बजाय document, क्योंकि documentबच्चा है Window?
स्टैकजेली

1
@ अरीमास वे नहीं करते हैं, इससे कोई मतलब नहीं होगा। लक्ष्य सबसे भीतरी तत्व है जिसे घटना प्राप्त करनी चाहिए। यदि आप <body> तत्व (एक खाली जगह) पर क्लिक करते हैं, तो <body> (= पृष्ठ के सभी तत्व) के अंदर के सभी तत्व स्पष्ट रूप से क्लिक इवेंट प्राप्त नहीं करना चाहिए।
आमिक

1
मैं सिर्फ उन सभी संसाधनों की कामना करता हूं, जिन्होंने "क्या" को "क्यों" शामिल किया है। हमेशा की तरह अधिक googling के लिए रवाना।
आआआआआआआ

80

कैप्चर इवेंट ( useCapture = true) बनाम बबल इवेंट ( useCapture = false)

एमडीएन संदर्भ

  • बबल इवेंट से पहले कैप्चर इवेंट प्रेषण किया जाएगा
  • ईवेंट प्रचार आदेश है
    1. जनक कैद
    2. बच्चे पकड़ लेते हैं
    3. लक्ष्य कैप्चर और लक्ष्य बुलबुला
      • आदेश में वे पंजीकृत थे
      • जब तत्व घटना का लक्ष्य है, तो useCaptureपैरामीटर कोई फर्क नहीं पड़ता (धन्यवाद @bam और @ किंवदंती 80)
    4. बच्चे बबलू
    5. जनक बबल
  • stopPropagation() प्रवाह को रोक देगा

कैप्चर फ्लो का उपयोग करें

डेमो

परिणाम:

  1. जनक कैद
  2. लक्ष्य बुलबुला १

    (क्योंकि कैप्चर और बबल ऑफ टारगेट वे दर्ज किए गए क्रम में ट्रिगर करेंगे, इसलिए बबल ईवेंट कैप्चर इवेंट से पहले ट्रिगर होता है)

  3. लक्ष्य पर कब्जा

  4. लक्ष्य बुलबुला २
  5. जनक बबल

var parent = document.getElementById('parent'),
target = document.getElementById('target');

target.addEventListener('click', function (e) { 
console.log('Target Bubble 1');
// e.stopPropagation();
}, false);

target.addEventListener('click', function (e) { 
console.log('Target Capture');
// e.stopPropagation();
}, true);

target.addEventListener('click', function (e) { 
console.log('Target Bubble 2');
// e.stopPropagation();
}, false);

parent.addEventListener('click', function (e) { 
console.log('Parent Capture');
// e.stopPropagation();
}, true);

parent.addEventListener('click', function (e) { 
console.log('Parent Bubble');
// e.stopPropagation();
}, false);
<div id="parent">
    <button id="target" style="padding: 1em 0.8em;">
        Trigger event
    </button>
</div>


1
उदाहरण में एक गलती है: आपने क्रम में बच्चे की घटनाओं की घोषणा की: 1. बच्चे पर कब्जा 2. बच्चा बुलबुला यह मायने रखता है! सिर्फ इसलिए कि अगर बच्चा घटना का लक्ष्य होगा, श्रोताओं को उसी क्रम में बुलाया जाएगा। एमडीएन पर नोट देखें: जब तत्व घटना का लक्ष्य है 'यूज़कैपचर' पैरामीटर कोई फर्क नहीं पड़ता। ( developer.mozilla.org/en-US/docs/Web/API/EventTarget/… )
बाम

1
नोट : ईवेंट टारगेट से जुड़े इवेंट श्रोताओं के लिए, कैप्चरिंग और बबलिंग चरणों के बजाय ईवेंट लक्ष्य चरण में है। Events in the target phase will trigger all listeners on an element in the order they were registered, regardless of the useCapture parameter.से developer.mozilla.org/en-US/docs/Web/API/EventTarget/... । इसलिए "चिल्ड्रन कैप्चर" और "चिल्ड्रेन बबल" का कोई चरण नहीं है।
पौराणिक कथा

और यह बताता है कि "बच्चे पकड़ने" से पहले उदाहरण "रनिंग बबल 1" क्यों पैदा करता है, जब आरेख बताता है कि "कब्जा" हमेशा किसी भी तत्व के लिए पहले होना चाहिए!
गेरशोम

18

जब आप कहते हैं कि यूजफेकप्टर = ट्रू इवेंट्स कैप्चर फेज में ऊपर से नीचे की तरफ एग्जीक्यूट करता है जब वह गलत होता है तो वह बबल बॉटम को टॉप पर करता है।


11

यह सभी इवेंट मॉडल के बारे में है: http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow आप ईवेंट को बबलिंग चरण या कैप्चरिंग चरण में पकड़ सकते हैं। आपकी पंसद। Http://www.quirksmode.org/js/events_order.html
पर एक नज़र डालें - आप इसे बहुत उपयोगी पाएंगे।


1
w3 के लिंक गूगल सर्च की तुलना में कम या ज्यादा उपयोगी हैं, लेकिन मैं वहां कुछ भी नहीं समझ सकता।
मुहम्मद उमेर Mu

3
हाँ, वह w3 लिंक सिर्फ शब्दों का एक बड़ा गुच्छा है, लेकिन इसके विपरीत, quirksmode साइट का दूसरा लिंक विषय को बहुत अच्छी तरह और संक्षेप में बताता है।
स्टेनो

11

कोड उदाहरण:

<div id="div1" style="background:#9595FF">
  Outer Div<br />
  <div id="div2" style="background:#FFFFFF">
    Inner Div
  </div>
</div>

जावास्क्रिप्ट कोड:

d1 = document.getElementById("div1");
d2 = document.getElementById("div2");

अगर दोनों झूठे हैं

d1.addEventListener('click',function(){alert("Div 1")},false);
d2.addEventListener('click',function(){alert("Div 2")},false);

Executes: इनर डिक्लाइन को ऑन करते हुए, अलर्ट प्रदर्शित किए जाते हैं: Div 2> Div 1

यहां स्क्रिप्ट को आंतरिक तत्व से निष्पादित किया गया है: ईवेंट बबलिंग (उपयोग गलत पर सेट किया गया है)

div 1 को सही पर सेट किया गया है और div 2 को असत्य पर सेट किया गया है

d1.addEventListener('click',function(){alert("Div 1")},true);
d2.addEventListener('click',function(){alert("Div 2")},false);

Executes: इनर डिक्वायरिंग पर क्लिक करते हुए, अलर्ट प्रदर्शित किए जाते हैं: Div 1> Div 2

यहां स्क्रिप्ट को पूर्वज / बाहरी तत्व से निष्पादित किया जाता है: ईवेंट कैप्चरिंग (उपयोग सही पर सेट किया गया है)

div 1 को झूठा और div 2 को सत्य पर सेट किया जाता है

d1.addEventListener('click',function(){alert("Div 1")},false);
d2.addEventListener('click',function(){alert("Div 2")},true);

Executes: इनर डिक्लाइन को ऑन करते हुए, अलर्ट प्रदर्शित किए जाते हैं: Div 2> Div 1

यहां स्क्रिप्ट को आंतरिक तत्व से निष्पादित किया गया है: ईवेंट बबलिंग (उपयोग गलत पर सेट किया गया है)

div 1 सच पर सेट है और div 2 सच पर सेट है

d1.addEventListener('click',function(){alert("Div 1")},true);
d2.addEventListener('click',function(){alert("Div 2")},true);

Executes: इनर डिक्वायरिंग पर क्लिक करते हुए, अलर्ट प्रदर्शित किए जाते हैं: Div 1> Div 2

यहां स्क्रिप्ट को पूर्वज / बाहरी तत्व से निष्पादित किया जाता है: इवेंट कैप्चरिंग का उपयोग के बाद से सही करने के लिए सेट किया गया है


1
इस संदर्भ में "अधिक से अधिक" शेवरॉन का क्या अर्थ है?
2540625

9

सारांश:

इसमें DOMवर्णित युक्ति:

https://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-phases

निम्नलिखित तरीके से काम करता है:

एक घटना को documentपेड़ के मूल ( ) से लक्ष्य नोड तक एक पथ के बाद भेजा जाता है । लक्ष्य नोड सबसे गहरा HTMLतत्व है, जो कि ईवेंट है। प्रेषण घटना (जिसे ईवेंट प्रचार भी कहा जाता है) तीन चरणों और निम्न क्रम में होती है:

  1. कब्जा चरण: घटना को पेड़ की जड़ ( document) से लक्ष्य नोड के प्रत्यक्ष माता-पिता तक लक्ष्य के पूर्वजों को भेज दिया जाता है।
  2. लक्ष्य चरण: घटना को लक्ष्य नोड के लिए भेजा जाता है। लक्ष्य चरण हमेशा सबसे गहरे htmlतत्व पर होता है, जिस पर यह घटना छितरी हुई थी।
  3. बुदबुदाहट चरण: घटना को लक्ष्य नोड के प्रत्यक्ष माता-पिता से पेड़ की जड़ तक लक्ष्य के पूर्वजों को भेज दिया जाता है।

इवेंट बबलिंग, इवेंट कैप्चरिंग, इवेंट टारगेट

उदाहरण:

// bubbling handlers, third argument (useCapture) false (default)
document.getElementById('outerBubble').addEventListener('click', () => {
  console.log('outerBubble');
}, false)

document.getElementById('innerBubble').addEventListener('click', () => {
  console.log('innerBubble');
}, false)


// capturing handlers, third argument (useCapture)  true
document.getElementById('outerCapture').addEventListener('click', () => {
  console.log('outerCapture');
}, true)

document.getElementById('innerCapture').addEventListener('click', () => {
  console.log('innerCapture');
}, true)
div:hover{
  color: red;
  cursor: pointer;
}
<!-- event bubbling -->
<div id="outerBubble">
  <div id="innerBubble">click me to see Bubbling</div>
</div>


<!-- event capturing -->
<div id="outerCapture">
  <div id="innerCapture">click me to see Capturing</div>
</div>

उपरोक्त उदाहरण वास्तव में इवेंट बबलिंग और ईवेंट कैप्चरिंग के बीच के अंतर को दर्शाता है। ईवेंट श्रोताओं को जोड़ने के दौरान addEventListener, एक तीसरा तत्व है, जिसे यूकैपचर कहा जाता है। यह booleanतब होता है जब trueइवेंट बर्नर के बजाय इवेंट श्रोता को इवेंट कैप्चरिंग का उपयोग करने की अनुमति देता है।

हमारे उदाहरण में, जब हम यू-चेप्टर तर्क का उपयोग falseकरते हैं, तो हम देखते हैं कि घटना बुदबुदाती है। पहले लक्ष्य चरण की घटना को निकाल दिया जाता है (इनरबबल लॉग करता है), और फिर इवेंट के माध्यम से पैरेंट एलिमेंट में घटना को निकाल दिया जाता है (लॉगबॉयर लॉग्स)।

जब हम useCapture तर्क सेट करते हैं trueतो हम देखते हैं कि बाहरी में घटना <div>पहले निकाल दी जाती है। ऐसा इसलिए है क्योंकि ईवेंट अब कैप्चरिंग चरण में निकाल दिया गया है न कि बबलिंग चरण।


7

घटना यात्रा के तीन चरणों को देखते हुए :

  1. कब्जा चरण : घटना लक्ष्य नोड के प्रत्यक्ष माता-पिता के लिए पेड़ की जड़ से लक्ष्य के पूर्वजों के लिए भेजा जाता है।
  2. लक्ष्य चरण : घटना लक्ष्य नोड के लिए भेजा जाता है।
  3. बुदबुदाती चरण : घटना पेड़ की जड़ को लक्ष्य नोड के प्रत्यक्ष माता पिता से लक्ष्य के पूर्वजों के लिए भेजा जाता है।

useCaptureइंगित करता है कि किसके लिए घटना यात्रा होगी:

यदि true, useCapture इंगित करता है कि उपयोगकर्ता ईवेंट श्रोता को केवल कैप्चर चरण के लिए जोड़ना चाहता है, अर्थात इस ईवेंट श्रोता को लक्ष्य और बबलिंग चरणों के दौरान ट्रिगर नहीं किया जाएगा। यदि false, इवेंट श्रोता केवल लक्ष्य और बुदबुदाती चरणों के दौरान ट्रिगर किया जाएगा

स्रोत दूसरे सर्वश्रेष्ठ उत्तर के समान है: https://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-phases


2

परिभाषा का क्रम केवल तभी मायने रखता है जब आइटम समान स्तर पर हों। यदि आप अपने कोड में परिभाषा के क्रम को उलटते हैं तो आपको समान परिणाम मिलेंगे।

हालाँकि, यदि आप दो ईवेंट हैंडलर पर उपयोग सेटिंग सेटिंग को उल्टा करते हैं, तो चाइल्ड ईवेंट हैंडलर पैरेंट के पहले प्रतिक्रिया करता है। इसका कारण यह है कि चाइल्ड ईवेंट हैंडलर को अब कैप्चर चरण में ट्रिगर किया जाएगा जो बबलिंग चरण से पहले होता है जिसमें पैरेंट इवेंट हैंडलर को ट्रिगर किया जाएगा।

यदि आप दोनों घटना संचालकों के लिए सही करने के लिए useCapture सेट करते हैं - परिभाषा के आदेश की परवाह किए बिना - अभिभावक घटना संचालक को पहले ट्रिगर किया जाएगा क्योंकि यह कैप्चरिंग चरण में बच्चे से पहले आता है।

इसके विपरीत, यदि आप दोनों घटना संचालकों के लिए झूठे का उपयोग करें - फिर से परिभाषा के आदेश की परवाह किए बिना - बाल घटना संचालक को पहले ट्रिगर किया जाएगा क्योंकि यह बबलिंग चरण में माता-पिता से पहले आता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.