views:

53

answers:

2

Hi,

Is there a way to trigger a event in jQuery when an elements classes are changed?

Examples:

<img class="selected" />

into

<img class="selected newclass" />

triggers an event


And

<img class="selected" />

into

<img class="" />

trigger an event

A: 

I do not think this is possible.

Events are based on user actions so click,dblclick,mouseover etc are all user actions.

You may want to devise some kind of data block on each element and then build a small system that integrates into jQuery .class() and .attr() methods so that when your code updates a class it will add data to that element holding the previous class,

then if the previous class is different to class being set then trigger your events.

What i mean by integrate is

var old_ClassFunc = $.fn.class; //Save it

var $.fn.class = function()
{
   if($(this).data('old-class'))
   {
      if($(this).data('class_callback'))#
      {
          $(this).data('class_callback')(this);
      }
   }
   $(this).data('old-class',$(this).attr('class')); //Update Data
   return old_class.apply(this,arguments);
}

then you can do like

$('element').data('class_callback',function(context){
   alert('Element class has changed');
})

Hope this gives you some help

RobertPitt
+5  A: 

You might be able to workaround on a little hacky way. Hook .addClass() & .removeClass() like so:

var _addClass    = $.fn.addClass,
    _removeClass = $.fn.removeClass;

$.fn.addClass    = function(){
    // do whatever here
    return _addClass.apply(this, arguments);
}

$.fn.removeClass = function(){
    // do whatever here
    return _removeClass.apply(this, arguments);
}

That way, assuming you are just interested in watching elements class changes with jQuery, you can trigger whatever code on adding or removing classes. Again, just if you are using jQuery, for this example.

Of course, you can hook and overwrite any javascript function that way.

As Nick Craver mentioned in a comment, there are several other jQuery methods which can add or remove an elements class. You would have to hook all of those, namely:

.addClass()
.removeClass()
.toggleClass()
.removeAttr('class')
.attr('class', 'changed')

unless you know exactly which methods are called to manipulate a class, you would have to care about all of those.

jAndy
+1 for coming up with this idea..!
Kai
+1 Elegant solution.
jensgram
Elegant, but be aware of other methods here, `.toggleClass()`, `.attr('class')`, `.class = `, there are a *lot* of ways to change a class. I'm thinking there's an even simpler solution, but need to know what the OP is after. Also `.addClass('alreadyHadThisClass')` and `.removeClass('DidNotHaveThis')` have no net effect, you would need to handle this as well.
Nick Craver
marked solved to fast, have to check that it works for all situations first.
Andreas
@Andreas - What are you actually trying to do?
Nick Craver
Well I got a plugin for jQuery and there wasn't a good event to show when it changed something.. So I thought that I would fix it this way. But I will check more closely for a better solution and post it here if I find any :) I will still marked this as solved, as it answers my question.
Andreas
Isn't there a function in jQuery that all of those functions goes through? Would be a smart thing to collect all of those class-functions against a common function, or even a common attr-changing-function?
Andreas