Molly Campbell
Molly Campbell

Reputation: 439

Delay Javascript hover action

I have an image on my site that has a jquery hover action assigned to it. But it's easy to accidentally mouse over that area, and if you do it more than once, the hover keeps appearing, disappearing, appearing, etc, until it's shown and disappeared once for every time you moused over it. Is there a way to make it so the action doesn't fire unless you hover for a few seconds? I don't want to just delay the action, because it would still happen for every mouseover, I want to see if there's a way the mouseover doesn't count unless you're on the image for a few seconds.

Script so far:

$("img.badge").hover(
function() {
  $("h3.better").animate({"left": "125px"}, 1200);
},
function() {
  $("h3.better").animate({"left": "-500px"}, 800);
});

Upvotes: 9

Views: 14039

Answers (3)

Denys Séguret
Denys Séguret

Reputation: 382092

You could use setTimeout to launch the action and bind a function calling clearTimeout on the mouseout event :

$('img.badge').hover(function(){
    window.mytimeout = setTimeout(function(){
        $("h3.better").animate({"left": "125px"}, 1200);
    }, 2000);
}, function(){
    clearTimeout(window.mytimeout);    
});

Or you could use a plugin for that, like hoverintent.

Upvotes: 14

jfriend00
jfriend00

Reputation: 707158

You can use a timer to not fire the hover action until you've been hovered a certain amount of time like this and then, if the hover leaves before the timer fires, you clear the timer so nothing happens if you're only hovered a short period of time:

$("img.badge").hover(function() {
    var timer = $(this).data("hover");
    // if no timer set, set one otherwise if timer is already set, do nothing
    if (!timer) {
        // set timer that will fire the hover action after 2 seconds
        timer = setTimeout(function() {
            $("h3.better").stop(true).animate({"left": "125px"}, 1200);
            $(this).data("hover", null);
        }, 2000);
        // save timer
        $(this).data("hover", timer);
    }
}, function() {
    var timer = $(this).data("hover");
    if (timer) {
        clearTimeout(timer);
        $(this).data("hover", null);
    } else {
        // probably would be better to make this an absolute position rather
        // than a relative position
        $("h3.better").stop(true).animate({"left": "-500px"}, 800);
    }
});

Note: I also added .stop(true) to your animation so animations will never pile up.

Upvotes: 0

Samuel Liew
Samuel Liew

Reputation: 79022

Use a .stop() before animate, to cancel the previous animation. I believe this is what you are looking for, and will solve your current problem.

$("img.badge").hover(
function() {
  $("h3.better").stop().animate({"left": "125px"}, 1200);
},
function() {
  $("h3.better").stop().animate({"left": "-500px"}, 800);
});

Upvotes: 1

Related Questions