简体   繁体   中英

Listen for change of class in jquery

Is there a way in jquery to listen for a change to a node's class and then take some action on it if the class changes to a specific class? Specifically, I'm using the jquery tools tabs plugin with the slideshow and as the slideshow is playing, I need to be able to detect when the focus is on a particular tab/anchor so that I can unhide a specific div.

In my specific example, I need to know when:

<li><a class="nav-video" id="nav-video-video7" href="#video7-video">Video Link 7</a></li>

changes to the following with the class "current" added:

<li><a class="nav-video" id="nav-video-video7 current" href="#video7-video">Video Link 7</a></li>

Then I want to unhide a div at that moment.

Thanks!

You can bind the DOMSubtreeModified event. I add an example here:

 $(document).ready(function() { $('#changeClass').click(function() { $('#mutable').addClass("red"); }); $('#mutable').bind('DOMSubtreeModified', function(e) { alert('class changed'); }); }); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="mutable" style="width:50px;height:50px;">sjdfhksfh <div> <div> <button id="changeClass">Change Class</button> </div> 

http://jsfiddle.net/hnCxK/13/

Here are some other finds that might provide a solution:

  1. Most efficient method of detecting/monitoring DOM changes?
  2. How can I detect when an HTML element's class changes?
  3. Monitoring DOM Changes in JQuery

And as it was suggested in #2, why not make current a class that is added, rather than a ID, and have the following CSS handle the show/hide action.

<style type='text/css>
    .current{display:inline;}
    .notCurrent{display:none;}
</style>

Might also be worth it to look into .on() in jquery .

With anything like this you have essentially two options, callbacks or polling.

Since you possibly can't get an event to be triggered when the DOM mutates in this way (reliably across all platforms) you may have to resort to polling. To be a bit nicer about it, you could try using the requestAnimationFrame api rather than just using something like setInterval natively.

Taking the most basic approach (ie using setInterval and assuming jQuery) you might try something like this:

var current_poll_interval;
function startCurrentPolling() {
  current_poll_interval = setInterval(currentPoll, 100);
}
function currentPoll() {
  if ( $('#nav-video-7').hasClass('current') ) {
    // ... whatever you want in here ...
    stopCurrentPolling();
  }
}
function stopCurrentPolling() {
  clearInterval(current_poll_interval);
}

I know this is old, but the accepted answer uses DOMSubtreeModified , which has now been deprecated for the MutationObserver . Here's an example using jQuery (test it out here ):

// Select the node that will be observed for mutations
let targetNode = $('#some-id');

// Options for the observer (which mutations to observe)
const config = { attributes: true, childList: false, subtree: false, attributeFilter: ['class'] };

// Callback function to execute when mutations are observed
const callback = function(mutationsList, observer) {
    for (let mutation of mutationsList) {
        if (mutation.attributeName === "class") {
            var classList = mutation.target.className;
            // Do something here with class you're expecting
            if(/red/.exec(classList).length > 0) {
                console.log('Found match');
            }
        }
    }
};

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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM