JQuery के `क्लिक`,` बाइंड`, `लाइव`,` डेलिगेट`, `ट्रिगर` और` ऑन` फ़ंक्शंस (एक उदाहरण के साथ) के बीच अंतर?


139

मैंने प्रत्येक फ़ंक्शन के दस्तावेज़ीकरण को पढ़ा है jQuery official website, लेकिन नीचे दिए गए कार्यों के बीच ऐसी तुलना लिस्टिंग नहीं है:

$().click(fn)
$().bind('click',fn)
$().live('click',fn)
$().delegate(selector, 'click', fn)
$().trigger('click') // UPDATED
$().on('click', selector ,fn); // more UPDATED

कृपया किसी भी संदर्भ लिंक से बचें।

उपरोक्त सभी कार्य कैसे कार्य करते हैं और किस स्थिति में प्राथमिकता दी जानी चाहिए?

नोट: यदि समान कार्यक्षमता या तंत्र के कोई अन्य कार्य हैं, तो कृपया विस्तृत करें।

अपडेट करें

मैंने एक $.triggerफंक्शन भी देखा है । क्या यह उपरोक्त कार्यों के समान काम करता है?

अधिक अद्यतन

अब v1.7.on में जोड़ा गया है और मुझे लगता है कि यह किसी भी तरह उपरोक्त सभी कार्यों की आवश्यकता को एक साथ कवर करता है।


3
@I PHP की तरह, कभी-कभी लोग चीजों को वोट देते हैं अगर उन्हें नहीं लगता कि यह एक ऐसा सवाल है जिसका जवाब मैनुअल से नहीं दिया जा सकता है या यह एक होमवर्क प्रश्न प्रतीत होता है। चिंता न करें, यदि वे इसे उपयोगी पाते हैं तो अन्य लोग इसे वोट करेंगे।
टाइपटोनरोर

@ टाइपनेयर - समर्थन के लिए धन्यवाद, मैं पहले से ही मैनुअल पढ़ता हूं और जब मुझे स्पष्ट अंतर समझ में नहीं आया, तो मैं यहां पोस्ट करता हूं।
diEcho

3
@ आई लाइक पीएचपी - सवाल को थोड़ा साफ करने के लिए संपादित किया ... यह अक्सर पूछा जाता है लेकिन इस तरह से शायद ही कभी, यह आसानी से एक मूल्यवान गूगल-सक्षम संसाधन हो सकता है। मैं सहमत हूं कि इस तरह से कुछ की विकी-ईश प्रविष्टि बहुत उपयोगी होगी, मुझे इसके चारों ओर भ्रम दिखाई देता है, विशेष रूप से .live()और .delegate()लगभग हर दिन, +1 पूरी तरह से वैध प्रश्न के लिए।
निक Craver

@Nick क्रेवर संपादन के लिए धन्यवाद, वास्तव में अंग्रेजी में खराब है (योग्य)। क्या कोई मौनल / संदर्भ है कि हम एक प्रश्न कैसे पोस्ट करते हैं SO। ओटी यह सिर्फ अनुभव से आया है
diEcho

@ PHP की तरह - यह दोनों का एक सा है, यहाँ SO के लिए एक बढ़िया ऑल-अराउंड FAQ है: meta.stackexchange.com/questions/7931 phrasing / comments के लिए, आप बस सीखना शुरू करते हैं कि क्या फिट बैठता है और सबसे अच्छा तरीका है अपने विचारों, कोड> किसी भी विवरण से अवगत कराएं, कभी-कभी सही कीवर्ड का उपयोग करके, उचित रूप से टैग करते हुए, बस अब आप यहाँ हैं कि मुझे लगता है कि लगता है, मुझे समय के साथ बहुत सारे पोस्टर में सुधार दिखाई दे रहा है। आपके संपादन के लिए, .trigger()बस इवेंट हैंडलर को आमंत्रित करता हूं ... मैं नीचे अपने उत्तर में एक विवरण जोड़ूंगा।
निक Craver

जवाबों:


162

इससे पहले कि आप इसे पढ़े, किसी दूसरे पृष्ठ की घटनाओं की इस सूची को खींच लें, एपीआई अपने आप में काफी सहायक है, और जो मैं नीचे चर्चा कर रहा हूं वह सब इस पृष्ठ से सीधे जुड़ा हुआ है

पहला, .click(function)वस्तुतः इसके लिए एक शॉर्टकट है .bind('click', function), वे समकक्ष हैं। एक हैंडलर को सीधे किसी तत्व से बांधते समय उनका उपयोग करें , जैसे:

$(document).click(function() {
  alert("You clicked somewhere in the page, it bubbled to document");
});

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

.live()और .delegate()इसी तरह से संबंधित हैं, .delegate()वास्तव में .live()आंतरिक रूप से उपयोग करते हैं, वे दोनों बुलबुले की घटनाओं के लिए सुनते हैं। यह नए और पुराने तत्वों के लिए काम करता है , वे उसी तरह से बुलबुले बनाते हैं। जब आपके तत्व बदल सकते हैं, तो आप इनका उपयोग करते हैं, जैसे नई पंक्तियाँ, सूची आइटम इत्यादि जोड़ना, यदि आपके पास कोई अभिभावक / सामान्य पूर्वज नहीं है जो पृष्ठ में रहेगा और किसी भी बिंदु पर प्रतिस्थापित नहीं किया जाएगा .live(), तो इस तरह का उपयोग करें:

$(".clickAlert").live('click', function() {
  alert("A click happened");
});

यदि फिर भी आपके पास कोई मूल तत्व है जो प्रतिस्थापित नहीं हो रहा है (इसलिए इसके ईवेंट हैंडलर अलविदा नहीं हैं) तो आपको इसे .delegate()इस तरह से संभालना चाहिए :

$("#commonParent").delegate('.clickAlert', 'click', function() {
  alert("A click happened, it was captured at #commonParent and this alert ran");
});

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

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


ट्रिगर - अद्यतन किए गए प्रश्न के लिए

2 मुख्य ईवेंट-हैंडलर ट्रिगरिंग फ़ंक्शन उपलब्ध हैं, वे एपीआई में एक ही "इवेंट हैंडलर अटैचमेंट" श्रेणी के अंतर्गत आते हैं, ये हैं .trigger()और .triggerHandler().trigger('eventName')आम घटनाओं के लिए अंतर्निहित कुछ शॉर्टकट हैं:

$().click(fn); //binds an event handler to the click event
$().click();   //fires all click event handlers for this element, in order bound

आप यहां इन शॉर्टकट सहित एक सूची देख सकते हैं

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

.triggerHandler()आमतौर पर एक अलग उद्देश्य के लिए, यहां आप केवल बाउंड हैंडलर को आग लगाने की कोशिश कर रहे हैं, यह मूल घटना को आग लगाने का कारण नहीं बनता है, उदाहरण के लिए एक फॉर्म सबमिट करना। यह DOM को बबल नहीं करता है, और यह चेनेबल नहीं है (यह उस ईवेंट रिटर्न के लिए अंतिम बाउंड इवेंट हैंडलर जो भी देता है)। उदाहरण के लिए यदि आप किसी focusघटना को ट्रिगर करना चाहते हैं, लेकिन वास्तव में ऑब्जेक्ट पर ध्यान केंद्रित नहीं करना चाहते हैं, तो आप चाहते हैं कि कोड आपको .focus(fn)चलाने के लिए बाध्य हो , यह ऐसा करेगा, जबकि .trigger()ऐसा करने के साथ-साथ वास्तव में तत्व और बुलबुले को ध्यान में रखना होगा ।

यहाँ एक वास्तविक दुनिया उदाहरण है:

$("form").submit(); //actually calling `.trigger('submit');`

यह किसी भी सबमिट हैंडलर को चलाएगा, उदाहरण के लिए jQuery सत्यापन प्लगइन , फिर सबमिट करने का प्रयास करें <form>। हालाँकि, यदि आप इसे केवल मान्य करना चाहते थे, क्योंकि यह एक submitइवेंट हैंडलर के माध्यम से तैयार किया गया <form>था, लेकिन बाद में सबमिट नहीं किया गया, तो आप .triggerHandler('submit')इस तरह का उपयोग कर सकते हैं :

$("form").triggerHandler('submit');

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


बहुत गहन। एक छोटा सुधार: triggerएक मूल घटना को आग नहीं देता है। मूल निवासी से मेरा मतलब है कि एक घटना fireEvent(IE) या dispatchEvent(w3c) के साथ सिम्युलेटेड ।
क्रिसेंट ताजा

@Crescent - कम अस्पष्ट होने के लिए अपडेट किया गया, मैं का मतलब है कि यह देशी ईवेंट सक्रिय कार्यों निम्न रूपों प्रस्तुत करने, लिंक की तरह, आदि ... उम्मीद है कि अद्यतन है स्पष्ट :)
निक Craver

@ जो भी मैं पढ़ रहा हूं, उससे लगता है कि यह आपकी पसंद है live() द्वारा मुझे दिए गए से अलग है: stackoverflow.com/questions/3981762/… क्या 'वेट' का उपयोग करते समय अभी भी एक चिंता है live()?
येलहुल

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

1
jQuery 1.7 में, लाइव () $ (दस्तावेज़) .on () के पक्ष में पदावनत किया गया है।
सिंक्रो

28

पहले दो बराबर हैं।

// The following two statements do the same thing:
$("blah").click( function() { alert( "Click!" ); } );
$("blah").bind( "click", function() { alert( "Click!" ); } ); 

दूसरा, हालांकि, एक ही समय में एक से अधिक घटनाओं को बांधने के लिए इस्तेमाल किया जा सकता है, कई स्थान-अलग इवेंट नामों को निर्दिष्ट करके:

$("blah").bind( "click mouseover mouseout", function() { alert( "Click! Or maybe mouse moved." ); } ); 

.liveविधि और अधिक रोचक है। निम्नलिखित उदाहरण पर विचार करें:

<a class="myLink">A link!</a>
<a id="another">Another link!</a>

<script>
    $("a.myLink").click( function() { alert( 'Click!' ); } );

    $("a#another").addClass( "myLink" );
</script>

स्क्रिप्ट निष्पादित होने की दूसरी पंक्ति के बाद, दूसरी कड़ी में "myLink" की CSS क्लास भी होगी। लेकिन इसमें ईवेंट हैंडलर नहीं होगा, क्योंकि ईवेंट संलग्न होने पर इसमें क्लास नहीं थी।

अब विचार करें कि आप इसे दूसरे तरीके से चाहते थे: हर बार जब पृष्ठ पर कहीं "myLink" श्रेणी का लिंक दिखाई देता है, तो आप चाहते हैं कि यह समान ईवेंट हैंडलर स्वचालित रूप से हो। जब आप किसी प्रकार की सूचियाँ या तालिकाएँ बनाते हैं, जहाँ आप पंक्तियों या कक्षों को गतिशील रूप से जोड़ते हैं, तो यह बहुत सामान्य है, लेकिन चाहते हैं कि सभी समान तरीके से व्यवहार करें। हर बार ईवेंट हैंडलर्स को नए सिरे से असाइन करने के सभी दर्द के बजाय, आप .liveविधि का उपयोग कर सकते हैं :

<a class="myLink">A link!</a>
<a id="another">Another link!</a>

<script>
    $("a.myLink").live( "click", function() { alert( 'Click!' ); } );

    $("a#another").addClass( "myLink" );
</script>

इस उदाहरण में, दूसरे लिंक को भी इवेंट हैंडलर मिलेगा जैसे ही उसे "myLink" क्लास मिलती है। जादू! :-)

बेशक, यह वह शाब्दिक नहीं है। जो .liveवास्तव में करता है वह हैंडलर को निर्दिष्ट तत्व से नहीं, बल्कि HTML ट्री ("बॉडी" तत्व) के मूल में संलग्न करता है। DHTML की घटनाओं में "बबलिंग अप" की यह अजीब विशेषता है। इस पर विचार करो:

<div> <a> <b>text</b> </a> </div>

यदि आप "पाठ" पर क्लिक करते हैं, तो पहले <b> तत्व को एक "क्लिक" घटना मिलेगी। उसके बाद, <a> तत्व को "क्लिक" ईवेंट मिलेगा। और उसके बाद <div> तत्व को एक "क्लिक" इवेंट मिलेगा। और इसी तरह - सभी तरह से <शरीर> तत्व। और यहीं से jQuery इवेंट को पकड़ लेगा और देखेगा कि क्या कोई "लाइव" हैंडलर उस तत्व पर लागू होता है जो पहली जगह में इवेंट का कारण बनता है। साफ!

और अंत में, द .delegate विधि। यह बस आपके तत्व के सभी बच्चों को लेता है जो दिए गए चयनकर्ता के अनुरूप होते हैं और उन्हें "लाइव" हैंडलर देते हैं। जरा देखो तो:

$("table").delegate( "td", "click", function() { alert( "Click!" ); } );

// Is equivalent to:
$("table").each( function() {
    $(this).find( "td" ).live( "click", function() { alert( "Click!" ); } );
} );

प्रशन?


सटीक होने के लिए, .live()बांधने के लिए documentनहीं <body>:) आप यहां एक डेमो देख सकते हैं, बस निरीक्षण करने के लिए कंसोल को ऊपर खींचें: jsfiddle.net/aJy2B
Nick Craver

3
इसे इस तरह समझाना अधिक सुविधाजनक था। :-)
फ्योडोर सोइकिन

4
"शरीर" भाग पर पर्याप्त रूप से उचित है, लेकिन "सभी तरह से <शरीर> तत्व" गलत है, घटनाएं वहाँ अतीत में जारी रहती हैं, और यह नहीं है कि .live()हैंडलर कहाँ रहते हैं, यह ऊपर है, उस पर document:) आप देख सकते हैं : यह यहाँ के डेमो jsfiddle.net/S2VBX
निक Craver

8

JQuery 1.7 के रूप में, .live () विधि को हटा दिया गया था। यदि आप एक jQuery संस्करण का उपयोग कर रहे हैं <1.7 की तुलना में इसे आधिकारिक तौर पर उपयोग करने की सिफारिश की गई है।

.live () को अब .on () से बदल दिया गया है।

अधिक जानकारी के लिए सीधे jQuery साइट पर जाने के लिए सबसे अच्छा है, लेकिन यहाँ .on () विधि के वर्तमान संस्करण हैं:

.on( events [, selector] [, data], handler(eventObject) )
.on( events-map [, selector] [, data] )

http://api.jquery.com/on/


2

$().click(fn)और $().bind('click', fn)पहली नजर में समान हैं, लेकिन $.bindसंस्करण दो कारणों से अधिक शक्तिशाली है:

  1. $().bind()आपको एक हैंडलर को कई घटनाओं में असाइन करने की अनुमति देता है, उदाहरण के लिए $().bind('click keyup', fn),।
  2. $().bind()नामांकित घटनाओं का समर्थन करता है - एक शक्तिशाली विशेषता यदि आप हटाना चाहते हैं (unbind) केवल कुछ ईवेंट हैंडलर जो एक तत्व से बंधे हैं - नामस्थान इवेंट में अधिक पढ़ें ।

लाइव बनाम प्रतिनिधि: यह पहले से ही अन्य उत्तरों में उत्तर दिया गया है।


1

यह वह जगह है जहाँ एपीआई पढ़ने में मदद मिल सकती है। हालांकि, मैं अपने सिर के ऊपर से जानता हूं, इसलिए आप आलसी (याय!) बने रह सकते हैं।

$('#something').click(fn);
$('#something').bind('click',fn);

यहाँ कोई अंतर नहीं है (कि मुझे पता है)। .clickबस एक सुविधा / सहायक विधि है.bind('click'

// even after this is called, all <a>s in
// <div class="dynamic_els"> will continue
// to be assigned these event handlers

$('div.dynamic_els a').live(‘click’,fn);

यह बहुत अलग है, जैसा .liveकि आप चयनकर्ता (जिसमें आप यहां नहीं हैं) में ईवेंट जोड़ते हैं और DOM को देखना जारी रखते हैं क्योंकि नोड्स डाले / हटाए जाते हैं

$('#some_element').delegate('td','click',fn);

ईवेंट हैंडलर्स को असाइन करने के तरीके के कारण यह केवल अलग है। .delegateडोम इवेंट बबलिंग पर केंद्रित है। बुनियादी सिद्धांत हर घटना डोम पेड़ के माध्यम से ऊपर की ओर बुलबुले कि जब तक यह मूल तत्व तक पहुँच जाता है (है documentया windowया <html>या <body>, मैं वास्तव में याद नहीं कर सकते)।

किसी भी तरह से, आप एक onclickहैंडलर को सभी <td>s के भीतर बांध रहे हैं $('#some_element')(आपको एक चयनकर्ता निर्दिष्ट करना होगा, हालांकि आप कह सकते हैं $(document))। जब इसके बच्चों में से एक पर क्लिक किया जाता है, तो इस घटना पर ध्यान जाता है <td>। फिर आप ईवेंट का स्रोत तत्व निकाल सकते हैं (जो आपके लिए jQuery स्वचालित रूप से करता है)।

यह उपयोगी है जब तत्वों के टन होते हैं और आपके पास केवल कुछ (या एक केंद्रीय) बिंदु [एस] होते हैं जो इन घटनाओं से गुजरेंगे। यह इन ईवेंट हैंडलर को कम ऑब्जेक्ट में समेकित करने के लिए ब्राउज़र के प्रयास और मेमोरी को बचाता है।


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