क्या कोई जावास्क्रिप्ट / jQuery डोम परिवर्तन श्रोता है?


402

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

जवाबों:


488

लंबे समय तक, DOM3 म्यूटेशन इवेंट सबसे अच्छा उपलब्ध समाधान था, लेकिन उन्हें प्रदर्शन कारणों से हटा दिया गया है। DOM4 म्यूटेशन ऑब्जर्वर , हटाए गए DOM3 उत्परिवर्तन घटनाओं के लिए प्रतिस्थापन हैं। वे वर्तमान में आधुनिक ब्राउज़रों में MutationObserver(या WebKitMutationObserverChrome के पुराने संस्करणों में विक्रेता-उपसर्ग के रूप में) लागू किए गए हैं:

MutationObserver = window.MutationObserver || window.WebKitMutationObserver;

var observer = new MutationObserver(function(mutations, observer) {
    // fired when a mutation occurs
    console.log(mutations, observer);
    // ...
});

// define what element should be observed by the observer
// and what types of mutations trigger the callback
observer.observe(document, {
  subtree: true,
  attributes: true
  //...
});

यह उदाहरण DOM documentऔर इसके पूरे उप- परिवर्तन के लिए सुनता है , और यह तत्व विशेषताओं के साथ-साथ संरचनात्मक परिवर्तनों पर भी आग लगाएगा। मसौदा कल्पना में मान्य म्यूटेशन श्रोता गुणों की पूरी सूची है :

childList

  • यह निर्धारित करें trueकि बच्चों को लक्षित करने के लिए उत्परिवर्तन मनाया जाना है या नहीं।

गुण

  • यह निर्धारित करने के लिए trueकि क्या लक्ष्य की विशेषताओं के म्यूटेशन देखे जाने हैं।

characterData

  • यह निर्धारित करने के लिए trueकि क्या लक्ष्य के डेटा में परिवर्तन किए जाने हैं।

सबट्री

  • trueयदि केवल लक्ष्य नहीं करने के लिए उत्परिवर्तन के लिए सेट करें , बल्कि लक्ष्य के वंशज भी देखे जा सकते हैं।

attributeOldValue

  • करने के लिए सेट trueकरता है, तो attributesसच और लक्ष्य की विशेषता मान पर सेट है उत्परिवर्तन जरूरतों दर्ज किया जा से पहले।

characterDataOldValue

  • करने के लिए सेट trueकरता है, तो characterDataसच और लक्ष्य के डेटा के लिए सेट है उत्परिवर्तन जरूरतों दर्ज किया जा से पहले।

attributeFilter

  • यदि सभी विशेषता म्यूटेशनों को देखने की आवश्यकता नहीं है, तो विशेषता स्थानीय नामों (बिना नामस्थान) की एक सूची पर सेट करें।

(यह सूची अप्रैल 2014 तक चालू है; आप किसी भी बदलाव के लिए विनिर्देश की जाँच कर सकते हैं।)


3
@AshrafBashir मुझे फ़ायरफ़ॉक्स 19.0.2 में नमूना ठीक काम करते हुए दिखाई देता है: मुझे ([{}])कंसोल पर लॉग इन दिखाई देता है, जो MutationRecordउस पर क्लिक करने पर अपेक्षित दिखाता है। कृपया फिर से जांचें, क्योंकि यह JSFiddle में एक अस्थायी तकनीकी विफलता हो सकती है। मैंने इसे IE में अभी तक परीक्षण नहीं किया है, क्योंकि मेरे पास IE 10 नहीं है, जो वर्तमान में उत्परिवर्तन घटनाओं का समर्थन करने के लिए एकमात्र संस्करण है।
अप्सिलर्स

1
मैंने सिर्फ एक उत्तर पोस्ट किया है जो IE10 + और ज्यादातर कुछ और में काम करता है।
नौगटुर

1
विनिर्देशन में ऐसा ग्रीन बॉक्स नहीं लगता है जो उत्परिवर्तन पर्यवेक्षक विकल्पों को किसी भी समय सूचीबद्ध करता है। यह खंड ५.३.१ में विकल्पों को सूचीबद्ध करता है और उनसे थोड़ा आगे का वर्णन करता है।
एलएस

2
@LS धन्यवाद, मैंने लिंक को अपडेट कर दिया है, हरे बॉक्स के बारे में थोड़ा हटा दिया है, और पूरी सूची को मेरे उत्तर में संपादित कर दिया है (बस भविष्य के लिंक सड़ने के मामले में)।
अप्सिलर्स

3
यहाँ मैं उपयोग कर सकते हैं से एक ब्राउज़र संगतता तालिका है।
ब्रेडशाम

211

संपादित करें

यह उत्तर अब हटा दिया गया है। उत्तर देखें अप्सिलर्स द्वारा ।

चूंकि यह क्रोम एक्सटेंशन के लिए है, इसलिए आप मानक DOM ईवेंट का उपयोग कर सकते हैं - DOMSubtreeModified। ब्राउज़रों में इस ईवेंट के लिए समर्थन देखें । यह 1.0 के बाद से क्रोम में समर्थित है।

$("#someDiv").bind("DOMSubtreeModified", function() {
    alert("tree changed");
});

एक कार्यशील उदाहरण यहां देखें ।


मैंने देखा है कि कुछ चयनकर्ताओं के बाद भी इस घटना को निकाल दिया जा सकता है। फिलहाल मैं जांच कर रहा हूं।
पेडर राइस

9
w3.org/TR/DOM-Level-3-Events/#event-type-DOMSubtreeModified का कहना है कि यह ईवेंट हटा दिया गया है, इसके बजाय हम क्या उपयोग करेंगे?
मस्लो

2
@ Maslow- वहाँ नहीं है! stackoverflow.com/questions/6659662/…
सैम रूबी

4
वहाँ है github.com/joelpurra/jquery-mutation-summary जो मूल रूप से गुड़ उपयोगकर्ताओं के लिए इसे हल करती है।
Capi Etheriel

1
यदि आप क्रोम एक्सटेंशन का निर्माण कर रहे हैं तब भी काम करता है। अमूल्य।
अवधारणा 47

49

कई साइट गतिशील रूप से सामग्री को जोड़ने / दिखाने / बदलने के लिए AJAX का उपयोग करती हैं। कभी-कभी इसका उपयोग इन-साइट नेविगेशन के बजाय किया जाता है, इसलिए वर्तमान URL को प्रोग्रामेटिक रूप से बदल दिया जाता है और सामग्री स्क्रिप्ट को स्वचालित रूप से इस मामले में ब्राउज़र द्वारा निष्पादित नहीं किया जाता है, क्योंकि पृष्ठ को दूरस्थ सर्वर से पूरी तरह से प्राप्त नहीं किया जाता है।


सामग्री स्क्रिप्ट में उपलब्ध पृष्ठ परिवर्तनों का पता लगाने के सामान्य जेएस तरीके ।


एक्सटेंशन-विशिष्ट: पृष्ठभूमि / ईवेंट पृष्ठ में URL परिवर्तनों का पता लगाएं ।

नेविगेशन के साथ काम करने के लिए उन्नत API हैं: webNavigation , webRequest , लेकिन हम सरल chrome.tabs.onUpdated ईवेंट श्रोता का उपयोग करेंगे जो सामग्री स्क्रिप्ट को संदेश भेजता है :


29

एक और तरीका इस बात पर निर्भर करता है कि आप किस तरह से डिव को बदल रहे हैं। यदि आप J html का उपयोग अपने html () विधि के साथ सामग्री को बदलने के लिए कर रहे हैं, तो आप उस विधि का विस्तार कर सकते हैं और जब भी आप html को div में रखते हैं, तब पंजीकरण फ़ंक्शन को कॉल कर सकते हैं।

(function( $, oldHtmlMethod ){
    // Override the core html method in the jQuery object.
    $.fn.html = function(){
        // Execute the original HTML method using the
        // augmented arguments collection.

        var results = oldHtmlMethod.apply( this, arguments );
        com.invisibility.elements.findAndRegisterElements(this);
        return results;

    };
})( jQuery, jQuery.fn.html );

हम केवल html () को कॉल को इंटरसेप्ट करते हैं, इसके साथ एक पंजीकरण फ़ंक्शन को कॉल करते हैं, जो संदर्भ में नई सामग्री प्राप्त करने वाले लक्ष्य तत्व को संदर्भित करता है, फिर हम कॉल को मूल jquery.html () फ़ंक्शन पर पास करते हैं। मूल html () विधि के परिणामों को वापस करने के लिए याद रखें, क्योंकि JQuery ने विधि-निर्धारण के लिए इसकी अपेक्षा की है।

ओवरराइडिंग और एक्सटेंशन के बारे में अधिक जानकारी के लिए, http://www.bennadel.com/blog/2009-Using-Self-Executing-Function-Arguments-To-Override-Core-jQuery-Method.htm , जो यहाँ है , की जाँच करें मैंने क्लोजर फंक्शन को क्रिब किया। JQuery की साइट पर प्लग इन ट्यूटोरियल को भी देखें।


7

MutationObserverएपीआई द्वारा प्रदान किए गए "कच्चे" टूल के अलावा , DOM म्यूटेशन के साथ काम करने के लिए "सुविधा" लाइब्रेरी मौजूद हैं।

विचार करें: MutationObserver उपशीर्षक के संदर्भ में प्रत्येक DOM परिवर्तन का प्रतिनिधित्व करता है। इसलिए, यदि आप, उदाहरण के लिए, एक निश्चित तत्व के सम्मिलित होने की प्रतीक्षा कर रहे हैं, तो यह बच्चों के अंदर गहरा हो सकता है mutations.mutation[i].addedNodes[j]

एक अन्य समस्या यह है कि जब आपका अपना कोड उत्परिवर्तन की प्रतिक्रिया में DOM को बदलता है - तो आप अक्सर इसे फ़िल्टर करना चाहते हैं।

एक अच्छी सुविधा पुस्तकालय जो इस तरह की समस्याओं को हल करता है mutation-summary(अस्वीकरण: मैं लेखक नहीं हूं, सिर्फ एक संतुष्ट उपयोगकर्ता हूं), जो आपको उन प्रश्नों को निर्दिष्ट करने में सक्षम बनाता है जो आप में रुचि रखते हैं, और वास्तव में प्राप्त करते हैं।

डॉक्स से मूल उपयोग उदाहरण:

var observer = new MutationSummary({
  callback: updateWidgets,
  queries: [{
    element: '[data-widget]'
  }]
});

function updateWidgets(summaries) {
  var widgetSummary = summaries[0];
  widgetSummary.added.forEach(buildNewWidget);
  widgetSummary.removed.forEach(cleanupExistingWidget);
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.