javascript - घटना गतिशील रूप से बनाए गए तत्वों पर बाध्यकारी?




jquery events (14)

मेरे पास थोड़ा सा कोड है जहां मैं किसी पृष्ठ पर सभी चुनिंदा बॉक्सों के माध्यम से लूपिंग कर रहा हूं और mouse on/off अपनी चौड़ाई के साथ थोड़ा सा .hover करने के लिए उन्हें एक .hover ईवेंट बाध्य कर रहा .hover

यह पेज तैयार होता है और ठीक काम करता है।

मेरी समस्या यह है कि प्रारंभिक लूप के बाद अजाक्स या डोम के माध्यम से जोड़े गए किसी भी चुनिंदा बॉक्स में ईवेंट बाध्य नहीं होगा।

मुझे यह प्लगइन ( jQuery लाइव क्वेरी प्लगइन ) मिला है, लेकिन इससे पहले कि मैं प्लगइन के साथ अपने पृष्ठों में एक और 5k जोड़ूं, मैं देखना चाहता हूं कि कोई ऐसा करने का तरीका जानता है या तो jQuery के साथ या किसी अन्य विकल्प से।


घटना गतिशील रूप से बनाए गए तत्वों पर बाध्यकारी

एकल तत्व:

$(document.body).on('click','.element', function(e) {  });

बाल तत्व:

 $(document.body).on('click','.element *', function(e) {  });

जोड़ा * । उस तत्व के सभी बच्चों के लिए एक कार्यक्रम ट्रिगर किया जाएगा।

मैंने नोटिस किया है कि:

$(document.body).on('click','.#element_id > element', function(e) {  });

यह अब और काम नहीं कर रहा है, लेकिन यह पहले काम कर रहा था। मैं Google CDN से jQuery का उपयोग कर रहा हूं, लेकिन मुझे नहीं पता कि उन्होंने इसे बदल दिया है या नहीं।


आप उपयोग कर सकते हैं

$('.buttons').on('click', 'button', function(){
    // your magic goes here
});

या

$('.buttons').delegate('button', 'click', function() {
    // your magic goes here
});

ये दो विधियां बराबर हैं लेकिन पैरामीटर का एक अलग क्रम है।

देखें: jQuery प्रतिनिधि कार्यक्रम


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

function addCallbacks(eles){
    eles.hover(function(){alert("gotcha!")});
}

$(document).ready(function(){
    addCallbacks($(".myEles"))
});

// ... add elements ...
addCallbacks($(".myNewElements"))

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

 $(document).on( 'eventName', '.elementName', function () { ... do your work 
}); 

इवेंटनाम कोई भी घटना हो सकता है जैसे क्लिक, माउसओवर, माउसलेव, इनपुट, चेंज ...


कोई भी पी नहीं है जो ईवेंट बाध्य होने पर मौजूद होता है और यदि आपका पृष्ठ कक्षा नाम बटन के साथ गतिशील रूप से तत्व बना रहा था, तो आप ईवेंट को ऐसे माता-पिता से जोड़ देंगे जो पहले से मौजूद है

$(document).ready(function(){
  //Particular Parent chield click
  $(".buttons").on("click","button",function(){
    alert("Clicked");
  });  
  
  //Dynamic event bind on button class  
  $(document).on("click",".button",function(){
    alert("Dymamic Clicked");
  });
  $("input").addClass("button");  
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="buttons">
  <input type="button" value="1">
  <button>2</button>
  <input type="text">
  <button>3</button>  
  <input type="button" value="5">  
  </div>
<button>6</button>


जब आप jQuery(html, attributes) का उपयोग करके गतिशील रूप से बनाए जाते हैं तो आप तत्व को तत्व संलग्न कर सकते हैं।

JQuery 1.8 के अनुसार , किसी भी jQuery इंस्टेंस विधि ( jQuery.fn का एक तरीका) दूसरे पैरामीटर को पारित ऑब्जेक्ट की संपत्ति के रूप में उपयोग किया जा सकता है:

function handleDynamicElementEvent(event) {
  console.log(event.type, this.value)
}
// create and attach event to dynamic element
jQuery("<select>", {
    html: $.map(Array(3), function(_, index) {
      return new Option(index, index)
    }),
    on: {
      change: handleDynamicElementEvent
    }
  })
  .appendTo("body");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>


तत्व "MAIN" वर्ग का ध्यान रखें, उदाहरण के लिए,

<div class="container">
     <ul class="select">
         <li> First</li>
         <li>Second</li>
    </ul>
</div>

उपरोक्त परिदृश्य में, jQuery ऑब्जेक्ट जो jQuery देखेंगे वह "कंटेनर" है।

फिर आप मूल रूप से कंटेनर के तहत तत्वों के नाम जैसे ul , li , और select :

$(document).ready(function(e) {
    $('.container').on( 'click',".select", function(e) {
        alert("CLICKED");
    });
 });

तत्व बनाने और घटनाओं को बांधने के लिए अधिक लचीला समाधान ( source )

// creating a dynamic element (container div)
var $div = $("<div>", {id: 'myid1', class: 'myclass'});

//creating a dynamic button
 var $btn = $("<button>", { type: 'button', text: 'Click me', class: 'btn' });

// binding the event
 $btn.click(function () { //for mouseover--> $btn.on('mouseover', function () {
    console.log('clicked');
 });

// append dynamic button to the dynamic container
$div.append($btn);

// add the dynamically created element(s) to a static element
$("#box").append($div);

नोट: यह प्रत्येक तत्व के लिए एक ईवेंट हैंडलर उदाहरण बनाएगा (लूप में उपयोग किए जाने पर प्रदर्शन को प्रभावित कर सकता है)


मैं चयनकर्ता का उपयोग करना पसंद करता हूं और मैं इसे दस्तावेज़ पर लागू करता हूं।

यह दस्तावेज़ पर खुद को बांधता है और उन तत्वों पर लागू होगा जो पेज लोड के बाद प्रस्तुत किए जाएंगे।

उदाहरण के लिए:

$(document).on("click", $(selector), function() {
    // Your code here
});

यह किसी भी पुस्तकालय या प्लगइन्स के बिना एक शुद्ध जावास्क्रिप्ट समाधान है:

document.addEventListener('click', function (e) {
    if (hasClass(e.target, 'bu')) {
        // .bu clicked
        // Do your thing
    } else if (hasClass(e.target, 'test')) {
        // .test clicked
        // Do your other thing
    }
}, false);

जहां hasClass है

function hasClass(elem, className) {
    return elem.className.split(' ').indexOf(className) > -1;
}

लाइव डेमो

क्रेडिट डेव और शिम विदास जाता है

अधिक आधुनिक जेएस का उपयोग करके, hasClass को इस प्रकार कार्यान्वित किया जा सकता है:

function hasClass(elem, className) {
    return elem.classList.contains(className);
}

लाइव तत्वों के लिए ईवेंट हैंडलर संलग्न करने के लिए jQuery on() की .on() विधि का उपयोग करें।

संस्करण 1.9 के रूप में। .live() विधि हटा दी गई है।


on() के प्रलेखन में एक अच्छी व्याख्या है।

संक्षेप में:

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

इस प्रकार कोड में उत्पन्न होने से पहले निम्नलिखित उदाहरण #dataTable tbody tr मौजूद होना चाहिए।

$("#dataTable tbody tr").on("click", function(event){
    console.log($(this).text());
});

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

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

$("#dataTable tbody").on("click", "tr", function(event){
    console.log($(this).text());
});

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

एक प्रतिनिधि-घटना दृष्टिकोण (दूसरा कोड उदाहरण) एक ईवेंट हैंडलर को केवल एक तत्व, tbody , और ईवेंट को केवल एक स्तर (क्लिक किए गए tr से tbody ) को बुलबुला करने की आवश्यकता होती है।

नोट: प्रतिनिधि कार्यक्रम SVG लिए काम नहीं करते हैं।


JQuery 1.7 के रूप में आपको jQuery.fn.on उपयोग करना चाहिए:

$(staticAncestors).on(eventName, dynamicChild, function() {});

इससे पहले , अनुशंसित दृष्टिकोण live() का उपयोग करना था:

$(selector).live( eventName, function(){} );

हालांकि, live() को live() पक्ष में 1.7 में बहिष्कृत किया गया था, और पूरी तरह से 1.9 में हटा दिया गया था। live() हस्ताक्षर:

$(selector).live( eventName, function(){} );

... on() हस्ताक्षर on() निम्न के साथ प्रतिस्थापित किया जा सकता है:

$(document).on( eventName, selector, function(){} );

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

$(document).on('mouseover mouseout', '.dosomething', function(){
    // what you want to happen when mouseover and mouseout 
    // occurs on elements that match '.dosomething'
});

घटना के बाध्य होने पर मौजूद कोई भी माता-पिता ठीक है। उदाहरण के लिए

$('.buttons').on('click', 'button', function(){
    // do something here
});

पर लागू होगा

<div class="buttons">
    <!-- <button>s that are generated dynamically and added here -->
</div>

<html>
    <head>
        <title>HTML Document</title>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
    </head>

    <body>
        <div id="hover-id">
            Hello World
        </div>

        <script>
            jQuery(document).ready(function($){
                $(document).on('mouseover', '#hover-id', function(){
                    $(this).css('color','yellowgreen');
                });

                $(document).on('mouseout', '#hover-id', function(){
                    $(this).css('color','black');
                });
            });
        </script>
    </body>
</html>






unobtrusive-javascript