jQuery इवेंट: एक div के HTML / पाठ में परिवर्तन का पता लगाने


265

मैं एक div जो अपनी सामग्री हर समय बदल रहा है है, यह हो सकता है ajax requests, jquery functions, blurआदि आदि

क्या कोई तरीका है जिससे मैं किसी भी समय अपने div पर किसी भी परिवर्तन का पता लगा सकता हूँ?

मैं किसी भी अंतराल या डिफ़ॉल्ट मान की जाँच नहीं करना चाहता।

कुछ ऐसा होगा

$('mydiv').contentchanged() {
 alert('changed')
}

5
संभव डुप्लिकेट: stackoverflow.com/questions/10328102/…
रॉब

14
@ रब एक keypressघटना को एक संतोषी <div>तत्व के लिए बाध्य कर रहा है । मुझे यकीन नहीं है कि वहां के समाधान इस पर लागू होते हैं। वे निश्चित रूप से किसी तत्व की सामग्री में कोई प्रोग्रामेटिक परिवर्तन नहीं करेंगे।
एंथनी ग्रिस्ट

जवाबों:


407

यदि आप टाइमर का उपयोग नहीं करना चाहते हैं और इनर HTML की जांच कर सकते हैं तो आप इस घटना को आजमा सकते हैं

$('mydiv').bind('DOMSubtreeModified', function(){
  console.log('changed');
});

अधिक विवरण और ब्राउज़र समर्थन डेटा यहाँ हैं

ध्यान दें: नए jQuery के संस्करणों में बाइंड () को हटा दिया गया है, इसलिए आपको इसके बजाय () पर उपयोग करना चाहिए:

$('body').on('DOMSubtreeModified', 'mydiv', function(){
  console.log('changed');
});

14
ध्यान रखें कि DOMSubtreeModified IE8 (और नीचे) में समर्थित नहीं है।
गाविं


3
मोज़िला 33: तत्व <शरीर> के लिए पुनरावृत्ति में गिर गया। दूसरा रास्ता खोजने की जरूरत है
Chaki_Black

17
यह गंभीर है इस घटना का उपयोग न करें यह आपके सभी काम को दुर्घटनाग्रस्त कर देगा जो इसे हर समय निकाल दिया जाता है। इसके बजाय $ ('myDiv') से नीचे की घटनाओं का उपयोग करें। बाइंड ('DOMNodeInserted DOMNodeRemoved', function () {});
जॉर्ज SEDRA

19
इस विधि को हटा दिया गया है! इसके बजाय उपयोग करें:$("body").on('DOMSubtreeModified', "mydiv", function() { });
आसिफ

55

जावास्क्रिप्ट MutationObserver का उपयोग करना

  //More Details https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
 // select the target node
var target = document.querySelector('mydiv')
// create an observer instance
var observer = new MutationObserver(function(mutations) {
  console.log($('mydiv').text());   
});
// 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);

6
यह सही उत्तर है क्योंकि यह अब DOMSubtreeModified का उपयोग करने के पक्ष में है
जोएल डेवी

3
मुझे इसके साथ त्रुटि हो रही है, भले ही मैंने सही चयनकर्ता दिया हो। "VM21504: 819 बिना पढ़े टाइपर: 'म्यूटेशनऑब्जर्वर' पर 'अवलोकन' निष्पादित करने में विफल: पैरामीटर 1 प्रकार 'नोड' का नहीं है।"
समीर

54

जब $("#selector").bind()से पदावनत किया गया है , आपको उपयोग करना चाहिए:

$("body").on('DOMSubtreeModified', "#selector", function() {
    // code here
});

1
यह विभेदक कारक था, यह #इंगित करने के लिए कि प्रतीक चयनकर्ता से पहले जाना चाहिए।
क्रिस - जूनियर

42

आप यह कोशिश कर सकते हैं

$('.myDiv').bind('DOMNodeInserted DOMNodeRemoved', function() {

});

लेकिन यह इंटरनेट एक्सप्लोरर में काम नहीं कर सकता है, इसका परीक्षण नहीं किया है


10
सही किया गया: developer.mozilla.org/en-US/docs/Web/Guide/Events/… इसके बजाय का उपयोग करें: developer.mozilla.org/en-US/docs/Web/API/MutationObverver
रान्डेल

3
नोट !: यदि आप इसे ट्रिगर के लिए उपयोग करते हैं और पृष्ठ में बहुत सारे बदलाव किए जा रहे हैं - तो यह आपके फ़ंक्शन को एक्स बार (शायद एक्स = 1,000 या अधिक) चलाएगा जो बहुत अक्षम हो सकता है। एक सरल उपाय यह है कि "चल रहा" बूलियन संस्करण को परिभाषित किया जाए, जो कि ... (चल रहा है == सच) {वापसी} ... आपके कोड को चलाने के बिना अगर यह पहले से ही चल रहा है। अपने तर्क के बाद सही = सही चल रहा है, और चल रहा है, अपने कार्य से पहले = गलत चल रहा है। आप अपने फ़ंक्शन को सीमित करने के लिए एक टाइमर का उपयोग कर सकते हैं, केवल हर एक्स सेकंड चलाने में सक्षम हो। चल = true setTimeout (function () {चल = false}, 5000); (या कुछ बेहतर)
JxAxMxIxN

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

2
@JxAxMxIxN आप टाइमआउट टाइमर को क्लियर करके और टाइमआउट को फिर से सेट कर सकते हैं:clearTimeout(window.something); window.something = setTimeout(...);
Ctrl-C

सहमत - आपका रास्ता जाने का रास्ता है - पाइथन सीखने के बाद से मैंने कई भाषाओं में अपनी खराब कोडिंग प्रथाओं को पूरा किया है (सभी नहीं, बस बहुत सारे?)
JxAxMxIxN

33

आप MutationObserver या Mutation Events की तलाश कर रहे हैं । न तो हर जगह समर्थन किया जाता है और न ही डेवलपर दुनिया द्वारा बहुत शौक से देखा जाता है।

यदि आप जानते हैं (और यह सुनिश्चित कर सकते हैं कि) div का आकार बदल जाएगा, तो आप क्रॉसब्रोसर रिसाइज़ ईवेंट का उपयोग करने में सक्षम हो सकते हैं ।


1
यही तो है वो। विशेष रूप से, DOMSubtreeModified । आपको म्यूटेशन-सारांश लाइब्रेरी उपयोगी हो सकती है , और DOM ट्री इवेंट्स की यह सूची ।
बेंजामिनरह

1
इस घटना को डेवलपर ने
Adrien Be

9
किसी और को हर जगह हर चीज के माध्यम से पढ़ने की कोशिश करनी है, यह सही उत्तर है। म्यूटेशन इवेंट्स को पिछले ब्राउज़र में सपोर्ट किया गया था, Mutation Observer वह है जो आधुनिक ब्राउज़र में समर्थित है और भविष्य में समर्थित होगा। समर्थन के लिए लिंक देखें: CANIUSE Mutation Observer
Josh Mc

20

निम्नलिखित कोड मेरे लिए काम करता है।

$("body").on('DOMSubtreeModified', "mydiv", function() {
    alert('changed');
});

आशा है कि यह किसी की मदद करेगा :)


यह उसी तरह का उत्तर है जैसे @Artley
Black

@ ब्लैंक थैंक्यू! मेरे पास केवल आर्टली उत्तर की जांच है। मैं अगली बार इसका ध्यान रखूंगा।
संचित गुप्ता

17

इस समस्या का कोई इनबिल्ट समाधान नहीं है, यह आपके डिज़ाइन और कोडिंग पैटर्न के साथ एक समस्या है।

आप प्रकाशक / ग्राहक पैटर्न का उपयोग कर सकते हैं। इसके लिए आप jQuery के कस्टम इवेंट या अपने स्वयं के ईवेंट तंत्र का उपयोग कर सकते हैं।

प्रथम,

function changeHtml(selector, html) {
    var elem = $(selector);
    jQuery.event.trigger('htmlchanging', { elements: elem, content: { current: elem.html(), pending: html} });
    elem.html(html);
    jQuery.event.trigger('htmlchanged', { elements: elem, content: html });
}

अब आप निम्न के रूप में divhtmlchanging / divhtmlchanged घटनाओं की सदस्यता ले सकते हैं,

$(document).bind('htmlchanging', function (e, data) {
    //your before changing html, logic goes here
});

$(document).bind('htmlchanged', function (e, data) {
    //your after changed html, logic goes here
});

अब, आपको इस changeHtml()फ़ंक्शन के माध्यम से अपनी div सामग्री में परिवर्तन करना होगा। तो, आप निगरानी कर सकते हैं या तदनुसार आवश्यक परिवर्तन कर सकते हैं क्योंकि जानकारी से युक्त कॉलबैक डेटा तर्क को बांधें।

आपको अपने div के html को इस तरह बदलना होगा;

changeHtml('#mydiv', '<p>test content</p>');

और इसके अलावा, आप इनपुट तत्व को छोड़कर किसी भी html तत्व (एस) के लिए इसका उपयोग कर सकते हैं। वैसे भी आप इसे किसी भी तत्व (एस) के साथ उपयोग करने के लिए संशोधित कर सकते हैं।


किसी विशेष तत्व में परिवर्तन पर देखने और कार्य करने के लिए, केवल 'jQuery.event.trigger (...)' के बजाय 'elem.trigger (...)' का उपयोग करने के लिए changeHtml फ़ंक्शन को संशोधित करें, और फिर जैसे तत्व को बांधें $ ('# my_element_id')। ('htmlchanged', function (e, data) {...}
KenB

8
"यह आपके डिजाइन और कोडिंग पैटर्न के साथ एक समस्या है", क्या करें यदि आप तीसरे पक्ष की स्क्रिप्ट शामिल करते हैं इसलिए आपके स्रोत कोड पर आपका कोई नियंत्रण नहीं है? लेकिन आपको एक div में उनके परिवर्तनों का पता लगाने की आवश्यकता है?
DrLightman

@DrLightman अंगूठे का एक नियम कॉलबैक घटना के साथ तीसरे पक्ष के काम का चयन करने के लिए प्रदान की जाती है
Marcel Djaman

8

MutillaObserver का उपयोग करें जैसा कि मोज़िला द्वारा प्रदान की गई इस स्निपेट में देखा गया है , और इस ब्लॉग पोस्ट से अनुकूलित किया गया है

वैकल्पिक रूप से, आप इस लिंक में देखे गए JQuery के उदाहरण का उपयोग कर सकते हैं

क्रोम 18+, फ़ायरफ़ॉक्स 14+, IE 11+, सफारी 6+

// Select the node that will be observed for mutations
var targetNode = document.getElementById('some-id');

// Options for the observer (which mutations to observe)
var config = { attributes: true, childList: true };

// Callback function to execute when mutations are observed
var callback = function(mutationsList) {
    for(var mutation of mutationsList) {
        if (mutation.type == 'childList') {
            console.log('A child node has been added or removed.');
        }
        else if (mutation.type == 'attributes') {
            console.log('The ' + mutation.attributeName + ' attribute was modified.');
        }
    }
};

// Create an observer instance linked to the callback function
var observer = new MutationObserver(callback);

// Start observing the target node for configured mutations
observer.observe(targetNode, config);

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

3

आप div के पुराने आंतरिक HTML को एक चर में संग्रहीत कर सकते हैं। पुरानी सामग्री वर्तमान सामग्री से मेल खाती है या नहीं यह जाँचने के लिए एक अंतराल सेट करें। जब यह सच नहीं है तो कुछ करो।


1

MutationObserver आज़माएं:

ब्राउज़र समर्थन: http://caniuse.com/#feat=mutationobserver

<html>
  <!-- example from Microsoft https://developer.microsoft.com/en-us/microsoft-edge/platform/documentation/dev-guide/dom/mutation-observers/ -->

  <head>
    </head>
  <body>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script type="text/javascript">
      // Inspect the array of MutationRecord objects to identify the nature of the change
function mutationObjectCallback(mutationRecordsList) {
  console.log("mutationObjectCallback invoked.");

  mutationRecordsList.forEach(function(mutationRecord) {
    console.log("Type of mutation: " + mutationRecord.type);
    if ("attributes" === mutationRecord.type) {
      console.log("Old attribute value: " + mutationRecord.oldValue);
    }
  });
}
      
// Create an observer object and assign a callback function
var observerObject = new MutationObserver(mutationObjectCallback);

      // the target to watch, this could be #yourUniqueDiv 
      // we use the body to watch for changes
var targetObject = document.body; 
      
// Register the target node to observe and specify which DOM changes to watch
      
      
observerObject.observe(targetObject, { 
  attributes: true,
  attributeFilter: ["id", "dir"],
  attributeOldValue: true,
  childList: true
});

// This will invoke the mutationObjectCallback function (but only after all script in this
// scope has run). For now, it simply queues a MutationRecord object with the change information
targetObject.appendChild(document.createElement('div'));

// Now a second MutationRecord object will be added, this time for an attribute change
targetObject.dir = 'rtl';


      </script>
    </body>
  </html>


0

एक div में कुछ सामग्री जोड़ना, चाहे jQuery के माध्यम से या सीधे डी-डोम-एपीआई के माध्यम से, .appendChild()फ़ंक्शन को डिफॉल्ट करता है। आप जो भी कर सकते हैं वह .appendChild()वर्तमान वस्तु के कार्य को ओवरराइड करने और इसमें एक पर्यवेक्षक को लागू करने के लिए है। अब हमारे .appendChild()फ़ंक्शन को ओवरराइड कर दिया गया है, हमें कंटेंट को जोड़ने में सक्षम होने के लिए उस फ़ंक्शन को किसी अन्य ऑब्जेक्ट से उधार लेने की आवश्यकता है। हम .appendChild()अंत में सामग्री को जोड़ने के लिए एक दूसरे div के कॉल करते हैं । बेशक, इस के लिए भी मायने रखता है .removeChild()

var obj = document.getElementById("mydiv");
    obj.appendChild = function(node) {
        alert("changed!");

        // call the .appendChild() function of some other div
        // and pass the current (this) to let the function affect it.
        document.createElement("div").appendChild.call(this, node);
        }
    };

यहां आप एक भोली उदाहरण पा सकते हैं। आप इसे अपने हिसाब से बढ़ा सकते हैं। http://jsfiddle.net/RKLmA/31/

वैसे: यह दिखाता है कि जावास्क्रिप्ट OpenClosed priciple का अनुपालन करता है। :)


यह बच्चे के साथ काम नहीं करता है ... मैं वास्तव में इसे अन्य कार्यों के माध्यम से संशोधित करता हूं।
BoqBoq

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