jQuery: Prevent stacking animations - javascript

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.

Related

click event is triggered by scrolling

in my js code I have pretty simple event listener listening for a click -
element.addeventlistener('click', ()=>{
#do somthing
})
the issue is that when I am scrolling on IOS (iphone) - touching this element to start the scroll, triggers the event listener.
Is there a way to prevent a event listener on iphone, unless no scrolling is to follow?
i.e. do something if clicked but scrolling doesn't follow
alternatively the might be a completely different solution (but I am trying to avoid a library)
thanks
W
ANSWER
After reviewing the answer given below (which does work) as described, this issue was still persisting. This gave me cause to review my CSS on which I found that on IOS mobile (iphone) - the CSS psudo selector :focus is activated when you scroll over an item.
I added a media query to only allow :focus to be used on desktop size devices or above, which solved the issue.
I have a found a possible solution on another question in Stackoverflow: Question
Basically you add a scroll listener to your window. This will then set a global boolean called disable_click_flag to true when scrolling. If the user wasn't scrolling for at least 250ms it will be set to false.
When the boolean is true then the click event isn't able to go trough.
var disable_click_flag = false;
var timeout = null;
window.addEventListener('scroll', () => {
disable_click_flag = true;
if(timeout) clearTimeout(timeout);
timeout = setTimeout(function(){ disable_click_flag = false }, 250);
}
element.addeventlistener('click', () => {
if(disable_click_flag === false{
#do somthing
}
})
I'm not an expert, but I would try:
var prevScroll = pageYOffset;
window.addEventListener("scroll", () => prevScroll = pageYOffset);
window.addEventListener("click", (e) => {
if (pageYOffset !== prevScroll) return;
// your code
});
Please note that this code is not tested, however I think it should work.

JQuery animation loop on hover

this is probably a very basic question, but I am trying to animate an image (with a kind of pulse effect) when a button is hovered over.
So far I have this:
$("#austriaBtn").mouseenter(
function animate(){
$('#austria').animate({width:"35", top:"-=4", left:"-=4"},600);
$('#austria').animate({width:"27", top:"+=4", left:"+=4"},600, animate);
}
);
Now, I can hover over the button (austriaBtn) and the image (austria) starts to pulsate, however, when I take the mouse off, it carries on pulsating. How can I stop it?
I know it must be something to do with stop(), but whenever I try to put it in, the animation stops working all together.
Thanks in advance!
Put .stop() in a .mouseleave() function.
$("#austriaBtn").mouseleave(function(){ $('#austria').stop(true,true); });
The true arguments in .stop() are as follows:
clear animation queue (default is false; shouldn't be an issue.)
jump to end of animation (default is false; stops the element from being caught in the middle of an animation. important here.)
You have to use the corresponding mouseleave event, thus catching the event when the mouse leaves the button and then stop the animation.
$("#austriaBtn").mouseleave(
function() {
$("#austria").stop();
}
);
you could use a lock variable:
var stopAnimation = false;
$("#austriaBtn").mouseenter(
function animate(){
if(stopAnimation){
stopAnimation = false;
} else {
$('#austria').animate({width:"35", top:"-=4", left:"-=4"},600);
$('#austria').animate({width:"27", top:"+=4", left:"+=4"},600, animate);
}
}
);
$("#austriaBtn").mouseleave(
function(){
$('#austria').stop();
stopAnimation = true;
}
);

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.

How do I add a delay to the mouseover function?

I'm making a calendar app using the jQuery plugin FullCalendar and I made a tab to the left of the calendar with the weeks from 1-6 on it. When the user drags their mouse over one of the weeks the calendar switches to the view of the respective view. This works but it can be annoying for the user if they do it accidentally. So, I want to add a delay to the function so that it will only happen if the user has their mouse on it for a few hundred milliseconds so it will happen less without the user wanting it to happen.
$('#week3').mouseover(function() {
$('#week3').css('color', 'white');
$('#week3').css('background-color', '#6B8BA9');
$('#week3').week3();
I want to add a short delay before $('#week3').css('color', 'white');
If I am understanding you correctly, then you will need a more complete solution like below
var mouse_monitor
$('#week3').mouseover(function() {
mouse_monitor = setTimeout(function(){
$('#week3').css('color', 'white');
$('#week3').css('background-color', '#6B8BA9');
$('#week3').week3();
}, 1500)
});
$('#week3').mouseout(function() { clearTimeout( mouse_monitor ); }
The var mouse_monitor is a global reference to your timeout function. The mouseout function is missing in other post, which assures that your mouseover function will not fire if the user moves the mouse off the hover target before the value of the setTimeout expires. Other examples will still invoke your mouseover function everytime, but with just an added delay, so they won't work for what I think you are trying to achieve.
Use a timeout :
$('#week3').on({
mouseenter: function() {
var that = this;
$(that).data('timer',
setTimeout(function() {
$(that).css('color', 'white');
},1000)
).css('background-color', '#6B8BA9').week3();
},
mouseleave: function() {
clearTimeout( $(this).data('timer') );
}
});
you are looking for setTimeout

How do you cancel a jQuery fadeOut() once it has started?

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.

Categories

Resources