jQuery .live () बनाम .on () डायनामिक html लोड करने के बाद क्लिक इवेंट जोड़ने के लिए विधि


217

मैं jQuery v.1.7.1 का उपयोग कर रहा हूं जहां .live () विधि स्पष्ट रूप से पदावनत है।

समस्या मुझे यह है कि जब गतिशील रूप से HTML को एक तत्व में लोड किया जा रहा है:

$('#parent').load("http://..."); 

यदि मैं कोशिश करता हूं और बाद में एक क्लिक ईवेंट जोड़ता हूं, तो यह इन विधियों में से किसी एक का उपयोग करके ईवेंट को पंजीकृत नहीं करता है:

$('#parent').click(function() ...); 

या

// according to documentation this should be used instead of .live()
$('#child').on('click', function() ...); 

इस कार्यक्षमता को प्राप्त करने का सही तरीका क्या है? यह केवल मेरे लिए .live () के साथ काम करने लगता है, लेकिन मुझे उस पद्धति का उपयोग नहीं करना चाहिए। ध्यान दें कि #child एक गतिशील रूप से भरा हुआ तत्व है।

धन्यवाद।


25
आप "कथित रूप से पदावनत" क्यों कहते हैं ? क्या आपको डॉक्स पर विश्वास नहीं है?

6
यह नहीं कर रहा है माना जाता है कि पदावनत: यह है पदावनत। आप को देखो, तो jQuery doco के लिए.live() यह आपको बताता है की मौजूदा का उपयोग करता है के पुनर्लेखन के लिए कैसे .live()उपयोग करने के लिए .delegate()या .on()(चाहे आप संस्करण पर नहीं कर रहे हैं 1.7+ या के आधार पर)। ध्यान दें कि यदि आप .click()"बाद में" के साथ एक हैंडलर जोड़ते हैं , जैसा कि आप उल्लेख करते हैं, अर्थात, गतिशील रूप से लोडिंग तत्वों के बाद, यह काम करना चाहिए - केवल समस्या यह है .click() कि गतिशील रूप से लोडिंग तत्वों से पहले असाइन करने की कोशिश की जा रही है ।
nnnnnn

मैंने शब्दांकन को 'जाहिरा तौर पर' में बदल दिया क्योंकि मूल रूप से मेरा यही मतलब था। वैसे भी, मुझे अब समझ में आया है कि स्पष्ट रूप से .लोड () घटना अतुल्यकालिक है तो #child तत्व केवल विश्वसनीय रूप से सफलता हैंडलर में पहचाना जा सकता है, जो समझ में आता है।
सीन थोमैन

जवाबों:


606

यदि आप चाहते हैं कि क्लिक हैंडलर गतिशील रूप से लोड होने वाले तत्व के लिए काम करे, तो आप इवेंट हैंडलर को पैरेंट ऑब्जेक्ट पर सेट करें (जो कि गतिशील रूप से लोड नहीं होता है) और उसे एक चयनकर्ता दें जो आपकी डायनामिक ऑब्जेक्ट से इस तरह मेल खाता हो:

$('#parent').on("click", "#child", function() {});

ईवेंट हैंडलर को #parentऑब्जेक्ट से जोड़ा जाएगा और कभी भी एक क्लिक ईवेंट उस तक पहुंच #childजाएगा जो उस पर उत्पन्न होता है , यह आपके क्लिक हैंडलर को आग लगा देगा। इसे डेलिगेट इवेंट हैंडलिंग कहा जाता है (इवेंट हैंडलिंग को पैरेंट ऑब्जेक्ट को सौंप दिया जाता है)।

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


23
महान व्याख्या! मैंने पहले आसपास मेरे सिर लपेटो करने में सक्षम कभी नहीं किया गया है live()बनाम on()लेकिन आज रात मैं एक बार फिर कोशिश करने का फैसला किया है, और अपने स्पष्टीकरण तुरंत पता चला कि मैं क्या सब साथ लापता हो गया था। धन्यवाद!
माइकस्किंकेल

6
एक लाख अप । इससे पहले कि मुझे एहसास हुआ कि गतिशील रूप से बनाए गए बच्चों के लिए jQuery में यह संभव था, मैंने आपको बहुत धन्यवाद दिया।
ब्रॉक हेंसले

9
आपको पुस्तक या कुछ लिखने पर विचार करना चाहिए: आपका छोटा पाठ jQuery डॉक्स में « ऑन () » के पूर्ण पृष्ठ की तुलना में मेरे लिए अधिक उपयोगी रहा है । आपका बहुत बहुत धन्यवाद!
कोलेस्ट्रॉल

@ jfriend00 क्या आपको पता है कि हम इस प्रक्रिया को एक हॉवर, नॉन-हॉवर स्थिति पर कैसे लागू कर सकते हैं? क्या कोई ऐसा स्रोत है जो इस बारे में बात करता है?
क्लेविस

@blackhawk - देखें यह उत्तर । आप हैंडलर के अंदर घटनाओं mouseenterऔर mouseleaveघटनाओं के लिए पंजीकरण कर सकते हैं और परीक्षण कर सकते हैं । jQuery का छद्म "होवर" ईवेंट प्रतिनिधिमंडल के साथ उपलब्ध नहीं है।
२०

33

इसे इस्तेमाल करे:

$('#parent').on('click', '#child', function() {
    // Code
});

से $.on()प्रलेखन:

ईवेंट हैंडलर केवल वर्तमान में चयनित तत्वों के लिए बाध्य हैं; जिस समय आपका कोड कॉल करता है, उस समय उन्हें पृष्ठ पर मौजूद होना चाहिए .on()

#childजब आप इस $.on()पर कॉल करते हैं तो आपका तत्व मौजूद नहीं होता है, इसलिए ईवेंट बाध्य नहीं है (इसके विपरीत $.live())। #parent, तथापि, करता है अस्तित्व है, तो घटना बाध्यकारी है कि ठीक है।

ऊपर दिए गए मेरे कोड में दूसरा तर्क केवल 'ट्रिगर' के रूप में काम करता है, जब घटना से बुदबुदाती #parentहै #child


यदि मैं $ .load () विधि के बाद $ .on () विधि को कॉल करता हूं, तो उस बिंदु पर #child तत्व क्यों नहीं होगा?
सीन थोमैन

6
@ सीनियन - आपको इसे .load()विधि के सफलता हैंडलर से कॉल करना होगा - विधि के बाद कोड से नहीं .load()#childकेवल तभी लोड होने के लिए जाना जाता है जब सफलता हैंडलर वास्तव में निष्पादित करता है और पहले नहीं।
जॉइटरेस

और फिर भी समय जो भी डेटा आप DOM में वापस मिला है डालने का मतलब है कि यह कनेक्ट नहीं हो सकता है। मैं हाल ही में बहुत सारे सिंगल पेज ऐप का काम कर रहा हूं और मेरा मानक var $ body = $ ('body') है; $ body.on ("इवेंट", "। पेमेंट / # क्लास", फंक्शन (ई) {}); प्रत्येक वस्तु के लिए। 1 चयनकर्ता। लोड नहीं है या क्या नहीं है, इसके बारे में कोई चिंता नहीं है।
16

21

$(document).on('click', '.selector', function() { /* do stuff */ });

संपादित करें: मैं थोड़ा अधिक जानकारी प्रदान कर रहा हूं कि यह कैसे काम करता है, क्योंकि ... शब्द। इस उदाहरण के साथ, आप पूरे दस्तावेज़ पर एक श्रोता रख रहे हैं।

जब आप click किसी भी तत्व पर मेल खाते हैं .selector, तो ईवेंट मुख्य दस्तावेज़ तक पहुंच जाता है - इसलिए जब तक कोई अन्य श्रोता नहीं event.stopPropagation()होता है जो कॉल विधि नहीं करता है - जो किसी ईवेंट के बबलिंग को मूल तत्वों में बदल देगा।

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

यह कुछ कारणों से स्मार्ट है, जिसमें प्रदर्शन और मेमोरी उपयोग (बड़े पैमाने पर अनुप्रयोगों में) शामिल हैं

संपादित करें:

जाहिर है, आप जिस निकटतम मूल तत्व को सुन सकते हैं वह बेहतर है, और आप किसी भी तत्व का उपयोग तब तक कर सकते हैं documentजब तक कि आप उन घटनाओं की निगरानी करना चाहते हैं जो उस मूल तत्व के भीतर हैं ... लेकिन वास्तव में ऐसा करने के लिए कुछ भी नहीं है सवाल के साथ।


23
उसने कोशिश की $(element).on(...)। यह वह जगह है $(document).on(...,element,...)। अलग-अलग जानवर।
cHao

@AnnoldRoa हाँ, बेहतर प्रदर्शन। आपके पास कई बच्चों पर एक श्रोता नहीं होगा, श्रोता को किसी भी समय फिर से आवेदन करने की आवश्यकता नहीं है, जबकि डोम को संशोधित किया गया है, और ईवेंट डिफ़ॉल्ट रूप से डोम के माध्यम से बुलबुला। एक बार चलाएं और चयन करने वाले प्रत्येक बच्चे को क्लिक किए जाने पर दिए गए फ़ंक्शन को ट्रिगर करेगा।
L422Y

@ L422Y की टिप्पणी यहाँ बहुत ही भ्रामक है। यदि आप प्रदर्शन के निहितार्थ के बारे में उत्सुक हैं, तो @ Jared00 के जवाब
Gust van de Wal

@GustvandeWal यह भ्रामक कैसे है? यदि आप जाते हैं और एक सौ डॉलर (यह) .on (...) बनाम एक घटना को एक मूल तत्व पर एक बार सुनते हैं, तो यह काफी अधिक प्रदर्शनकारी है।
L422Y

आप केवल घटनाओं को संलग्न करने के बारे में बात कर रहे हैं। वास्तविक दुनिया के प्रदर्शन में अड़चनें बहुत से श्रोताओं को निकाल देती हैं (जैसे कि आप जो प्रतिनिधि हैं), न कि उन तत्वों की बड़ी मात्रा में जो उनसे जुड़ी एक घटना की आवश्यकता होती है।
Gust van de Wal

12

1.7 में .live () का समकक्ष इस प्रकार है:

$(document).on('click', '#child', function() ...); 

मूल रूप से, क्लिक इवेंट्स के लिए दस्तावेज़ देखें और उन्हें #child के लिए फ़िल्टर करें।


क्योंकि ईवेंट हैंडलर दस्तावेज़ (जिस तरह से .live()करता है) से जुड़ता है ।
काओ

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

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

सबसे खराब रूप से, यह पदावनत दृष्टिकोण का अनुकरण करता है.live() ; हालांकि प्रतिनिधिमंडल को नियंत्रित करने की क्षमता निश्चित रूप से लाभप्रद है।
डैन लुग

9

मुझे पता है कि उत्तर के लिए थोड़ा देर हो चुकी है, लेकिन मैंने .live () विधि के लिए एक पॉलीफ़िल बनाया है। मैंने इसे jQuery 1.11 में परीक्षण किया है, और यह बहुत अच्छी तरह से काम करता है। मुझे पता है कि हम जहां भी संभव हो .on () विधि को लागू करने वाले हैं, लेकिन बड़ी परियोजनाओं में, जहाँ सभी (।) कॉल को समतुल्य .on () कॉल में परिवर्तित करना संभव नहीं है, जो भी कारण हो, निम्नलिखित हो सकता है। काम:

if(jQuery && !jQuery.fn.live) {
    jQuery.fn.live = function(evt, func) {
        $('body').on(evt, this.selector, func);
    }
}

आपके द्वारा jQuery लोड करने और लाइव कॉल करने से पहले इसे शामिल करें ()।


5

.on () jQuery के संस्करण 1.7 और इसके बाद के संस्करण के लिए है। यदि आपके पास एक पुराना संस्करण है, तो इसका उपयोग करें:

$("#SomeId").live("click",function(){
    //do stuff;
});

8
ओपी कहता है "मैं jQuery v.1.7.1 का उपयोग कर रहा हूं"
अरुमुगम

1
@ हंसी-मजाक क्यों नहीं करना चाहिए? मैं 1.6 से छोटे सभी संस्करणों के साथ हर दिन लाइव () का उपयोग करता हूं और यह ठीक काम करता है। मैं देख सकता हूं कि आप दस्तावेज़ीकरण पढ़ने में अच्छे हैं, लेकिन कभी-कभी किसी व्यक्ति के लिए अभ्यास में कुछ डालना अधिक मददगार होता है। .live () काम करता है। अवधि।
मैट कैसहैट

5
@MatthewPatrickCashatt - मैंने अपना उत्तर पोस्ट किया और आपका उत्थान नहीं किया - इस तरह की अंध धारणाएं नहीं बनाते। 1.7 पूर्व, .delegate()इससे बेहतर प्रदर्शन करता .live()है कि क्यों jQuery के डॉक्टर इसकी सिफारिश करते हैं और पदावनत करते हैं .live()। हां, .live()अभी भी काम करता है, लेकिन एसओ पर जवाब यहां चीजों को करने के बेहतर तरीके की सिफारिश करना चाहिए। मैंने एसओ पर 20 बार यहां देखा है। यदि आप .live()एसओ के यहां कोड पोस्ट करते हैं, तो यह डाउनवोट हो जाएगा (आमतौर पर मेरे द्वारा नहीं जब तक कि इसके साथ कुछ और गंभीर रूप से गलत न हो)।
जून को jfriend00

1
मैं नीच नहीं था, लेकिन हालांकि .live()निश्चित रूप से संस्करण 1.7 में भी काम करता है आपको अभी भी उपयोग करना चाहिए .delegate()या .on()क्योंकि .live()एक अच्छे कारण के लिए पदावनत किया गया था। जब तक आप दो नए कार्यों के लिए सिंटैक्स में परिवर्तन को नोट करते हैं या तो ठीक काम करेगा।
nnnnnn

1
@ jfriend00- आप बिल्कुल सही हैं। लंबा दिन। मैं क्षमाप्रार्थी हूं।
मैट कैसहैट

3

मैंने अपने प्रोजेक्ट में 'लाइव' का इस्तेमाल किया लेकिन मेरे एक दोस्त ने सुझाव दिया कि मुझे लाइव के बजाय 'ऑन' का इस्तेमाल करना चाहिए। और जब मैंने उपयोग करने की कोशिश की, तो मुझे आपके जैसी समस्या का अनुभव हुआ।

अपने पृष्ठों पर मैं गतिशील रूप से बटन तालिका पंक्तियाँ और कई डोम सामग्री बनाता हूँ। लेकिन जब मैं जादू पर उपयोग गायब हो गया।

एक बच्चे की तरह इसका उपयोग करने वाले अन्य समाधान हर बार हर क्लिक पर आपके कार्यों को कॉल करते हैं। लेकिन मैं इसे फिर से बनाने का एक तरीका खोजता हूं और यहां समाधान है।

अपना कोड इस प्रकार लिखें:

function caller(){
    $('.ObjectYouWntToCall').on("click", function() {...magic...});
}

कॉल करने वाला (); इस तरह से आप पृष्ठ में अपनी वस्तु बनाते हैं।

$('<dom class="ObjectYouWntToCall">bla... bla...<dom>').appendTo("#whereeveryouwant");
caller();

इस तरह से आपके फंक्शन को कॉल किया जाता है, जब पेज पर हर क्लिक नहीं करना चाहिए।

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