How to detect class changing by DOMAttrModified
Asked Answered
C

1

8

I need to detect some class changing, i use for this DOMAttrModified, but something is wrong, what?

var first_img = $('body').find('li:first').find('img');

first_img.on('DOMAttrModified',function(e){
    if (e.attrName === 'class') {
        if ($(this).hasClass('current-image')) {
            $(this).removeClass().addClass('previous-image');
        }
        console.log('log');
    }
});

Thx for advice.

Cosmo answered 18/6, 2013 at 15:9 Comment(5)
The attrName property isn't part of jQuery's event's object...you need to use e.originalEvent.attrNameWhoa
Unrelated, But Mutation events have been deprecated. You may probably want to take a look at Mutation ObserversEisegesis
@Eisegesis I'd definitely say that's related. Mentioning deprecation is very important, so great point. And I saw your comment on my answer - sorry, we must've created our own fiddles and posted them around the same time. When I saw your comment here, I realized it would be a good idea to at least give an example with MutationObserverWhoa
@Whoa In fact i did not have your answer refreshed so thought of posting it in as comment, then i saw you already had updated Urs :). No issues i did +1 urs for similar thoughts. :) Infact i had explored this while answering a bootstrap related question before. :)Eisegesis
@Eisegesis No problem, I would've gladly added your fiddle if I hadn't already done it, and I appreciate it! Cool, thanks for the link. And yeah, I've definitely heard of these features, I've just never explored/used them, so it's interesting setting it upWhoa
W
14

The immediate problem is that a attrName property isn't part of jQuery's event's object...you need to use e.originalEvent.attrName. Here's an example of it working:

var first_img = $("body").find("div").first();

first_img.on("DOMAttrModified", function (e) {
    if (e.originalEvent.attrName === "class") {
        console.log("##DOMAttrModified, class changed");
        if ($(this).hasClass("current-image")) {
            console.log("##Element has 'current-image' class, changing");
            $(this).removeClass().addClass("previous-image");
        }
    }
});

setTimeout(function () {
    first_img.addClass("current-image");
}, 1000);

DEMO: http://jsfiddle.net/R5rTy/1/

The setTimeout is to simulate the event randomly happening.

Apparently, the DOMAttrModified event is not supported in all browsers - http://help.dottoro.com/ljfvvdnm.php#additionalEvents


UPDATE:

Using the newer MutationObserver, the following shows the use of both ideas:

var firstImg, observerConfig, firstImgObserver;

firstImg = $("body").find("div").first();
observerConfig = {
    attributes: true,
    childList: true,
    characterData: true
};
firstImgObserver = new MutationObserver(function (mutations) {
    mutations.forEach(function (mutation) {
        var newVal = $(mutation.target).prop(mutation.attributeName);
        if (mutation.attributeName === "class") {
            console.log("MutationObserver class changed to", newVal);
        } else if (mutation.attributeName === "id") {
            console.log("MutationObserver id changed to", newVal);
        }
    });
});

firstImgObserver.observe(firstImg[0], observerConfig);
// later, you can stop observing
//observer.disconnect();

firstImg.on("DOMAttrModified", function (e) {
    var newVal = $(this).prop(e.originalEvent.attrName);
    console.log("DOMAttrModified", e.originalEvent.attrName, "changed to", newVal);
});

setTimeout(function () {
    firstImg.addClass("previous-image").addClass("fdsa");
}, 1000);

DEMO: http://jsfiddle.net/ybGCF/

Reference:

Whoa answered 18/6, 2013 at 15:21 Comment(4)
@Cosmo Let me guess...testing in Chrome or IE? I was testing in FireFox and it works fine for me there, but decided to test in Chrome and found it didn't work. It looks like it's not supported in all browsers: help.dottoro.com/ljfvvdnm.php#additionalEventsWhoa
@Cosmo I forgot to mention - I updated my answer a long time ago to also use MutationObserver, which has different browser support. Hopefully my answer now covers enough casesWhoa
In fact, it took advantage of your solution, and I forgot to add some up vote. Thank you very much for your help, everything running smoothly.Cosmo
@Cosmo No problem at all, I just wanted to make sure you weren't still having trouble with it. Glad it helped/works!Whoa

© 2022 - 2024 — McMap. All rights reserved.