jQuery ইভেন্ট: একটি ডিভির এইচটিএমএল / পাঠ্যে পরিবর্তনগুলি সনাক্ত করুন


265

আমি একটি div যা এর বিষয়বস্তু সব সময় পরিবর্তন হয়েছে আছে, এটা হতে ajax requests, jquery functions, blurইত্যাদি ইত্যাদি

সময় মতো কোনও সময়ে আমি আমার ডিভিতে কোনও পরিবর্তন সনাক্ত করতে পারি এমন কোন উপায় আছে কি?

আমি কোনও অন্তর বা ডিফল্ট মান পরীক্ষিত ব্যবহার করতে চাই না।

এরকম কিছু করবে

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

5
সম্ভাব্য সদৃশ: স্ট্যাকওভারফ্লো.com
রব

14
@ রব এটি একটি keypressইভেন্টকে একটি বিতর্কিত উপাদানকে বাধ্য করছে <div>। আমি নিশ্চিত না যে সেখানকার সমাধানগুলি এর জন্য প্রযোজ্য। তারা অবশ্যই কোনও উপাদানের সামগ্রীতে কোনও প্রোগ্রাম্যাটিক পরিবর্তন গ্রহণ করবে না।
অ্যান্থনি গ্রিস্ট

উত্তর:


406

আপনি যদি টাইমার ব্যবহার করতে চান না এবং অভ্যন্তরীণ এইচটিএমএল পরীক্ষা করতে চান তবে আপনি এই ইভেন্টটি চেষ্টা করতে পারেন

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

আরও বিশদ এবং ব্রাউজার সমর্থন ডেটা এখানে

মনোযোগ দিন: নতুন jQuery সংস্করণে বাইন্ড () হ্রাস করা হয়েছে, সুতরাং এর পরিবর্তে আপনার () ব্যবহার করা উচিত:

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

14
মনে রাখবেন ডিওএমএস সাবট্রি মডিডাইফড আইই 8 (এবং নীচে) সমর্থন করে না।
গাভিন

56

3
মজিলা 33: <<< এলিমেন্টের জন্য পুনরাবৃত্তি হতে পারে। অন্য কোনও উপায় খুঁজে পাওয়া দরকার
চকী_ব্ল্যাক

17
এটি গুরুতর এই ইভেন্টটি ব্যবহার করবেন না এটি আপনার সমস্ত কাজের ক্রাশ হয়ে যাবে কারণ এটি সর্বদা বহিস্কার করা হয়। পরিবর্তে $ ('। MyDiv') এর নীচে ইভেন্টগুলি ব্যবহার করুন b বাঁধন ('DOMNodeInsert DOMNodeRemoved', ফাংশন () {});
জর্জি শেড্রা

19
এই পদ্ধতিটি অবমূল্যায়ন করা হয়েছে! পরিবর্তে ব্যবহার করুন:$("body").on('DOMSubtreeModified', "mydiv", function() { });
আসিফ

55

জাভাস্ক্রিপ্ট মিউটেশনঅবসভার ব্যবহার করে

  //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
এটিই সঠিক উত্তর হিসাবে এখন এটি ডিওএমএস সাবট্রি মডিডাইফড
জোয়েল ডেভি

3
আমি সঠিক নির্বাচক দিলেও এর সাথে আমি ত্রুটি পাচ্ছি। "ভিএম 21504: 819 আনচাট টাইপ এরির: 'মিউটেশনঅবার্সার'-এ' পর্যবেক্ষণ 'কার্যকর করতে ব্যর্থ: প্যারামিটার 1' নোড 'টাইপের নয়" "
সমীর

54

যেহেতু $("#selector").bind()অবহেলিত , তাই আপনার ব্যবহার করা উচিত:

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

1
এটি পৃথকীকরণকারী কারণ ছিল, #প্রতীকটি অবশ্যই নির্বাচকের আগে অবশ্যই যেতে হবে indicate
ক্রিস - জুন

42

আপনি এটি চেষ্টা করতে পারেন

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

});

তবে এটি ইন্টারনেট এক্সপ্লোরার এ কাজ করতে পারে না, এটি পরীক্ষা করে নি



3
দ্রষ্টব্য: আপনি যদি এটি ট্রিগারটির জন্য ব্যবহার করেন এবং পৃষ্ঠায় অনেকগুলি পরিবর্তন আনা হচ্ছে - এটি আপনার ফাংশনটি এক্স বার (সম্ভবত এমনকি এক্স = 1000 বা আরও বেশি) চালাবে যা খুব অকার্যকর হতে পারে। একটি সহজ সমাধান হ'ল "চলমান" বুলিয়ান ভার সংজ্ঞায়িত করা, যা ... যদি (চলমান == সত্য) {ফেরত। ... আপনার কোডটি ইতিমধ্যে চালু না করে চালিয়ে দিবে। আপনার চলমান যুক্তির পরে চলমান = আসল ডানদিকে সেট করুন, এবং আপনার ক্রিয়াকলাপটি প্রস্থান হওয়ার আগে চলমান = মিথ্যা। আপনি কেবল প্রতিটি এক্স সেকেন্ডে চালাতে সক্ষম হয়ে নিজের ফাংশনকে সীমাবদ্ধ করতে টাইমার ব্যবহার করতে পারেন। চলমান = সত্য; setTimeout (ফাংশন () {চলমান = মিথ্যা}, 5000); (বা আরও ভাল কিছু)
JxAxMxIxN

আমি এটি একটি নির্বাচিত বাক্সে ব্যবহার করেছি যাতে বিকল্পগুলি যুক্ত এবং সরানো হচ্ছে। আইটেমগুলি যুক্ত করার সময় এটি দুর্দান্ত কাজ করেছে তবে অপসারণটি 1 টি আইটেমের পিছনে বলে মনে হয়েছে। শেষ বিকল্পটি সরিয়ে ফেলা হবে না।
কোডমনকি

2
@ জেএক্সএক্সএমএক্সএনএন আপনি সময়সীমা টাইমারটি সাফ করে আবার টাইমআউট সেট করেও করতে পারেন:clearTimeout(window.something); window.something = setTimeout(...);
Ctrl-C

সম্মত - আপনার
পথটি

33

আপনি খুঁজছেন মিউটেশনঅবার্সার বা মিউটেশন ইভেন্টগুলি সন্ধান করছেন । ডেভেলপার ওয়ার্ল্ডও উভয়কেই সমর্থিত নয় বা খুব স্নেহপূর্ণভাবে দেখে না।

আপনি যদি জানেন (এবং এটি নিশ্চিত করতে পারেন) যে ডিভের আকার পরিবর্তন হবে তবে আপনি ক্রসব্রোজারের আকার পরিবর্তন ইভেন্টটি ব্যবহার করতে সক্ষম হতে পারেন ।


1
এটিই সেইটি. বিশেষত, ডিওএমএসব্রিডি মডিডাইফড । আপনি মিউটেশন-সারসংক্ষেপ গ্রন্থাগারটি সহায়ক এবং DOM ট্রি ইভেন্টগুলির এই তালিকাটি পেতে পারেন ।
বেনজামিনআরএইচ


9
অন্য যে কোনও ব্যক্তিকে সর্বত্র সমস্ত জায়গায় পড়ার চেষ্টা করতে হবে, এটি সঠিক উত্তর। মিউটেশন ইভেন্টগুলি পূর্ববর্তী ব্রাউজারগুলিতে সমর্থিত ছিল, মিউটেশন পর্যবেক্ষক যা আধুনিক ব্রাউজারগুলিতে সমর্থিত এবং ভবিষ্যতে সমর্থন করা হবে। সমর্থনের জন্য লিঙ্কটি দেখুন: কানেকশন মিউটেশন পর্যবেক্ষক
জোশ ম্যাক

21

নিম্নলিখিত কোডটি আমার পক্ষে কাজ করে।

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

আশা করি এটি কাউকে সাহায্য করবে :)


এই @Artley থেকে এক হিসাবে একই উত্তর
ব্ল্যাক

নিবন্ধন করুন আমি শুধু আর্টলি উত্তর চেক করেছি। আমি পরবর্তী সময় এই যত্ন নিতে হবে।
সংচিত গুপ্ত

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 });
}

এখন আপনি DivhtML পরিবর্তন / DivhtML পরিবর্তন ইভেন্টগুলি সাবস্ক্রাইব করতে পারেন নিম্নলিখিত হিসাবে,

$(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()ফাংশনের মাধ্যমে আপনার ডিভ সামগ্রী পরিবর্তন করতে হবে । সুতরাং, আপনি তদারকি করতে পারেন বা তদনুসারে প্রয়োজনীয় পরিবর্তনগুলি করতে পারেন কারণ তথ্য সম্বলিত কলব্যাক ডেটা যুক্তি বাঁধুন।

আপনাকে এইভাবে আপনার ডিভের এইচটিএমএল পরিবর্তন করতে হবে;

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

এবং এছাড়াও, আপনি ইনপুট উপাদান ব্যতীত অন্য কোনও HTML উপাদান (গুলি) এর জন্য এটি ব্যবহার করতে পারেন। যাইহোক আপনি যে কোনও উপাদান (গুলি) এর সাথে ব্যবহার করতে এটি পরিবর্তন করতে পারেন।


কোনও নির্দিষ্ট উপাদানের পরিবর্তনগুলি পর্যবেক্ষণ ও কাজ করতে, 'jQuery.event.trigger (...)' এর পরিবর্তে 'elem.trigger (...)' ব্যবহার করার জন্য পরিবর্তনের HTML ফাংশনটি পরিবর্তন করুন এবং তারপরে উপাদানটির সাথে আবদ্ধ করুন $ ('# আমার_এলিমেন্ট_আইডি')। ('এইচটিএমএল পরিবর্তনশীল', ফাংশন (ই, ডেটা) {...}
কেনবি

8
"এটি আপনার নকশা এবং কোডিং প্যাটার্নের সাথে সমস্যা", আপনি যদি তৃতীয় পক্ষের স্ক্রিপ্টগুলি অন্তর্ভুক্ত করেন তবে তাদের সোর্স কোডে আপনার কোনও নিয়ন্ত্রণ নেই? তবে আপনার তাদের পরিবর্তনগুলি একটি ডিভে সনাক্ত করতে হবে?
DrLightman

@ ডিআরলাইটম্যানকে থাম্বের একটি বিধি দেওয়া হল কলব্যাক ইভেন্ট সরবরাহের সাথে তৃতীয় পক্ষের
লাইব বেছে নেওয়া

8

মজিলার সরবরাহিত এই স্নিপেটে যেমন দেখা হয়েছে তেমন রূপান্তরকেন্দ্র ব্যবহার করুন এবং এই ব্লগ পোস্টটি থেকে অভিযোজিত

বিকল্পভাবে, আপনি এই লিঙ্কটিতে দেখা JQuery উদাহরণ ব্যবহার করতে পারেন

ক্রোম 18+, ফায়ারফক্স 14+, আইই 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

আপনি একটি পরিবর্তনশীল মধ্যে ডিভ পুরানো অভ্যন্তরীণ এইচটিএমএল সংরক্ষণ করতে পারেন। পুরানো সামগ্রীটি বর্তমান সামগ্রীর সাথে মেলে কিনা তা পরীক্ষা করার জন্য একটি বিরতি সেট করুন। যখন এটি সত্য না হয় তখন কিছু করুন।


1

মিউটেশনঅবার্সার চেষ্টা করুন:

ব্রাউজার সমর্থন: http://caniuse.com/#feat=mutesobserver

<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

ডিভিউতে কিছু বিষয়বস্তু যুক্ত করা, jQuery এর মাধ্যমে বা সরাসরি ডি ডোম-এপিআইয়ের মাধ্যমে, .appendChild()ফাংশনে ডিফল্ট । আপনি যা করতে পারেন তা হ'ল .appendChild()বর্তমান অবজেক্টের ক্রিয়াকে ওভাররাইড করে এবং এটিতে একটি পর্যবেক্ষক প্রয়োগ করা। এখন আমাদের .appendChild()ফাংশনটি ওভাররাইড করে রেখে, বিষয়বস্তু সংযোজন করতে সক্ষম হতে আমাদের অন্য কোনও বিষয় থেকে সেই ফাংশনটি ধার করতে হবে। এর জন্য আমরা .appendChild()শেষ পর্যন্ত সামগ্রীটি সংযুক্ত করতে অন্য একটি ডিভের কল করি । অবশ্যই, এই জন্য গণনা .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);
        }
    };

এখানে আপনি একটি naïf উদাহরণ খুঁজে পেতে পারেন। আপনি নিজেই এটি বাড়িয়ে দিতে পারেন বলে আমার ধারণা। http://jsfiddle.net/RKLmA/31/

যাইহোক, এটি জাভাস্ক্রিপ্ট ওপেনক্লসড প্রসিপেলকে মেনে চলে। :)


এটি অ্যাপেন্ড চাইল্ডের সাথে কাজ করে না ... আমি অন্যান্য ফাংশনগুলির মাধ্যমে এটির এইচটিএমএলটি আসলেই সংশোধন করি।
BoqBoq

চাইল্ড () রিপ্লেসচাইল্ড () ইত্যাদি পছন্দ করুন তবে আপনি ঠিক অভ্যন্তরীণ এইচটিএমএল এ আছেন। আপনার এটি কোনওভাবে এড়ানো উচিত।
অ্যান্ড্রিজ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.