开发者

JS setTimeout & jQuery function

I have this function and I am wondering why the setTimeout is not working:

$(document).ready(function() {      
    $('.sliding .text').css("top","130px")     

    $('.sliding').mouseenter(function() {       
        mouseOverTimer = setTimeout开发者_如何学C(function() {
            $(this).find('.text').animate({"top": "0"}, 200);             
        }, 500);       
    })
    .mouseleave(function() { 
        $(this).find('.text').delay(500).animate({"top": "130px"}, 400); 
    });       
});     

I tried wrapping the mouseenter event in the timeout, but that didn't seem like a great idea. I just want the animation on mouseenter to only work after the mouse has been over it for at least half a second.

Alternatively, is there a better way of doing it in jQuery?


The this value inside your timeout handler will not be what you think it'll be. Add an explicit variable:

   $('.sliding').mouseenter(function() {   
        var self = this;    
        mouseOverTimer = setTimeout(function() {
            $(self).find('.text').animate({"top": "0"}, 200);             
        }, 500);       
    })

Also you should declare "mouseOverTimer" as a local variable outside the handler setup code (that is, as a local variable of the "ready" handler) and then cancel the timeout in the "mouseleave" handler:

    var mouseOverTimer = null;

   $('.sliding').mouseenter(function() {   
        var self = this;    
        mouseOverTimer = setTimeout(function() {
            $(self).find('.text').animate({"top": "0"}, 200);             
        }, 500);       
    })
   .mouseleave(function() { 
        $(this).find('.text').delay(500).animate({"top": "130px"}, 400); 
        cancelTimeout(mouseOverTimer);
    });       

As I look at this, I'm pretty sure that the "mouseleave" code isn't really what you want; specifically I think the delay is probably unnecessary. I'm not 100% sure about what you want things to look like, however.


I would perhaps simplify the problem this way: On mouseover I would instantiate a new Date(), getTime() on it and stash it into a var. Then on mouseleave you take another date, grabbing the timestamp again. In that same mouseleave, do an evaluation: if the difference between date 1 and date 2 is greater than 1/2 second, you fire your action. Else, you reset date 1.


you could try this instead of using setTimeout:

$(document).ready(function() {      
    $('.sliding .text').css("top","130px")     

    $('.sliding').mouseenter(function() {       
        $(this).find('.text').stop().delay(500).animate({"top": "0"}, 200);             
    })
    .mouseleave(function() { 
        $(this).find('.text').stop().animate({"top": "130px"}, 400); 
    });       
});

This will delay the mouseover animation by 500ms. If you mouse out, it calls stop(), which would kill the pending animation and then animate back to the starting position. If it never moved, the mouseout animation will also not happen (correctly - it has nowhere to go).


Another way to do this

mouseIn = false;
$(document).ready(function() {      
    $('.sliding .text').css("top","130px")     

    $('.sliding').mouseenter(function() {   
        mouseIn = true;  
        mouseOverTimer = setTimeout(function() {
            if(mouseIn==true)
                 $(this).find('.text').animate({"top": "0"}, 200);             
        }, 500);       
    })
    .mouseleave(function() {
        mouseIn=false;
        $(this).find('.text').delay(500).animate({"top": "130px"}, 400); 
    });       
});
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜