0
votes

This seems to be a very common problem, although I've tried the recommendations to use addClass / removeClass rather than direct CSS manipulation, and I've tried mouseleave / mouseout but both cause problems.

All I want is a simple roll over that changes the class! Everything I try either inconsistently flickers the class on or off. The only other requirement I've been trying to accommodate is to have the listener live in a function rather than inline. Is that what's making this impossible?

function highlight(_event){
  $(this).addClass("Highlighted");
}
function unhighlight(_event){
  $(this).delay(2000,function(){
    $(this).removeClass("Highlighted");
  });
}

$(document).ready(function () { 
  $(".Content").live('mouseenter',highlight);
  $(".Content").live('mouseout',unhighlight);
});

JSFiddle of the above

Edit

Adding .stop(true,true) seems to help quite a bit.

3
What are you trying to highlight? Text, a div? - Walker
I'm not witnessing any issues with your example as you describe it (flickering). What is the problem? - Jared Farrish
Sorry, I didn't label the JSFiddle link. The styles are being applied to divs. In both chrome and FF the effect is applied inconsistently on mouseenter / mouseout, but always eventually end up stuck in the highlighted state - RSG
see the update to the answer I posted, I read the comment you use the functions in other places so added to my answer to see if it helps out a little bit more. - Scoobler

3 Answers

1
votes

If you want to use live, you could do the following using .toggleClass(), .mouseover() & .mouseout():

$(".content").live("mouseover mouseout", function() {
    $(this).toggleClass("highlight");
});

See a demo here


Update: I couldn't leave this one, so carried on messing with your example - after the comment you use the functions in other places. So here is what I found:

Instead of calling .mouseout() use .mouseleave() - for some reason .mouseout() get's called multiple times when the mouse moves round - it even gets called when the mouse first enters the object..... See the demo at the end to see what i mean here

Secondly, the .delay() isn't really being used correctly here - it is really meant for queuing effect's - but what you really want is to add a delayed function (albeit it is an effect that you are after) so instead use the .setTimeout() to do the call for you.

As per the doc's:

The .delay() method is best for delaying between queued jQuery effects. Because it is limited—it doesn't, for example, offer a way to cancel the delay — .delay() is not a replacement for JavaScript's native .setTimeout() function, which may be more appropriate for certain use cases.

So the finished functions would look like this:

function highlight(_event) {
    $(this).addClass("Highlighted");
}

function unhighlight(_event) {
    var obj = $(this);
    setTimeout(function() {
        obj.removeClass("Highlighted");
    }, 2000);
}

$(document).ready(function() {
    $(".Content").live('mouseenter', highlight);
    $(".Content").live('mouseleave', unhighlight);  
});

See the demo here this one will show you what I mean about the .mouseout() event being fired multiple times, where as the .mouseleave() function is only called once when the mouse actually leaves.
Note: use your enter button to press the alert ok, don't move your mouse!!

See the demo here to see the final version working here as close to your original as possible.

0
votes

If you want to, I think you can dump the functions and do this instead - if you aren't using the functions for anything else of course:

$(document).ready(function () {
$(".Content").live('mouseenter',function(){ $(this).addClass("Highlighted");
});
$(".Content").live('mouseout',function(){ $(this).delay(2000,function(){ $(this).removeClass("Highlighted"); });
}); });

0
votes

Try

//Might be better to use .toggleClass("Highlighted");

var timer;

$(".Content").hover(
    function(){
        clearTimeout(timer);
        $(this).addClass("Highlighted");
    },
    function(){
        timer = setTimeout(function(){
            $(this).removeClass("Highlighted");
        }, 2000);
    }
);