I have a basic div element to represent a message that I show for a few seconds and then fade it out using
$('#message').fadeOut(5000);
I want to be able to cancel the fade out if the user hovers their mouse over the div.
How can I cancel the fade out once the fadeOut method has started to fade the div?
My existing code, below, works if the mouse enters the div whilst it is being shown but I need to allow for if the user hovers over the div once it has started to fade.
$('#message').mouseenter(function() {
clearTimeout(this.timeout);
});
$('#message').mouseleave(function() {
this.timeout = setTimeout("$('#message').fadeOut(5000)", 3000);
});
$('#message').fadeIn(2000, function() {
this.timeout = setTimeout("$('#message').fadeOut(3000)", 3000);
});
Check out the stop function
http://docs.jquery.com/Effects/stop#clearQueuegotoEnd
Also, you can test if an element is in the middle of an animation using the :animated selector:
$('#message').mouseover(
function () {
if($(this).is(':animated')) {
$(this).stop().animate({opacity:'100'});
}
}
);
In my case stop() merely didn't work at least in Firefox, after searching I figured out that It should be stop(true, true):
$('#message').mouseover(
function () {
$(this).stop(true, true).fadeOut();
}
);
stop(): Stops the currently-running animation on the matched elements.
or even you can use finish() instead:
$('#message').mouseover(
function () {
$(this).finish().fadeOut();
}
);
but there is a side effect about finish(), it stops all other running animations too.
finish(): Stops the currently-running animation, remove all queued animations, and complete all animations for the matched elements.
Read more here.
Related
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.
I have a container that fades on a timer when hovered on (#module-container) but when clicking on a .return-news, it stops the hover and keeps it from fading. Now I need it where, when called through a function, I need to allow the hover effect again on the #module-container just like before. Here's the hover code:
var module = $('#module-container');
$('.menu-control').add(module).mouseenter(function() {
module.stop().show();
clearTimeout(window.mtimer);
console.log('hovered');
});
$('.menu-control').add(module).mouseleave(function() {
var time = 3000;
window.mtimer = setTimeout(function() {
module.fadeOut(600);
}, time);
console.log(window.mtimer);
});
By clicking .return-news, I've successfully stopping the hover with this line:
$('.return-news').on('click',function(e) {
e.stopPropagation();
module.add('.menu-control').off('mouseenter').off('mouseleave');
console.log('stop it!');
});
NOT WORKING: If I click .next-video then I need to re-enable the hover (which will then use the mouseeneter and mouseleave functions previously declared). I've tried calling this line but it doesn't work:
$('.next-video').on('click',function(e) {
e.stopPropagation();
module.add('.menu-control').on('mouseenter').on('mouseleave');
});
Later, I'll be having the hover re-enabled by calling it using Vimeo's API (instead of the .next-video click) but for the sake of time, I stripped the code to it's basic functionality.
HERE'S THE CODE ON JSFIDDLE.
I have the following code:
$(document).ready(function () {
$("#full-btns").children().delay(4000).fadeOut("slow");
$('#full-btns').hover(function() {
$('#full-btns').children().stop().animate({opacity:'100'});
$('#full-btns').children().show();
}, function() {
$("#full-btns").children().fadeOut("slow");
});
When the page is loaded, the #full-btns element is shown for 4000ms before fading out. The problem I have is that if a user hovers over the #full-btns element while its still visible, it causes it to fade out because $("#full-btns").children().fadeOut("slow"); is called on the hover. I want #full-btns to always be visible when hovering over it.
When the page loads, hover over the red div, notice how it fades out. That is undesirable. When hovering over the red div (while its visible) it should remain visible
Update:
http://jsfiddle.net/gazedge/nhBBc/ (now includes solution)
Use setInterval and clearInterval;
$('#full-btns').hover(function() {
clearInterval(refreshIntervalId);
$('#full-btns').children().stop().animate({opacity:'100'});
$('#full-btns').children().show();
}, function() {
$("#full-btns").children().fadeOut("slow");
});
var refreshIntervalId = setInterval(function() {
$("#full-btns").children().fadeOut("slow");
}, 4000);
If I haven't misunderstood the question - can't you just return false; at the end of your hover calls to prevent the events bubbling?
http://www.quirksmode.org/js/events_order.html
http://fuelyourcoding.com/jquery-events-stop-misusing-return-false/
The only thing you have to do is clear all animation before anyone hovers.
$("#full-btns").children().delay(4000).fadeOut("slow");
$('#full-btns').hover(function() {
$('#full-btns').children().stop(true, true); // Stop the fade-out animation
$('#full-btns').children().stop().animate({opacity:'100'});
$('#full-btns').children().show();
}, function() {
console.log('fadeOout called');
$("#full-btns").children().fadeOut("slow");
});
http://jsfiddle.net/nhBBc/5/
Note: First time when you hover and (in your code) the div fades out it is not because of $("#full-btns").children().fadeOut("slow"); but because it is just completing the earlier animation which you have applied. [ your 1st line ].
I know there are several other posts with solutions to this, but my current problem is a little different.
I have two events on an element - mouseenter and mouseleave. The first changed the color of my element to light and the other back to dark, this makes a flashing effect.
The problem is when I go in and out a couple of times the events stack and it flashes many times even if no new events are triggered. I would like to prevent that, but .stop() does not help.
Here's the catch: I would like to trigger 1 flash no matter what, but not more than 1. So when someone moves in / out - the event mouseenter will be fired, after it mouseleave and after it nothing.. until another in / out is triggered.
I guess this could be made by locking (not listening for) new events when in / out is triggered up until the effect has finished, but I don't know how to do without unbinding and binding it again. Isn't there any lockEvent() or something?
Have you already used .stop(true) or .stop(true, true)?
there is pseudo-class in jQuery ":animated"
you can use it on first mouseenter even like:
if ( $(this).is(':animated')) {
return false;
}
to prevent additional animation
You can try just setting a bool var and firing only if false...
var anim = {
animating: false,
over: function(){
if(!anim.animating)
{
anim.animating = true;
// do you animation here
// and set your animating bool to false before calling outro...
$('#elem').animate({/*some css change*/ }, 1000, function(){
anim.animating = false;
anim.out();
});
}
},
out: function(){
if(!anim.animating)
{
anim.animating = true;
//do your outro animation here
$('#elem').animate({/*some css change*/ }, 1000, function(){
anim.animating = false;
});
}
}
};
then have your listener call anim.over and anim.out...
$('#elem').on('mouseenter', function(){
anim.over();
}).on('mouseleave', function(){
anim.out();
});
This way you will call animation on enter and it will automatically fire off the outro animation when the intro completes.
i am making a something like this :
When a user mouseenter DIV1 , the DIV2 will fadeIn and when the user mouseout DIV1 , DIV2 will fadeOut
But something weird is happening , when you hover in and out DIV1 quickly , the FADEIN and OUT effect of DIV2 will repeat the total number of your hovers in.
For example:
i quickly hovers in and out for 10 times # DIV1 , DIV2 will continue to FADE IN and OUT for 10 times although my mouse is not hovering it.
I hope people understand what i'm saying.
CODE:
$('div1').bind('mouseenter', function() {
$('div2').fadeIn(600);
});
$('div1').bind('mouseout', function() {
$('div2').fadeOut(600);
});
Thanks and have a nice day .
use .stop(true,true) on the mouseout event that will stop all the existing animations
here is the working fiddle http://jsfiddle.net/XkmFy/
You can stop the existing animation when you start a new animation instead of stacking them up:
$('div1').bind('mouseenter', function() {
$('div2').stop().fadeIn(600);
});
$('div1').bind('mouseout', function() {
$('div2').stop().fadeOut(600);
});
You want .stop, which stops the current animation so that the animation queue does not get filled up with deferred animations: http://jsfiddle.net/pQQ2G/.
$('#div1').bind('mouseenter', function() {
$('#div2').stop().fadeIn(600);
});
$('#div1').bind('mouseout', function() {
$('#div2').stop().fadeOut(600);
});
Also, you shuold use #div1. div1 selects div1 elements, whereas you have div elements I suppose.
use this
$('div1').bind('mouseenter', function() {
$('div2').fadeIn(600).stop(true, true);
});
$('div1').bind('mouseout', function() {
$('div2').fadeOut(600).stop(true, true);
});
hope it helps