DOM इवेंट डेलिगेशन क्या है?


202

क्या कोई कृपया जावास्क्रिप्ट में घटना प्रतिनिधिमंडल को समझा सकता है और यह कैसे उपयोगी है?


2
यह अच्छा है अगर इस बारे में जानकारी के उपयोगी स्रोत को स्मो करने के लिए एक लिंक था। 6 घंटे, यह "डोम इवेंट डेलिगेशन" के लिए Google शीर्ष हिट है। शायद यह एक उपयोगी कड़ी है? मुझे पूरा यकीन नहीं है: w3.org/TR/DOM-Level-2-Events/events.html
सीन मैकमिलन

या हो सकता है कि यह: sitepoint.com/blogs/2008/07/23/…
सीन मैकमिलन

7
यह एक लोकप्रिय है। यहां तक ​​कि fb लोग अपने रिएक्टज पेज davidwalsh.name/event-delegate
सॉर्टर

इस javascript.info/event-delegation को देखें इससे आपको बहुत मदद मिलेगी
सूरज जैन

जवाबों:


330

DOM इवेंट डेलिगेशन प्रत्येक बच्चे के बजाय एकल आम माता-पिता के माध्यम से ui-इवेंट्स का जवाब देने का एक तंत्र है, घटना "bubbling" (उर्फ इवेंट प्रचार) के जादू के माध्यम से।

जब किसी तत्व पर कोई घटना शुरू होती है , तो निम्न होता है :

घटना अपने लक्ष्य के लिए भेजा जाता है EventTargetऔर किसी भी घटना श्रोताओं पाया कि ट्रिगर कर रहे हैं। बुदबुदाती घटनाओं तो अनुसरण करके किसी भी अतिरिक्त घटना श्रोताओं को गति प्रदान करेगा EventTargetके माता-पिता श्रृंखला ऊपर की ओर , प्रत्येक उत्तरोत्तर EventTarget पर पंजीकृत किसी भी घटना श्रोताओं के लिए जाँच। यह ऊपर की ओर प्रचार प्रसार जारी रहेगा Document

ईवेंट बबलिंग ब्राउज़रों में ईवेंट प्रतिनिधिमंडल के लिए आधार प्रदान करता है। अब आप किसी इवेंट पेरेंट को सिंगल पेरेंट एलिमेंट में बाँध सकते हैं, और जब भी ईवेंट उसके किसी भी चाइल्ड नोड्स (और बदले में उसके किसी भी बच्चे ) पर होगा। यह इवेंट डेलिगेशन है। यहाँ इसका एक उदाहरण प्रचलन में है:

<ul onclick="alert(event.type + '!')">
    <li>One</li>
    <li>Two</li>
    <li>Three</li>
</ul>

उस उदाहरण के साथ यदि आप बच्चे के किसी भी <li>नोड पर क्लिक करना चाहते हैं, तो आपको एक अलर्ट दिखाई देगा "click!", फिर भी <li>आपके द्वारा क्लिक किए जाने के लिए बाध्य कोई हैंडलर नहीं है । यदि हम onclick="..."प्रत्येक के लिए बाध्य होते हैं <li>तो आपको समान प्रभाव मिलेगा।

तो फायदा क्या हुआ?

कल्पना कीजिए कि अब आपको <li>डोम हेरफेर के माध्यम से उपरोक्त सूची में नए आइटम को गतिशील रूप से जोड़ना होगा :

var newLi = document.createElement('li');
newLi.innerHTML = 'Four';
myUL.appendChild(newLi);

ईवेंट प्रतिनिधिमंडल का उपयोग किए बिना आपको "onclick"नए हैंडलर के लिए ईवेंट हैंडलर को "रिबंड" करना होगा <li>, ताकि वह अपने भाई-बहनों की तरह ही कार्य कर सके। इवेंट डेलिगेशन के साथ आपको कुछ भी करने की आवश्यकता नहीं है। बस <li>सूची में नया जोड़ें और आपका काम हो गया।

यह कई तत्वों से जुड़े इवेंट हैंडलर वाले वेब ऐप्स के लिए बिल्कुल शानदार है, जहां DOM में नए तत्वों को गतिशील रूप से बनाया और / या हटाया जाता है। ईवेंट प्रतिनिधिमंडल के साथ, ईवेंट बाइंडिंग की संख्या को एक आम अभिभावक तत्व के पास ले जाने से बहुत कम किया जा सकता है, और कोड जो गतिशील रूप से मक्खी पर नए तत्वों का निर्माण करता है, उनके ईवेंट हैंडलर को बांधने के तर्क से अलग किया जा सकता है।

इवेंट डेलिगेशन का एक और लाभ यह है कि इवेंट श्रोताओं द्वारा उपयोग किए जाने वाले कुल मेमोरी फ़ुटप्रिंट नीचे चले जाते हैं (चूंकि इवेंट बाइंडिंग की संख्या कम हो जाती है)। यह छोटे पृष्ठों के लिए बहुत अंतर नहीं कर सकता है जो अक्सर अनलोड करते हैं (यानी उपयोगकर्ता अक्सर विभिन्न पृष्ठों पर नेविगेट करते हैं)। लेकिन लंबे समय तक चलने वाले अनुप्रयोगों के लिए यह महत्वपूर्ण हो सकता है। कुछ वास्तव में मुश्किल-से-डाउन-डाउन स्थितियां हैं जब डोम से हटाए गए तत्व अभी भी मेमोरी का दावा करते हैं (अर्थात वे रिसाव करते हैं), और अक्सर यह लीक हुई मेमोरी एक इवेंट बाइंडिंग से बंधा होता है। इवेंट डेलिगेशन के साथ, आप अपने ईवेंट श्रोताओं (श्रोता के पूर्वज होने के बाद से) को भूल जाने के जोखिम के बिना बाल तत्वों को नष्ट करने के लिए स्वतंत्र हैं। इस प्रकार की मेमोरी लीक्स को तब समाहित किया जा सकता है (यदि समाप्त नहीं किया गया, जो कभी-कभी करने के लिए कठिन होता है। IE मैं आपको देख रहा हूं)।

यहाँ घटना प्रतिनिधि के कुछ बेहतर ठोस कोड उदाहरण हैं:


मुझे आपके तीसरे लिंक को खोलने के लिए मना किया गया है, बिना किसी जावास्क्रिप्ट लाइब्रेरी के इवेंट डेलिगेशन और आपके आखिरी लिंक के लिए +1
Bugwheels94

नमस्कार, एक महान स्पष्टीकरण के लिए धन्यवाद। मैं अभी भी एक निश्चित विवरण के बारे में उलझन में हूं: हालांकि मैं जिस तरह से DOM ट्री इवेंट फ्लो को समझता हूं (जैसा कि 3.1 में देखा जा सकता है । ईवेंट प्रेषण और DOM इवेंट फ्लो ) इवेंट ऑब्जेक्ट तब तक प्रचारित करता है जब तक कि वह लक्ष्य तत्व तक नहीं पहुंचता है तब बुलबुले उठते हैं। यदि यह नोड के बाल तत्वों तक पहुंच सकता है यदि इस नोड के माता-पिता प्रश्न में घटना लक्ष्य हैं? उदाहरण के लिए, <li>जब यह घटना रुक जानी चाहिए तो प्रचार कैसे हो सकता है <ul>? यदि मेरा प्रश्न अभी भी अस्पष्ट है या मुझे अलग से एक सूत्र की आवश्यकता है, तो मुझे प्रसन्नता होगी।
ऐटोस

@ एटोस: > यदि यह नोड का माता-पिता प्रश्न में घटना का लक्ष्य है तो यह नोड के बच्चे के तत्वों तक कैसे पहुंच सकता है? जैसा कि मैंने समझा, यह नहीं हो सकता। घटना लक्ष्य के माता-पिता के चरण 1 (कैप्चरिंग) को पूरा करती है, लक्ष्य पर चरण 2 (लक्ष्य) में प्रवेश करती है, फिर लक्ष्य के माता-पिता पर शुरू होने वाले चरण 3 (बुदबुदाहट) में प्रवेश करती है। कहीं यह लक्ष्य के एक बच्चे तक नहीं पहुंचता है।
वर्धमान ताजा

@ ताजा ताजा अच्छी तरह से तब घटना बच्चे के नोड पर कैसे लागू होती है अगर यह कभी नहीं पहुंचती है?
ऐटोस

1
वाकई शानदार जवाब। प्रासंगिक तथ्यों के साथ घटना प्रतिनिधिमंडल को समझाने के लिए धन्यवाद। धन्यवाद!
क्षितिज तिवारी

30

इवेंट डेलिगेशन आपको ईवेंट श्रोताओं को विशिष्ट नोड्स में जोड़ने से बचने की अनुमति देता है; इसके बजाय, इवेंट श्रोता को एक माता-पिता में जोड़ा जाता है। वह घटना श्रोता बाल तत्वों पर एक मैच खोजने के लिए बुदबुदाती घटनाओं का विश्लेषण करता है।

जावास्क्रिप्ट उदाहरण:

मान लें कि हमारे पास कई बच्चे तत्वों के साथ एक माता-पिता उल तत्व है:

<ul id="parent-list">
<li id="post-1">Item 1</li>
<li id="post-2">Item 2</li>
<li id="post-3">Item 3</li>
<li id="post-4">Item 4</li>
<li id="post-5">Item 5</li>
<li id="post-6">Item 6</li>

यह भी कहते हैं कि प्रत्येक बाल तत्व पर क्लिक करने पर कुछ होने की जरूरत है। आप प्रत्येक व्यक्तिगत LI तत्व में एक अलग ईवेंट श्रोता जोड़ सकते हैं, लेकिन क्या होगा यदि LI तत्वों को अक्सर सूची से जोड़ा और हटाया जाए? ईवेंट श्रोताओं को जोड़ना और निकालना एक बुरा सपना होगा, खासकर अगर आपके ऐप के भीतर अलग-अलग जगहों पर जोड़ और हटाना कोड है। माता-पिता उल तत्व के लिए एक घटना श्रोता को जोड़ने के लिए बेहतर समाधान है। लेकिन अगर आप इवेंट श्रोता को माता-पिता से जोड़ते हैं, तो आप कैसे जानेंगे कि किस तत्व पर क्लिक किया गया?

सरल: जब घटना उल तत्व तक जाती है, तो आप वास्तविक क्लिक किए गए नोड का संदर्भ प्राप्त करने के लिए ईवेंट ऑब्जेक्ट की लक्ष्य संपत्ति की जांच करते हैं। यहाँ एक बहुत ही मूल जावास्क्रिप्ट स्निपेट है जो घटना के प्रतिनिधिमंडल को दिखाता है:

// Get the element, add a click listener...
document.getElementById("parent-list").addEventListener("click", function(e) {
// e.target is the clicked element!
// If it was a list item
if(e.target && e.target.nodeName == "LI") {
    // List item found!  Output the ID!
    console.log("List item ", e.target.id.replace("post-"), " was clicked!");
       }
 });

मूल तत्व में एक क्लिक ईवेंट श्रोता जोड़कर प्रारंभ करें। जब ईवेंट श्रोता ट्रिगर हो जाता है, तो यह सुनिश्चित करने के लिए कि यह किस प्रकार का तत्व है, यह सुनिश्चित करने के लिए ईवेंट तत्व की जांच करें। यदि यह एक एलआई तत्व है, बूम: हमारे पास वह है जो हमें चाहिए! यदि यह ऐसा तत्व नहीं है जो हम चाहते हैं, तो घटना को अनदेखा किया जा सकता है। यह उदाहरण बहुत सरल है - उल और एलआई एक सीधे-आगे की तुलना है। चलो कुछ और कठिन प्रयास करें। चलो कई बच्चों के साथ एक माता-पिता DIV है, लेकिन हम सभी के बारे में परवाह है एक वर्ग सीएसएस वर्ग के साथ एक टैग है:

  // Get the parent DIV, add click listener...
  document.getElementById("myDiv").addEventListener("click",function(e) {
// e.target was the clicked element
if(e.target && e.target.nodeName == "A") {
    // Get the CSS classes
    var classes = e.target.className.split(" ");
    // Search for the CSS class!
    if(classes) {
        // For every CSS class the element has...
        for(var x = 0; x < classes.length; x++) {
            // If it has the CSS class we want...
            if(classes[x] == "classA") {
                // Bingo!
                console.log("Anchor element clicked!");
                // Now do something here....
            }
        }
    }

  }
});

http://davidwalsh.name/event-delegate


1
सुझाए गए ट्वीक: अंतिम उदाहरण के बजाय e.classList.contains () का उपयोग करें: developer.mozilla.org/en-US/docs/Web/API/Element/classList
nc।

7

डोम घटना प्रतिनिधिमंडल कंप्यूटर विज्ञान परिभाषा से कुछ अलग है।

यह तालिका तत्वों की तरह कई तत्वों से बुदबुदाती घटनाओं को संभालने के लिए संदर्भित करता है, तालिका की तरह एक मूल वस्तु से। यह कोड को सरल रख सकता है, विशेष रूप से तत्वों को जोड़ने या हटाने के दौरान, और कुछ मेमोरी को बचाता है।


6

प्रतिनिधिमंडल एक ऐसी तकनीक है जहां एक वस्तु बाहर के लिए कुछ व्यवहार को व्यक्त करती है लेकिन वास्तव में उस व्यवहार को किसी संबद्ध वस्तु पर लागू करने की जिम्मेदारी सौंपती है। यह पहली बार प्रॉक्सी पैटर्न के समान लगता है, लेकिन यह बहुत अलग उद्देश्य प्रदान करता है। प्रतिनिधिमंडल एक अमूर्त तंत्र है जो वस्तु (विधि) व्यवहार को केंद्रीकृत करता है।

आम तौर पर बोली जाती है: विरासत के विकल्प के रूप में प्रतिनिधिमंडल का उपयोग करें। वंशानुक्रम एक अच्छी रणनीति है, जब माता-पिता और बच्चे की वस्तु के बीच घनिष्ठ संबंध होता है, हालांकि, वंशानुक्रम जोड़े बहुत बारीकी से वस्तुओं का निर्माण करते हैं। अक्सर, वर्गों के बीच संबंधों को व्यक्त करने के लिए प्रतिनिधिमंडल अधिक लचीला तरीका है।

इस पैटर्न को "प्रॉक्सी चेन" के रूप में भी जाना जाता है। कई अन्य डिजाइन पैटर्न प्रतिनिधिमंडल का उपयोग करते हैं - राज्य, रणनीति और आगंतुक पैटर्न इस पर निर्भर करते हैं।


अच्छे खर्च। <Ul> के उदाहरण में, कई <li> बच्चों के साथ, जाहिरा तौर पर <li> वे हैं जो क्लिक लॉजिक को संभालते हैं, लेकिन ऐसा नहीं है क्योंकि वे इस तर्क को "<ul>
जुन्मा मेनेंडेज़

6

प्रतिनिधिमंडल की अवधारणा

यदि एक माता-पिता के अंदर कई तत्व हैं, और आप उनमें से घटनाओं को संभालना चाहते हैं - तो प्रत्येक तत्व को हैंडलर बांधें नहीं। इसके बजाय, एकल हैंडलर को उनके माता-पिता से बांधें, और बच्चे को event.target से प्राप्त करें। यह साइट इवेंट डेलिगेशन को लागू करने के तरीके के बारे में उपयोगी जानकारी प्रदान करती है। http://javascript.info/tutorial/event-delegation


6

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

उदाहरण के लिए, मान लीजिए कि आप किसी बड़ी तालिका की किसी तालिका सेल पर क्लिक करना चाहते हैं। आप कर सकते थे प्रत्येक कक्ष के लिए क्लिक करें हैंडलर सेट अप हुक करने एक पाश लिखने ... या आप तालिका और उपयोग घटना प्रतिनिधिमंडल पर एक क्लिक के हैंडलर यह केवल तालिका सेल के लिए गति प्रदान करने और तालिका हेडर, या एक के भीतर खाली स्थान के ऊपर हुक सकता है (नहीं कोशिकाओं के आसपास पंक्ति, आदि)।

यह तब भी उपयोगी है जब आप कंटेनर से तत्वों को जोड़ने और हटाने जा रहे हैं, क्योंकि आपको उन तत्वों पर ईवेंट हैंडलर जोड़ने और हटाने के बारे में चिंता करने की आवश्यकता नहीं है; बस कंटेनर पर ईवेंट को हुक करें और जब यह बुलबुले हो तो ईवेंट को संभालें।

यहाँ एक सरल उदाहरण है (यह इनलाइन स्पष्टीकरण के लिए जानबूझकर क्रिया करना है): tdकंटेनर तालिका में किसी भी तत्व पर एक क्लिक को हैंडल करना:

// Handle the event on the container
document.getElementById("container").addEventListener("click", function(event) {
    // Find out if the event targeted or bubbled through a `td` en route to this container element
    var element = event.target;
    var target;
    while (element && !target) {
        if (element.matches("td")) {
            // Found a `td` within the container!
            target = element;
        } else {
            // Not found
            if (element === this) {
                // We've reached the container, stop
                element = null;
            } else {
                // Go to the next parent in the ancestry
                element = element.parentNode;
            }
        }
    }
    if (target) {
        console.log("You clicked a td: " + target.textContent);
    } else {
        console.log("That wasn't a td in the container table");
    }
});
table {
    border-collapse: collapse;
    border: 1px solid #ddd;
}
th, td {
    padding: 4px;
    border: 1px solid #ddd;
    font-weight: normal;
}
th.rowheader {
    text-align: left;
}
td {
    cursor: pointer;
}
<table id="container">
    <thead>
        <tr>
            <th>Language</th>
            <th>1</th>
            <th>2</th>
            <th>3</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <th class="rowheader">English</th>
            <td>one</td>
            <td>two</td>
            <td>three</td>
        </tr>
        <tr>
            <th class="rowheader">Español</th>
            <td>uno</td>
            <td>dos</td>
            <td>tres</td>
        </tr>
        <tr>
            <th class="rowheader">Italiano</th>
            <td>uno</td>
            <td>due</td>
            <td>tre</td>
        </tr>
    </tbody>
</table>

उस के विवरण में जाने से पहले, आइए हम खुद को याद दिलाएं कि डोम ईवेंट कैसे काम करते हैं।

DOM इवेंट्स को डॉक्यूमेंट से टारगेट एलिमेंट ( कैप्चरिंग फेज) में भेजा जाता है , और फिर टार्गेट एलिमेंट से डॉक्यूमेंट ( बबलिंग फेज) पर बबल दिया जाता है । पुराने DOM3 ईवेंट स्पेक (अब सुपरकंडेड , लेकिन ग्राफिक का अभी भी मान्य है) में यह ग्राफिक इसे वास्तव में अच्छी तरह दिखाता है:

यहां छवि विवरण दर्ज करें

नहीं सभी घटनाओं बुलबुला, लेकिन ज्यादातर करते हैं, सहित click

ऊपर दिए गए कोड उदाहरण में टिप्पणियां बताती हैं कि यह कैसे काम करता है। matchesयह देखने के लिए जांचें कि क्या कोई तत्व CSS चयनकर्ता से मेल खाता है, लेकिन निश्चित रूप से आप यह जांच सकते हैं कि क्या कोई अन्य तरीके से आपके मापदंड से मेल खाता है या नहीं, यदि आप CSS चयनकर्ता का उपयोग नहीं करना चाहते हैं।

उस कोड को अलग-अलग चरणों को मौखिक रूप से कॉल करने के लिए लिखा जाता है, लेकिन अस्पष्ट-आधुनिक ब्राउज़रों (और IE पर भी यदि आप पॉलीफ़िल का उपयोग करते हैं), तो आप उपयोग कर सकते हैं closestऔर containsलूप के बजाय:

var target = event.target.closest("td");
    console.log("You clicked a td: " + target.textContent);
} else {
    console.log("That wasn't a td in the container table");
}

लाइव उदाहरण:

closestउस तत्व को चेक करता है जिस पर आप यह देखने के लिए कहते हैं कि क्या यह दिए गए CSS चयनकर्ता से मेल खाता है और यदि यह ऐसा करता है, तो उसी तत्व को लौटाता है; यदि नहीं, तो यह देखने के लिए कि यह मेल खाता है, और यदि ऐसा है, तो माता-पिता को लौटाता है; यदि नहीं, तो यह माता-पिता के माता-पिता आदि की जांच करता है, इसलिए यह पूर्वजों की सूची में "निकटतम" तत्व पाता है जो चयनकर्ता से मेल खाता है। चूंकि वह कंटेनर तत्व से आगे जा सकता है, इसलिए ऊपर दिया गया कोड containsयह जांचने के लिए उपयोग करता है कि यदि कोई मेल खाने वाला तत्व मिला है, तो वह कंटेनर के भीतर है - चूंकि कंटेनर पर ईवेंट को हुक करके, आपने संकेत दिया है कि आप केवल उस कंटेनर के भीतर तत्वों को हैंडल करना चाहते हैं ।

हमारे टेबल उदाहरण पर वापस जा रहे हैं, इसका मतलब है कि यदि आपके पास टेबल सेल के भीतर एक टेबल है, तो यह टेबल सेल वाले टेबल से मेल नहीं खाएगा:


3

यह मूल रूप से है कि संघ तत्व से कैसे बना है। .clickवर्तमान DOM पर लागू होता है, जबकि .on(डेलिगेशन का उपयोग करते हुए) इवेंट एसोसिएशन के बाद DOM में जोड़े गए नए तत्वों के लिए मान्य रहेगा।

जो उपयोग करने के लिए बेहतर है, मैं कहूंगा कि यह मामले पर निर्भर करता है।

उदाहरण:

<ul id="todo">
   <li>Do 1</li>
   <li>Do 2</li>
   <li>Do 3</li>
   <li>Do 4</li>
</ul>

क्लिक करें घटना:

$("li").click(function () {
   $(this).remove ();
});

घटना .on:

$("#todo").on("click", "li", function () {
   $(this).remove();
});

ध्यान दें कि मैंने चयनकर्ता को .on में अलग कर दिया है। मैं समझाता हूँ क्यों।

मान लें कि इस संगति के बाद, हम निम्नलिखित कार्य करें:

$("#todo").append("<li>Do 5</li>");

यही वह जगह है जहां आप अंतर देखेंगे।

यदि ईवेंट .click के माध्यम से संबद्ध था, तो टास्क 5 क्लिक इवेंट का पालन नहीं करेगा, और इसलिए इसे हटाया नहीं जाएगा।

यदि यह .on के माध्यम से जुड़ा हुआ था, चयनकर्ता अलग के साथ, यह पालन करेगा।


2

इवेंट डेलिगेशन को समझने के लिए पहले हमें यह जानना होगा कि हमें इवेंट डेलिगेशन की आवश्यकता क्यों और कब पड़ती है।

कई मामले हो सकते हैं लेकिन आइए घटना के प्रतिनिधिमंडल के लिए दो बड़े उपयोग के मामलों पर चर्चा करें। 1. पहला मामला तब होता है जब हमारे पास बहुत सारे बाल तत्वों के साथ एक तत्व होता है जिसमें हम रुचि रखते हैं। इस मामले में, इन सभी बाल तत्वों में एक घटना हैंडलर जोड़ने के बजाय, हम इसे मूल तत्व में जोड़ते हैं और फिर निर्धारित करते हैं। जिस पर बाल तत्व ने घटना को अंजाम दिया।

2. इवेंट डेलिगेशन के लिए दूसरा उपयोग मामला तब होता है जब हम एक ऐसा इवेंट हैंडलर चाहते हैं जो किसी ऐसे तत्व से जुड़ा हो जो अभी तक DOM में नहीं है जब हमारा पेज लोड होता है। यह निश्चित रूप से, क्योंकि हम एक घटना हैंडलर को हमारे पेज पर नहीं जोड़ सकते हैं, इसलिए कि हम कोडिंग कर रहे हैं।

मान लें कि जब आप अपना पृष्ठ लोड करते हैं, तो आपके पास DOM में 0, 10, या 100 आइटमों की एक सूची होती है, और अधिक आइटम सूची में जोड़ने के लिए आपके हाथ में प्रतीक्षा कर रहे हैं। इसलिए भविष्य के तत्वों के लिए कोई इवेंट हैंडलर संलग्न करने का कोई तरीका नहीं है या उन तत्वों को DOM में अभी तक नहीं जोड़ा गया है, और इसमें बहुत सारे आइटम भी हो सकते हैं, इसलिए प्रत्येक ईवेंट हैंडलर को एक से जोड़ना उपयोगी नहीं होगा उनमें से।

इवेंट डेलिगेशन

सब ठीक है, इसलिए घटना के प्रतिनिधिमंडल के बारे में बात करने के लिए, पहली अवधारणा जिसे हमें वास्तव में बात करने की आवश्यकता है, वह घटना बुदबुदाती है।

ईवेंट बबलिंग: ईवेंट बबलिंग का अर्थ है कि जब किसी ईवेंट को किसी DOM तत्व पर निकाल दिया जाता है या ट्रिगर कर दिया जाता है, उदाहरण के लिए हमारे बटन पर यहां क्लिक करके bellow इमेज पर क्लिक किया जाता है, तब सटीक इवेंट भी सभी पेरेंट तत्वों पर चालू हो जाता है।

यहां छवि विवरण दर्ज करें

घटना को पहले बटन पर निकाल दिया जाता है, लेकिन फिर इसे एक बार में सभी मूल तत्वों पर निकाल दिया जाएगा, इसलिए यह पैराग्राफ पर मुख्य तत्व को आग लगा देगा और वास्तव में डोम ट्री में सभी तरह से HTML तत्व तक जो रूट है। तो हम कहते हैं कि ईवेंट डोम ट्री के अंदर उबलता है, और इसीलिए इसे बुबलिंग कहा जाता है।

1 2 3 4

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

यह हमें घटना के प्रतिनिधिमंडल के लिए लाता है क्योंकि यदि ईवेंट DOM ट्री में बबल करता है, और यदि हमें पता है कि ईवेंट को कहां से निकाल दिया गया है, तो हम किसी ईवेंट हैंडलर को मूल तत्व में संलग्न कर सकते हैं और ईवेंट के बुलबुले बनने का इंतजार कर सकते हैं और हम कर सकते हैं उसके बाद हम जो कुछ भी करना चाहते हैं अपने लक्ष्य तत्व के साथ करते हैं। इस तकनीक को इवेंट डेलिगेशन कहा जाता है। इस उदाहरण में, हम ईवेंट हैंडलर को मुख्य तत्व में जोड़ सकते हैं।

ठीक है, इसलिए, फिर से, घटना के प्रतिनिधिमंडल को उस मूल तत्व पर घटना हैंडलर को स्थापित नहीं करना है जिसे हम रुचि रखते हैं, लेकिन इसे मूल तत्व में संलग्न करने के लिए और, मूल रूप से, इस घटना को पकड़ते हैं क्योंकि यह बुलबुले बनाता है। फिर हम उस तत्व पर कार्य कर सकते हैं जिसे हम लक्ष्य तत्व संपत्ति का उपयोग करने में रुचि रखते हैं।

उदाहरण: अब मान लें कि हमारे पेज में दो सूची आइटम हैं, उन सूची में आइटम जोड़ने के बाद प्रोग्रामेटिक रूप से हम उनमें से एक या अधिक आइटम हटाना चाहते हैं। घटना प्रतिनिधिमंडल का उपयोग करते हुए हम आसानी से अपने उद्देश्य को प्राप्त कर सकते हैं।

<div class="body">
    <div class="top">

    </div>
    <div class="bottom">
        <div class="other">
            <!-- other bottom elements -->
        </div>
        <div class="container clearfix">
            <div class="income">
                <h2 class="icome__title">Income</h2>
                <div class="income__list">
                    <!-- list items -->
                </div>
            </div>
            <div class="expenses">
                <h2 class="expenses__title">Expenses</h2>
                <div class="expenses__list">
                    <!-- list items -->
                </div>
            </div>
        </div>
    </div>
</div>

उन सूची में आइटम जोड़ना:

const DOMstrings={
        type:{
            income:'inc',
            expense:'exp'
        },
        incomeContainer:'.income__list',
        expenseContainer:'.expenses__list',
        container:'.container'
   }


var addListItem = function(obj, type){
        //create html string with the place holder
        var html, element;
        if(type===DOMstrings.type.income){
            element = DOMstrings.incomeContainer
            html = `<div class="item clearfix" id="inc-${obj.id}">
            <div class="item__description">${obj.descripiton}</div>
            <div class="right clearfix">
                <div class="item__value">${obj.value}</div>
                <div class="item__delete">
                    <button class="item__delete--btn"><i class="ion-ios-close-outline"></i></button>
                </div>
            </div>
        </div>`
        }else if (type ===DOMstrings.type.expense){
            element=DOMstrings.expenseContainer;
            html = ` <div class="item clearfix" id="exp-${obj.id}">
            <div class="item__description">${obj.descripiton}</div>
            <div class="right clearfix">
                <div class="item__value">${obj.value}</div>
                <div class="item__percentage">21%</div>
                <div class="item__delete">
                    <button class="item__delete--btn"><i class="ion-ios-close-outline"></i></button>
                </div>
            </div>
        </div>`
        }
        var htmlObject = document.createElement('div');
        htmlObject.innerHTML=html;
        document.querySelector(element).insertAdjacentElement('beforeend', htmlObject);
    }

आइटम हटाएं:

var ctrlDeleteItem = function(event){
       // var itemId = event.target.parentNode.parentNode.parentNode.parentNode.id;
        var parent = event.target.parentNode;
        var splitId, type, ID;
        while(parent.id===""){
            parent = parent.parentNode
        }
        if(parent.id){
            splitId = parent.id.split('-');
            type = splitId[0];
            ID=parseInt(splitId[1]);
        }

        deleteItem(type, ID);
        deleteListItem(parent.id);
 }

 var deleteItem = function(type, id){
        var ids, index;
        ids = data.allItems[type].map(function(current){
            return current.id;
        });
        index = ids.indexOf(id);
        if(index>-1){
            data.allItems[type].splice(index,1);
        }
    }

  var deleteListItem = function(selectorID){
        var element = document.getElementById(selectorID);
        element.parentNode.removeChild(element);
    }

1

C # में एक प्रतिनिधि C या C ++ में फ़ंक्शन पॉइंटर के समान है। एक प्रतिनिधि का उपयोग करना प्रोग्रामर को एक प्रतिनिधि ऑब्जेक्ट के अंदर एक विधि के संदर्भ को एनक्रिप्ट करने की अनुमति देता है। प्रतिनिधि ऑब्जेक्ट तब कोड के लिए पारित किया जा सकता है जो संदर्भित विधि को कॉल कर सकता है, बिना संकलन समय पर पता किए कि किस विधि को लागू किया जाएगा।

यह लिंक देखें -> http://www.akadia.com/services/dotnet_delegates_and_events.html


5
मैं इसे वोट नहीं करने जा रहा हूँ, क्योंकि यह शायद मूल प्रश्न का एक सही उत्तर था, लेकिन सवाल अब विशेष रूप से DOM इवेंट डेलिगेशन और जावास्क्रिप्ट के बारे में है
iandotkelly

1

ईवेंट प्रतिनिधिमंडल जावास्क्रिप्ट घटनाओं की दो अक्सर अनदेखी सुविधाओं का उपयोग करता है: ईवेंट बुदबुदाहट और लक्ष्य तत्व। जब एक घटना एक तत्व पर ट्रिगर होती है, उदाहरण के लिए एक बटन पर एक माउस क्लिक, उसी घटना को उस तत्व के सभी पूर्वजों पर भी ट्रिगर किया जाता है। । इस प्रक्रिया को ईवेंट बबलिंग के रूप में जाना जाता है; घटना मूल तत्व से डोम ट्री के शीर्ष तक बुलबुले बनती है।

10 स्तंभों और 100 पंक्तियों के साथ एक HTML तालिका की कल्पना करें, जिसमें आप चाहते हैं कि जब उपयोगकर्ता किसी तालिका कक्ष पर क्लिक करे। उदाहरण के लिए, मुझे एक बार क्लिक करने पर उस आकार की तालिका के प्रत्येक सेल को संपादन योग्य बनाना था। 1000 कोशिकाओं में से प्रत्येक में इवेंट हैंडलर जोड़ना एक बड़ी प्रदर्शन समस्या होगी और, संभवतः, ब्राउज़र-क्रैश मेमोरी लीक का एक स्रोत। इसके बजाय, इवेंट डेलिगेशन का उपयोग करते हुए, आप तालिका तत्व में केवल एक ईवेंट हैंडलर जोड़ेंगे, क्लिक इवेंट को इंटरसेप्ट करेंगे और यह निर्धारित करेंगे कि किस सेल पर क्लिक किया गया था।


0
इवेंट डेलिगेशन

किसी इवेंट एलिमेंट को किसी पैरेंट एलिमेंट से अटैच करें, जो किसी चाइल्ड एलिमेंट पर होने वाली घटना के समय फायर करता है।

घटना का प्रचार

जब कोई घटना बच्चे के माता-पिता के तत्व से डोम के माध्यम से चलती है, तो उसे इवेंट प्रचार कहा जाता है , क्योंकि ईवेंट प्रचार करता है, या डोम के माध्यम से आगे बढ़ता है।

इस उदाहरण में, बटन से कोई ईवेंट (ऑनक्लिक) पेरेंट पैराग्राफ में पास हो जाता है।

$(document).ready(function() {

    $(".spoiler span").hide();

    /* add event onclick on parent (.spoiler) and delegate its event to child (button) */
    $(".spoiler").on( "click", "button", function() {
    
        $(".spoiler button").hide();    
    
        $(".spoiler span").show();
    
    } );

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

<p class="spoiler">
    <span>Hello World</span>
    <button>Click Me</button>
</p>

Codepen

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