7

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.

Lukas
  • 7,384
  • 20
  • 72
  • 127
  • 1
    The `attrName` property isn't part of jQuery's event's object...you need to use `e.originalEvent.attrName` – Ian Jun 18 '13 at 15:15
  • 1
    Unrelated, But Mutation events have been deprecated. You may probably want to take a look at Mutation Observers – PSL Jun 18 '13 at 15:16
  • 1
    @PSL 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 `MutationObserver` – Ian Jun 18 '13 at 16:27
  • 1
    @Ian 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](http://stackoverflow.com/questions/16990573/how-to-bind-bootstrap-popover-on-dynamic-elements/16991216#16991216) before. :) – PSL Jun 18 '13 at 16:31
  • @PSL 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 up – Ian Jun 18 '13 at 16:36

1 Answers1

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:

Ian
  • 50,146
  • 13
  • 101
  • 111
  • @Lukas 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: http://help.dottoro.com/ljfvvdnm.php#additionalEvents – Ian Jun 18 '13 at 15:34
  • @Lukas 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 cases – Ian Jul 16 '13 at 17:03
  • 1
    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. – Lukas Jul 17 '13 at 07:02
  • 1
    @Lukas No problem at all, I just wanted to make sure you weren't still having trouble with it. Glad it helped/works! – Ian Jul 17 '13 at 15:21