प्रत्यक्ष बनाम प्रत्यायोजित - jQuery। ()


159

मैं jQuery () विधि का उपयोग करके प्रत्यक्ष और प्रत्यायोजित इवेंट हैंडलर के बीच इस विशेष अंतर को समझने की कोशिश कर रहा हूं । विशेष रूप से, इस पैराग्राफ में अंतिम वाक्य:

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

"किसी भी तत्व के लिए हैंडलर चलाता है" इसका क्या मतलब है? मैंने अवधारणा के साथ प्रयोग करने के लिए एक परीक्षण पृष्ठ बनाया । लेकिन दोनों निर्माणों में समान व्यवहार होता है:

$("div#target span.green").on("click", function() {
   alert($(this).attr("class") + " is clicked");
});

या,

$("div#target").on("click", "span.green", function() {
   alert($(this).attr("class") + " is clicked");
});

हो सकता है कि कोई व्यक्ति इस बिंदु को स्पष्ट करने के लिए एक अलग उदाहरण का उल्लेख कर सकता है? धन्यवाद।


7
सभी इच्छुक लोगों के लिए: jsperf.com/jquery-fn-on-delegate-vs-direct
dgo

1
@ केविनव्हीलर मैंने नीचे आपकी फिडेल पर टिप्पणी की थी , लेकिन यहां अनिवार्य रूप से इसे सही ढंग से सेट नहीं किया गया है (आप मूल तत्व के लिए बाध्य हैं, और बच्चों के लिए प्रतिनिधिमंडल का इरादा है)। आपके प्रश्न का उत्तर देने के लिए इसका मतलब यह है कि प्रत्यायोजित हैंडलर नए जोड़े गए तत्वों से मेल खाएगा, जहां प्रतिनिधि के बिना कोई भी नहीं होगा। प्रतिनिधिमंडल का लाभ है कि ब्राउज़र में कम घटनाओं को कम करने से ऐप के लिए मेमोरी की खपत कम हो जाती है, हालांकि ट्रेडऑफ़ यह एक क्लिक (न्यूनतम) संसाधित करने का समय बढ़ाता है। यदि आप एक खेल बना रहे हैं तो प्रतिनिधि मत बनो।
vipero07

1
आपके द्वारा संदर्भित "परीक्षण पृष्ठ" काम नहीं कर रहा है।
Jaime Montoya

जवाबों:


373

केस 1 (प्रत्यक्ष):

$("div#target span.green").on("click", function() {...});

== अरे! मैं चाहता हूँ कि हर स्पैन.ग्रीन इन डिव # टार्गेट टू लिसन: जब आप पर क्लिक करें, एक्स करें।

केस 2 (प्रत्यायोजित):

$("div#target").on("click", "span.green", function() {...});

== हे, दिव्य # लक्ष्य! जब आपके किसी भी बाल तत्व को "स्पैन.ग्रीन" पर क्लिक किया जाता है, तो उनके साथ एक्स करें।

दूसरे शब्दों में...

मामले 1 में, उन स्पानों में से प्रत्येक को व्यक्तिगत रूप से निर्देश दिए गए हैं। यदि नए स्पैन बनते हैं, तो उन्होंने निर्देश नहीं सुना होगा और क्लिक का जवाब नहीं देंगे। प्रत्येक स्पैन अपनी घटनाओं के लिए सीधे जिम्मेदार है

मामले 2 में, केवल कंटेनर को निर्देश दिया गया है; इसके लिए क्लिक पर ध्यान देने योग्य है अपने बाल तत्वों । घटनाओं को पकड़ने का काम सौंप दिया गया है । इसका मतलब यह भी है कि भविष्य में बनाए जाने वाले बाल तत्वों के लिए निर्देश दिया जाएगा।


45
यह एक महान स्पष्टीकरण है, और एक ऐसे मुद्दे पर स्पष्टता लाया है जिसे मैंने लंबे समय तक समझने से इनकार कर दिया है। धन्यवाद!
डी जी ओ

3
तो क्यों on()दो तर्कों की अनुमति देता है जब कि उपयोग के रूप में बहुत अधिक समान होगा click()?
निप्पोनेस

5
.on () एक सामान्य उद्देश्य एपीआई है जो किसी भी प्रकार के ईवेंट को संभाल सकता है, जिसमें कई अलग-अलग इवेंट्स शामिल हैं (आप उस पहले स्ट्रिंग में कई ईवेंट नाम डाल सकते हैं।) .click () उस पहले फॉर्म के लिए सिर्फ एक शॉर्टहैंड है।
N3dst4

1
@newbie, @ N3dst4: e.targetक्लिक इवेंट का प्रारंभिक लक्ष्य होगा (बच्चे होने पर बच्चा नोड हो सकता है span.green)। हैंडलर के अंदर से, आपको thisसंदर्भ का उपयोग करना चाहिए । देखिए यह फील
LeGEC

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

6

पहला तरीका, $("div#target span.green").on()एक क्लिक हैंडलर को सीधे उस स्पान से जोड़ता है, जो उस समय चयनकर्ता से मेल खाता है जिसे कोड निष्पादित किया गया है। इसका मतलब यह है कि अगर अन्य स्पैन को बाद में जोड़ा जाता है (या उनकी क्लास मैच के लिए बदल गई है) तो वे चूक गए हैं और उनके पास क्लिक हैंडलर नहीं होगा। इसका अर्थ यह भी है कि यदि आप बाद में "हरा" वर्ग को स्पैन में से किसी एक पर क्लिक करते हैं तो उसका हैंडलर चलता रहेगा - jQuery इस बात का ध्यान नहीं रखता है कि हैंडलर को कैसे सौंपा गया है और यह देखने के लिए जांचें कि क्या चयनकर्ता अभी भी मेल खाता है।

दूसरा तरीका, $("div#target").on()उस मैच के लिए एक क्लिक हैंडलर को बांधता है (फिर से, यह उस पल में उस मैच के खिलाफ है), लेकिन जब div में कहीं एक क्लिक होता है तो हैंडलर फ़ंक्शन केवल तभी चलेगा जब क्लिक सिर्फ डिव में ही नहीं, बल्कि दूसरे पैरामीटर में चयनकर्ता से मेल खाते एक बच्चे के तत्व में .on(), "स्पैन.ग्रीन" हुआ। इस तरह से यह कोई फर्क नहीं पड़ता कि जब उन बच्चों को बनाया गया था, तो उन पर क्लिक करने के बाद भी हैंडलर चलेगा।

तो ऐसे पृष्ठ के लिए जो गतिशील रूप से अपनी सामग्री जोड़ या परिवर्तित नहीं कर रहा है, आपको दोनों विधियों के बीच अंतर दिखाई नहीं देगा। यदि आप गतिशील रूप से अतिरिक्त बाल तत्वों को जोड़ रहे हैं तो दूसरा वाक्यविन्यास का मतलब है कि आपको क्लिक हैंडलर को असाइन करने के बारे में चिंता करने की ज़रूरत नहीं है क्योंकि आपने पहले ही एक बार इसे माता-पिता पर कर दिया है।


5

N3dst4 की व्याख्या एकदम सही है। इसके आधार पर, हम यह मान सकते हैं कि सभी बाल तत्व शरीर के अंदर हैं, इसलिए हमें केवल इसका उपयोग करने की आवश्यकता है:

$('body').on('click', '.element', function(){
    alert('It works!')
});

यह प्रत्यक्ष या प्रतिनिधि घटना के साथ काम करता है।


2
jquery शरीर का उपयोग करने के खिलाफ सलाह देता है, क्योंकि यह धीमा है, क्योंकि स्क्रिप्ट को शरीर के अंदर सभी बच्चों की तलाश करनी होगी, जो कि ज्यादातर मामलों में होना चाहिए। तत्व के आवक मूल कंटेनर का उपयोग करना बेहतर (तेज) है।
मिकसॉफ्ट

1
Jquery ने लाइव मेथड को हटा दिया जो आप जैसा दिखा रहे थे वैसा ही कर रहे थे। यह प्रदर्शन कमजोर है और इसका उपयोग नहीं किया जाना चाहिए।
मैकीज सिकोरा

आधुनिक ब्राउज़रों में, $('body').on()प्रतिनिधिमंडल को कॉलबैक में .elementमूल के document.body.addEventHandler()साथ बिल्कुल वैसा ही व्यवहार करना चाहिए if (Event.target.className.matches(/\belement\b/))। यह $.proxyओवरहेड की वजह से jquery में थोड़ा धीमा हो सकता है लेकिन मुझे उस पर उद्धृत नहीं करना चाहिए।
काऊबर्ट

2

ओपी के लिए स्पर्शरेखा, लेकिन इस अवधारणा ने मुझे इस सुविधा के साथ भ्रम को दूर करने में मदद की है कि बाध्य तत्व चयनित तत्वों के माता-पिता होने चाहिए

  • बाउंड से तात्पर्य है कि क्या बचा है .on
  • चयनित के 2 तर्क को संदर्भित करता है .on()

प्रतिनिधि काम नहीं करता है .find (), बाध्य तत्वों के एक सबसेट का चयन। चयनकर्ता केवल सख्त बाल तत्वों पर लागू होता है।

$("span.green").on("click", ...

से बहुत अलग है

$("span").on("click", ".green", ...

विशेष रूप से, "N3dst4 संकेत" भविष्य में बनाए गए तत्वों के साथ @ लाभ प्राप्त करने के लिए बाध्य तत्व एक स्थायी माता-पिता होना चाहिए । तब चयनित बच्चे आ सकते हैं और जा सकते हैं।

संपादित करें

प्रत्यायोजित क्यों .onकाम नहीं करता है की चेकलिस्ट

क्यों $('.bound').on('event', '.selected', some_function)काम नहीं कर सकते हैं मुश्किल कारण :

  1. बाध्य तत्व स्थायी नहीं है । इसे कॉल करने के बाद बनाया गया था.on()
  2. चयनित तत्व एक बाध्य तत्व का उचित बच्चा नहीं है । यह एक ही तत्व है।
  3. चयनित तत्व ने बुदबुदाहट को रोका किसी घटना को बुलाने वाले को.stopPropagation()

(कम गलत कारणों को स्वीकार करते हुए, जैसे कि एक गलत चयनकर्ता।)


1

मैंने प्रत्यक्ष घटनाओं और प्रत्यायोजित की तुलना के साथ एक पोस्ट को मिटा दिया। मैं शुद्ध js की तुलना करता हूं लेकिन इसका jquery के लिए वही अर्थ है जो केवल इसे एनकैप्सुलेट करता है।

निष्कर्ष यह है कि प्रत्यायोजित ईवेंट हैंडलिंग डायनेमिक DOM संरचना के लिए है जहाँ बाइंड किए गए तत्वों को बनाया जा सकता है, जबकि उपयोगकर्ता पेज के साथ इंटरैक्ट करता है (फिर दोबारा बाइंडिंग की आवश्यकता नहीं है), और डायरेक्ट ईवेंट हैंडलिंग स्थिर DOM तत्वों के लिए है, जब हम जानते हैं कि संरचना नहीं बदलेगी।

अधिक जानकारी और पूर्ण तुलना के लिए - http://maciejsikora.com/standard-events-vs-event-delegation/

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


यदि कई घटना संचालकों को संलग्न करना (उदाहरण के लिए, तालिका की प्रत्येक पंक्ति), तो कई प्रत्यक्ष संचालकों को संलग्न करने के बजाय एकल प्रतिनिधि हैंडलर का उपयोग करना बेहतर होता है। आप इसे मूल तथ्य से देख सकते हैं कि ईवेंट हैंडलर काउंट स्वयं एक प्रोफाइलिंग मीट्रिक है।
काउबर्ट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.