Prevent events to be triggered unecessarily - javascript

$('#menu > li').hover(function(){
$(this).find('ul').slideDown();
});
$('#menu > li').mouseleave(function(){
$(this).find('ul').slideUp();
});
this works fine, but if i hover/leave an <li> item of the menu many times and very fast, once i stop i will see it slide up and down as many times as i hovered,
please watch this sort video capture
http://www.screenr.com/dkes
¿how can that be prevent?

You can use stop to stop the current animation. You could also combine your two event handlers and just use hover (which can take 2 arguments, the first is a function to run on mouseenter, the second a function to run on mouseleave):
$('#menu > li').hover(function() {
$(this).find('ul').stop(true, true).slideDown();
}, function() {
$(this).find('ul').stop(true, true).slideUp();
});
The first argument is clearQueue, which will stop the animations queueing up endlessly as you hover repeatedly. The second argument is jumpToEnd, which forces any currently running animation to end before starting a new one.
Here's a simple example.

It all boils down to you having a variable that will store the state of your sliding and will prevent further requests from happening if a sliding is already taking place.
Set the flag at the beginning of sliding and use callback to unset the flag.
var closing = false;
$('#menu > li').mouseleave(function(){
closing = true;
$(this).find('ul').slideUp(null, function(){
closing = false;
});
});
// then in the hover method you would just check the value of closing to see if to allow or not opening.
The second idea was exposed a little earlier by James Allardice, and I like it more if it works.

Related

How to avoid duplicate each loop in jquery?

I had a function that looks like this
function show_services_title(show_services){
$('.service').fadeOut();
$.each($('.service'), function(i) {
$(this).delay(500*i).fadeIn();
});
}
Now, this functions is invoked when I click on a link, the problem is that when I click the link the function start to show each div with the class 'service', but when I click the link again and the divs haven't finish showing yet then occur a mess in the screen.
Here is an example that simulate the behavior I'm trying to describe and I want to avoid.
http://jsfiddle.net/bw7jn/4/
Try to disable running the animation the second time when the previous animation is still running.
$(document).ready(function(){
$('#link').click(function(){
show_services_title();
});
});
function show_services_title(show_services){
//if we're already animating, don't start a new one
if($('ul').attr('data-animating') != 'true'){
//make sure other clicks dont trigger this animation
$('ul').attr('data-animating', 'true');
$('.service').fadeOut();
$.each($('.service'), function(i, element) {
setTimeout(function(){
$(element).fadeIn();
//check if this is the last element we're gonna animate
if(i == $('.service').length-1){
//animation is done, allow new animations to start
$('ul').attr('data-animating', 'false');
}
}, 500*i);
});
}
}
http://jsfiddle.net/bw7jn/7/

How to re-enable button hovers in jquery

http://codepen.io/Snowfiring/pen/oKpBh
I'm attempting to disable the animation on click because when clicked, the animation starts moving and if your still hovered over an object it freezes, the end result is the animation stops running and it just moves,
my code to freeze the animation on hover is
function show_box() {
if($(window).width() > 768) {
$('.tab-content').hide(0,
function() {
$(this).prev().css('right', '29.337803855%');
$(this).prev().children().children().click(function () {
$('.favorite').off('mouseenter').css('-webkit-animation-play-state', 'running');
$('.secret').off('mouseenter').css('-webkit-animation-play-state', 'running');
$('.current-projects').off('mouseenter').css('-webkit-animation-play-state', 'running');
$('.tab-selection').animate({right: 0}, 3000).queue(function() {
$('.tab-content').show(1000);
});
$('.favorite').on('mouseenter');
$('.secret').on('mouseenter');
$('.current-projects').on('mouseenter');
});
}
);
}
}
to disable hover on mouseenter and mouseleave i used
.off('mouseenter')
but after the function is done, and the moving complete I set
.on('mouseenter')
but it doesn't re-enable.
At first your code could be much shorter, i think.
And please take a look in the jQuery doc for the on function it does Not, what you are expecting!
I think you should set a global variable if it is disabled at the moment and in the eventhandler you firstly check the variable and abort if its disabled.

Jquery bug dblclick/click

I've been experimenting with jquery and have come upon a problem. http://javascript.nicklewers.co.uk/nav/
On the 'Android' tab I've set it so that if you click once, the sub menu will appear, however when doubleclicking, the main content will appear.
Now the problem is: a double click involves two single clicks which involves the sub menu opening and closing very quickly and this looks bad. How do I prevent this?
try this (using a timer to know if single click or double):
alreadyclicked=false;
$('#android').bind('click',function(){
var el=$(this);
if (alreadyclicked)
{
alreadyclicked=false; // reset
clearTimeout(alreadyclickedTimeout); // prevent this from happening
// do what needs to happen on double click.
}
else
{
alreadyclicked=true;
alreadyclickedTimeout=setTimeout(function(){
alreadyclicked=false; // reset when it happens
// do what needs to happen on single click.
// use el instead of $(this) because $(this) is
// no longer the element
},300); // <-- dblclick tolerance here
}
return false;
});
Try a delay before showing/hiding the submenu. With JS this can be done using the setTimeout() function.
$('#android').dblclick(function(){
$('.content, #subnav').toggle();
});
why do you toggle both the content and the submenu? Removing it is not going to solve the problem, but I think it should not be there.

jQuery dropdown menu mouseleave problem

http://jsfiddle.net/borayeris/sb9Ju/4/
Here is my script. How can I stop fading out if mouse is back on menu?
Try adding a call to stop() on the fadeIn:
$(function(){
var piFade;
$('#menu > li').hover(
function(){
$('#menu > li:hover > div').stop(true,true).fadeIn('slow');
},
function(){
$('#menu > li > div').fadeOut('slow');
}
);
});
http://jsfiddle.net/sb9Ju/13/
And here is a version with the delay included. I'm not a huge fan but it's not too bad with the call to stop in there.
http://jsfiddle.net/sb9Ju/15/
You set too long a delay. It still runs the original hover function.
You remove it, it waits 2.5 second, then you back on it and it still removes menu from the first time you've hovered.
I really don't see a reason to use delay there.

jQuery delay doesn't work as expected

I have the following jQuery code
$("#dropdown").hover(function() {
$(this).stop(true,true).fadeTo('fast',1);
$("#options").stop(true,true).slideDown();
}, function() {
$(this).delay(1000).stop(true,true).fadeTo('fast',0.1);
$("#options").delay(1000).stop(true,true).slideUp();
}
);
What I expect to happen is when the mouse leaves #dropdown it will wait 1 second before continuing. This is not happening.
What I am trying to achieve, in case there is a better way, is to leave the drop down menu visible for a second or two after moving your mouse and I would also like to prevent the events from happening again to prevent artifacts and "funnies" if you were to move the mouse over and out from the div very quickly
The problem is .stop(). If you take that out it works:
http://jsfiddle.net/LZ8yt/
Your calls to stop aren't placed on the animation queue - they run immediately. I'm not sure whether you really need them in the "hover out" routine.
edit removed dumbness
You can always go lo-tech with setTimeout.
var dropDownElement = $(this);
setTimeout(function()
{
dropDownElement.fadeTo('fast', 0.1);
// Other Code
}, 1000);

Categories

Resources