4

Is it possible to undo a switchClass transition?

I'd like an element to slowly obtain class A as you hover over it, and slowly lose it again once the mouse has moved away. However, the function appears to be glitchy, and calling .stop(0,1) doesn't seem to help. In fact, it seems to break it.

I have a live example here. Yes, it's a 404 page, but that's not important. The navigation should be slowly gaining or losing a class, but it just jumps. The script can be found here.

Is such a transition possible?

EDIT:

Here's the code I'm using:

$('#navbar li:not(.current) a').hover(function() {
    $(this).parent()
        .stop(1,0)
        .addClass('current', 1000);
}, function () {
    $(this).parent()
        .stop(1,0)
        .removeClass('current', 1000);
});

Is it perhaps because changing the class of the li doesn't result in the style of its children being transitioned?

EDIT2:

Yup, that 'fixed' it. The true bug can now be observed in all its glory (getting frozen in an intermediate state).

Community
  • 1
  • 1
Eric
  • 95,302
  • 53
  • 242
  • 374
  • Not sure if this is part of the trouble, but your `li` elements are displayed with `inline-block`. jQuery overwrites this property with `block` when it animates. May not be your issue, though. – user113716 Jun 14 '10 at 18:45
  • Fixed. Now the `a`s are animated – Eric Jun 14 '10 at 18:54
  • Regarding your update, I did a simple test, and children do inherit the styles they are intended to inherit, 'color' for example. They won't inherit margin, background, etc. – user113716 Jun 14 '10 at 19:18
  • Ok, updated again. Now you can see the _real_ bug – Eric Jun 14 '10 at 19:38
  • It certainly seems fickle. I tried using a simple flag on a test page to prevent it from firing mid-animation. It worked, but you don't get the mouseleave handler if you leave too soon. Any other approach I took resulted in it non-functioning. Perhaps `hover` is just not the best place to animate a class transition. :( – user113716 Jun 14 '10 at 19:40

3 Answers3

1

This is the closest I've come to making it work:

Example: http://jsfiddle.net/TUrvP/

There may be some overkill, and you may be able to use the :animated selector, though I had troubles at first.

May not be worth the effort...

HTML

<div id='myElement' class='blue'>content</div>

CSS

div {
    width: 100px;
    height: 100px;
}

.blue {
    background: blue;
    position:relative;
    left: 20px;
}
.myClass {
    background:red;
    margin-top: 50px;
}

jQuery

var animating = false;
var interval;
$('#myElement').hover(
    function() {
        var $th = $(this);
        if(!animating && !interval) {
            $th.clearQueue();
            animating = true;
            $th.addClass('myClass',500,function() {animating=false;});
        }
    },
    function() {
            var $th = $(this);
            if(interval) return false;
            if(animating) {
                interval = setInterval(function() {
                                            if(!animating) {
                                                $th.clearQueue();
                                                animating = true;
                                                $th.removeClass('myClass',500, function(){animating = false;});
                                                clearInterval(interval);
                                                interval = null;
                                            }},50)
            } else {
                $th.clearQueue();
                $th.removeClass('myClass',500, function(){animating = false;});
            }
        }
);
user113716
  • 318,772
  • 63
  • 451
  • 440
0

It doesn't make sense to slowly obtain a class. An element either has a particular class or it doesn't, and CSS provides no way to indicate some sort of "partial inclusion" in a class.

edit — @patrick points out that jQuery UI does indeed support that, at least to some extent. The class-manipulating functions take a duration argument if you install the effects stuff.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • You can do this if you have jQueryUI installed. You are able to give a duration, and it will animate the properties of the class. – user113716 Jun 14 '10 at 18:41
  • @patrick wow so it reads the CSS or something? Really? That seems ... well, strictly speaking it seems like determining what the semantics should be would be pretty complicated, if even possible in the general case. What about selectors that act on elements with two classes, and you're just animating one of them? I'll have to read up on that now because it sounds pretty amazing. – Pointy Jun 14 '10 at 18:47
  • It really is pretty amazing, but hasn't always worked very well. The most recent version of UI seems to be much improved over the previous. I certainly don't claim to have any knowledge of the inner workings, though. :o) Makes for a nice way to eliminate CSS values scattered throughout your javascript. – user113716 Jun 14 '10 at 18:48
  • @patrick sure enough - well I guess it could do something like add the class, check the resulting style differences, and then animate that, actually giving the element the class when the transition finishes. Not sure how you'd do that without some visible artifact but probably that's a reason I'm not a jQuery UI developer :) – Pointy Jun 14 '10 at 18:52
0

It looks like you are looking for some form of .animate function of jQuery.

$('#clickme').hover(function() { $('#book').animate({ opacity: 0.25, left: '+=50', height: 'toggle' }, 5000, function() { // Animation complete. }); });

Otherwise switch class slowly doesnt makes much sense to me

sushil bharwani
  • 29,685
  • 30
  • 94
  • 128
  • 1
    You can do this if you have jQueryUI installed. You are able to give a duration, and it will animate the properties of the class. – user113716 Jun 14 '10 at 18:47