jquery का पता लगाने के लिए कुछ विशेष वर्ग के div को DOM में जोड़ा गया है


90

मैं .on()divs की घटनाओं को बाँधने के लिए उपयोग कर रहा हूँ जो पेज लोड होने के बाद बनते हैं। यह क्लिक, माउसेंटर के लिए ठीक काम करता है ... लेकिन मुझे यह जानने की जरूरत है कि कक्षा MyClass का एक नया div कब जोड़ा गया है। मैं यह देख रहा हूँ:

$('#MyContainer').on({

  wascreated: function () { DoSomething($(this)); }

}, '.MyClass');

मैं यह कैसे करु? मैं अपना पूरा ऐप बिना किसी प्लगइन के लिखने में कामयाब रहा हूं और मैं इसे उसी तरह रखना चाहता हूं।

धन्यवाद।


क्या यह आपका अपना कोड है जो तत्वों को उत्पन्न कर रहा है? यदि हां, तो आप इसे बनाने के समय की जांच कर सकते हैं और तदनुसार कार्य कर सकते हैं।
असली सपने

हाँ, यह सच है, लेकिन .on () के साथ, मैं डॉक्यूमेंट्स को पहले से ही बाँध सकता हूँ। तब और जब मुझे HTML उत्पन्न होता है तो मुझे बाइंडिंग के बारे में चिंता करने की ज़रूरत नहीं है। मैं DoSomething के साथ एक ही व्यवहार के लिए देख रहा हूँ।
फ्रेंचाइजी

आप $ ("div / your-selector") का उपयोग कर सकते हैं। hasClass ("MyClass"); यह जांचने के लिए कि किसी div के पास विशेष वर्ग है या नहीं। मुझे लगता है कि आप इस एपीआई को अपने उपयोग में ला सकते हैं।
KBN

.on () सिर्फ घटनाओं के लिए है। आप एक कस्टम ईवेंट के लिए सेट अप कर सकते हैं, लेकिन नए तत्व बनाते समय आपको उस ईवेंट को ट्रिगर करना होगा।
असली सपने

जवाबों:


102

पहले domManipसभी jQuery डोम जोड़-तोड़ को पकड़ने के लिए jQuery की विधि में हुक लगा सकते थे और देख सकते थे कि कौन से तत्व कहाँ डाले गए इत्यादि। लेकिन jQuery टीम ने इसे jQuery 3.0+ में बंद कर दिया क्योंकि यह आम तौर पर jQuery के तरीकों में हुक करने के लिए एक अच्छा समाधान नहीं है, और वे ' ve ने इसे इतना आंतरिक बना दियाdomManip विधि अब कोर jQuery कोड के बाहर उपलब्ध नहीं है।

उत्परिवर्तन घटनाओं को भी हटा दिया गया है, क्योंकि इससे पहले कि कोई ऐसा कर सकता है

$(document).on('DOMNodeInserted', function(e) {
    if ( $(e.target).hasClass('MyClass') ) {
       //element with .MyClass was inserted.
    }
});

इससे बचा जाना चाहिए, और आज इसके बजाय म्यूटेशन ऑब्जर्वर का उपयोग किया जाना चाहिए, जो इस तरह से काम करेगा

var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        console.log(mutation)
        if (mutation.addedNodes && mutation.addedNodes.length > 0) {
            // element added to DOM
            var hasClass = [].some.call(mutation.addedNodes, function(el) {
                return el.classList.contains('MyClass')
            });
            if (hasClass) {
                // element has class `MyClass`
                console.log('element ".MyClass" added');
            }
        }
    });
});

var config = {
    attributes: true,
    childList: true,
    characterData: true
};

observer.observe(document.body, config);

फ़ायरफ़ॉक्स और वेबकिट बहुत अधिक ठीक होना चाहिए, लेकिन इसके लिए समर्थन IE में कुछ खराब है। यह IE9 में काम करना चाहिए, लेकिन शायद IE8 में इतना नहीं। मुझे पता है कि मैंने वर्कअराउंड देखा है, और आईई में वास्तव में यह नहीं है, इसलिए पहले इसका परीक्षण करें, अगर यह काम नहीं कर रहा है, तो देखें कि क्या कोई वर्कअराउंड है। एक प्लगइन है जो दिखता है कि यह यहाँ IE समर्थन जोड़ता है , लेकिन यह कोशिश नहीं की है, बस इसे एक Google खोज में मिला है।
एडेनो

2
मैंने शुरू में आपके उत्तर का उपयोग किया था लेकिन यह तथ्य कि यह क्रॉस-ब्राउज़र काम नहीं कर रहा था एक समस्या थी। फिर, मैंने पहली बार में इस मुद्दे से बचने के लिए एक काम के आसपास जल्दी से पता लगा लिया। और फिर, कुछ सप्ताह पहले नोड सम्मिलन का पता लगाने का यह मुद्दा फिर से मेरे कोड में वापस आ गया। इस बार, मैंने अपने उत्तर में जो कोड पोस्ट किया है वह बिल्कुल उसी तरह काम करता है, जैसे कि क्रॉस-ब्राउजर और कुछ भी नहीं है। इसलिए मैंने अपना उत्तर स्वीकार कर लिया; एसओ कैसे काम करता है, ओपी तय करता है कि वह कौन सा उत्तर स्वीकार करता है और भीड़ जवाब पर वोट देती है। समय के साथ, लोग वोट देंगे और तय करेंगे कि कौन सा उत्तर उन्हें सबसे अच्छा लगता है।
फ्रेंची

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

इस कोड के साथ "
अनकैप्ड टाइपर्रर

53

यहाँ मेरा प्लगइन है कि exacly करता है - jquery.initialize

जैसे आप .eachफ़ंक्शन का उपयोग करेंगे वैसे ही है , लेकिन .initializeतत्व पर कार्य के साथ , अंतर से.each यह है कि यह भविष्य में किसी अतिरिक्त कोड के बिना जोड़े गए तत्वों को भी इनिशियलाइज़ करेगा - अगर आप इसे AJAX या किसी अन्य चीज़ के साथ जोड़ते हैं, तो कोई बात नहीं।

प्रारंभ में .each फ़ंक्शन के साथ एक ही सिंटैक्स है

$(".some-element").initialize( function(){
    $(this).css("color", "blue");
});

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

$("<div/>").addClass('some-element').appendTo("body"); //new element will have blue color!

प्लगइन पर आधारित है MutationObserver


बहुत बहुत धन्यवाद।
ब्रैंडन हैरिस

आरंभीकरण को कैसे रोकें? मैं एक बार जो सामान देख रहा था उसे जोड़कर देखना बंद करना चाहता हूं ...
इवगेनी वोस्तोक

$ ("। कुछ-तत्व")। आरंभ करें [..] पदावनत। $ .Initialize ("AddDialog", function () {$ ('। NoData') का उपयोग करें। छिपाएँ ();}) बजाय।
हेमी

क्या .initializeफ़ंक्शन को callback केवल उन तत्वों के लिए निष्पादित करना संभव है जो गतिशील रूप से जोड़े गए हैं (जैसे Ajax के माध्यम से), और जब पृष्ठ शुरू में लोड होता है तो पहले से मौजूद तत्वों के लिए कॉलबैक को छोड़ दें? मैं इसे पूरा करने के लिए एक पैरामीटर जोड़ने की कोशिश कर रहा हूं options, लेकिन अभी तक मुझे यह काम करने के लिए नहीं मिला है।
नेवरमोर

आप इसके बारे में github पर समस्या जोड़ सकते हैं। अभी के लिए, तकनीकी रूप से आप कर सकते हैं$('.myClass').addClass('ignore-initialize'); $.initialize('.myClass:not(.ignore-initialize)', callback);
pie6k

18

इस और कई अन्य पदों की समीक्षा करने के बाद, मैंने सोचा कि मैंने जो कुछ सोचा था, उसमें से प्रत्येक में सबसे अच्छा था जिसने तत्वों के एक वर्ग को सम्मिलित करने और फिर उन तत्वों पर कार्य करने की अनुमति दी ।

function onElementInserted(containerSelector, elementSelector, callback) {

    var onMutationsObserved = function(mutations) {
        mutations.forEach(function(mutation) {
            if (mutation.addedNodes.length) {
                var elements = $(mutation.addedNodes).find(elementSelector);
                for (var i = 0, len = elements.length; i < len; i++) {
                    callback(elements[i]);
                }
            }
        });
    };

    var target = $(containerSelector)[0];
    var config = { childList: true, subtree: true };
    var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
    var observer = new MutationObserver(onMutationsObserved);    
    observer.observe(target, config);

}

onElementInserted('body', '.myTargetElement', function(element) {
    console.log(element);
});

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


1
आपकी स्थिति यह होनी चाहिए if(mutation.addedNodes.length)क्योंकि addedNodesऔर removedNodesसरणियाँ हमेशा mutationप्रकार में होती हैं childList(IE11, Chrome53, FF49 में जाँच की जाती हैं)। फिर भी +1, क्योंकि आपका एकमात्र जवाब है जहां addedNodesमाना जाता है ( callbackकेवल तभी कहा जाता है जब एक नोड जोड़ा जाता है); न केवल इस धागे पर बल्कि कई अन्य धागे। बाकी callbackसभी म्यूटेशनों के लिए हर कोई बस आह्वान कर रहा है, भले ही नोड को हटाया जा रहा हो।
विवेक अठाली

17

3 साल के अनुभव के बाद, यह है कि मैं "DOM में जोड़े गए एक निश्चित वर्ग के तत्व" को सुनता हूं : आप बस html()इस तरह jQuery फ़ंक्शन में एक हुक जोड़ते हैं :

function Start() {

   var OldHtml = window.jQuery.fn.html;

   window.jQuery.fn.html = function () {

     var EnhancedHtml = OldHtml.apply(this, arguments);

     if (arguments.length && EnhancedHtml.find('.MyClass').length) {

         var TheElementAdded = EnhancedHtml.find('.MyClass'); //there it is
     }

     return EnhancedHtml;
   }
}

$(Start);

यह काम करता है यदि आप jQuery का उपयोग कर रहे हैं, जो मैं करता हूं। और यह ब्राउज़र-विशिष्ट ईवेंट पर निर्भर नहीं करता है DOMNodeInserted, जो क्रॉस-ब्राउज़र संगत नहीं है। मैंने उसी कार्यान्वयन को इसके लिए भी जोड़ा.prepend()

कुल मिलाकर, यह मेरे लिए एक आकर्षण की तरह काम करता है, और उम्मीद है कि आपके लिए भी।


6
हम्म - मैं स्पष्ट करता हूँ कि यह काम करता है यदि आप विशेष रूप htmlसे डोम को संशोधित करने के लिए jQuery के सहायक का उपयोग कर रहे हैं , न कि केवल "jQuery का उपयोग" सामान्य रूप से। तत्वों ने कहा, jQuery.appendइस घटना को ट्रिगर नहीं करेंगे।
इमली

1
हां, और इसीलिए मैंने स्पष्ट किया कि मैंने एक ही कार्यान्वयन को .preprend () के साथ जोड़ा है और यदि आप .append () का उपयोग करते हैं तो .append () के साथ एक ही काम करें
फ्रेंचाइजी

CSS3 एनिमेशन का उपयोग करते हुए बहुत तेज़ दृष्टिकोण है । ओपन-सोर्स लाइब्रेरी भी बहुत सरल कोड को उधार देती है:insertionQ('#intercom-container').every(function(/element){ element.style.display = 'none'; });
डैन डस्केलस्क्यू

3
नीच क्यों ?? यह वास्तव में काम करता है: कोई प्लगइन और कोई हैकी सेटटाइमआउट फ़ंक्शन नहीं।
16

2
अपवित्र - यह एक वैध विकल्प है - दुनिया में क्यों (!!!) इसको घटाया गया है ?????? Dan, CSS3 के एनिमेशन XBC नहीं हैं: caniuse.com/#search=keyframes ; davidwalsh.name/detect-node-insertion
कोड़ी

6

आप उत्परिवर्तन घटनाओं का उपयोग कर सकते हैं

http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-eventgroupings-mutationevents

संपादित करें

MDN से: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Mutation_events

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

उत्परिवर्तन पर्यवेक्षक DOM4 में उत्परिवर्तन घटनाओं के लिए प्रस्तावित प्रतिस्थापन हैं। उन्हें फ़ायरफ़ॉक्स 14 और क्रोम 18 में शामिल किया जाना है।

https://developer.mozilla.org/en/docs/Web/API/MutationObserver

MutationObserverडेवलपर्स को DOM में परिवर्तनों पर प्रतिक्रिया करने का एक तरीका प्रदान करता है। इसे DOM3 ईवेंट स्पेसिफिकेशन में परिभाषित म्यूटेशन इवेंट्स के प्रतिस्थापन के रूप में डिज़ाइन किया गया है।

उदाहरण उपयोग

निम्न उदाहरण http://hacks.mozilla.org/2012/05/dom-mutationobserver-reacting-to-dom-changes-without-killing-browser-performance/ से लिया गया था ।

// select the target node
var target = document.querySelector('#some-id');

// create an observer instance
var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    console.log(mutation.type);
  });    
});

// configuration of the observer:
var config = { attributes: true, childList: true, characterData: true };

// pass in the target node, as well as the observer options
observer.observe(target, config);

// later, you can stop observing
observer.disconnect();

2
उत्परिवर्तन घटनाएँ mdn के अनुसार बहुत अधिक चित्रित हैं , MutationObservers के पक्ष में
ओल्गा

अब जब IE10 ईओएल है, तो यह कहना लगभग सुरक्षित होना चाहिए कि MutationObserver व्यापक रूप से समर्थित है।
रयो १o

0

एडीनो के जवाब में दो जोड़:

(1) हम लाइन बदल सकते हैं

return el.classList.contains('MyClass');

सेवा

if( el.classList ) {
    return el.classList.contains('MyClass');
} else {
    return false;
}

इसलिए हम "Uncaught TypeError: Cannot read property 'contains' of undefined"त्रुटि नहीं देखेंगे ।

(2) ऐड subtree: trueमें configरिकर्सिवली सभी जोड़ा तत्वों में जोड़ा नोड्स खोजने के लिए।

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