23

I am using a plugin that added a class open to .slide-out-div when opened.

So I am trying to change some css if the open is detected.

What I need to do is

IF

$('.slide-out-div **open**') IS Detected then

$('.otherDiv').css('top','0px');

Not sure how to put this together...

gdoron
  • 147,333
  • 58
  • 291
  • 367
Satch3000
  • 47,356
  • 86
  • 216
  • 346

3 Answers3

31

The question's a bit old, but since I came across while looking for a similar problem, thought I'd share the solution I went with here - Mutation Observers

In your case, I'd create a mutation observer

var mut = new MutationObserver(function(mutations, mut){
  // if attribute changed === 'class' && 'open' has been added, add css to 'otherDiv'
});
mut.observe(document.querySelector(".slide-out-div"),{
  'attributes': true
});

The function in mutation observer is called any time an attribute of .slide-out-div is changed, so need to verify the actual change before acting.

More details here on Mozilla's documentation page

Stefano Ortisi
  • 5,288
  • 3
  • 33
  • 41
Adi B
  • 1,189
  • 13
  • 32
31

There is no event of class-added, you will need to track it yourself...

It can be done with an infinite loop with setTimeout to check if the class has changed.

function checkForChanges()
{
    if ($('.slide-out-div').hasClass('open'))
        $('.otherDiv').css('top','0px');
    else
        setTimeout(checkForChanges, 500);
}

You can call the function when you want, or onDOM ready:

$(checkForChanges);
gdoron
  • 147,333
  • 58
  • 291
  • 367
  • 62
    This will work. However, it's a very dirty approach if you ask me. – dubbelj Mar 07 '12 at 11:09
  • It seems a working solution can be found here: http://stackoverflow.com/a/1397500/439944 – sieppl Mar 09 '12 at 09:57
  • 17
    @sieppl. `mutation events` are **deprecated** as they have huge performance impact. – gdoron Mar 10 '12 at 21:17
  • 1
    @gdoron. +1 for mentioning this. – sieppl Mar 11 '12 at 17:47
  • 7
    @gdoron - They aren't deprecated! (check MDN) the OLD ones are, the mutation observer is the new way of detecting changes. here's how - http://stackoverflow.com/a/14570614/104380 – vsync May 25 '14 at 09:28
  • Done is better than perfect. +1 – Dylan Valade May 29 '15 at 21:47
  • Always prefer a setInterval solution over setTimeout when you use this kind of recursion. Cause your stack can endless grow. – Healkiss May 26 '16 at 07:48
  • 1
    @Healkiss it is exactly the same. The stack won't endless grow. – gdoron May 26 '16 at 07:52
  • 1
    @vsync you are aware your comment was written to years after the answer was given, right...? Anyway, the new mutation events have limited support. (For future readers) – gdoron May 26 '16 at 07:55
  • @gdoron You make me review my basics. Thanks, you're right. – Healkiss May 26 '16 at 07:58
  • 1
    @Healkiss it's funny how stuff work at stack overflow. People down vote without knowing the basics... well that's the internet, you can love it or hate it, but that's what it is. – gdoron May 26 '16 at 08:01
  • @gdoron. First, i beg your pardon. I didn't down vote for this in particular. It's a dirty solution. Many other, like DOMSubtreeModified, overridding addClass are prettiest solutions. In term of performance. Don't be offended." I " think we should avoid setInterval and SetTimeout when possible. Especially in this case where you should low the interval to the minimum to be reactive. – Healkiss May 26 '16 at 08:21
  • 1
    @Healkiss I didn't got offended, but if you want both performance and all browsers support, this is the best solution. Mutation events(at least when this answer was given, were deprecated and **huge** bad performance impact, I stopped following its state so I don't know how it's today) – gdoron May 26 '16 at 08:25
15

You can use attrchange jQuery plugin. The main function of the plugin is to bind a listener function on attribute change of HTML elements.

Code sample:

$("#myDiv").attrchange({
    trackValues: true, // set to true so that the event object is updated with old & new values
    callback: function(evnt) {
        if(evnt.attributeName == "class") { // which attribute you want to watch for changes
            if(evnt.newValue.search(/open/i) == -1) { // "open" is the class name you search for inside "class" attribute

                // your code to execute goes here...
            }
        }
    }
});
Muhammad Reda
  • 26,379
  • 14
  • 93
  • 105