jQuery - Fading animation on hover - javascript

I have a little jQuery animation which fades in a link when hovering an :
$(function() {
$('.delete').hide();
$('#photos img').hover(function() {
$(this).parents('li').children('.delete').fadeIn('fast');
}, function() {
$(this).parents('li').children('.delete').fadeOut('fast');
});
});
But if I quickly move my mouse in and out of the image, the new animation is always added to the queue and when I stop I can see the link pulsating for a while. I tried using .stop(true), but then sometimes the fade in effect doesn't work at all (or just up to some opacity value less than 1). What can I do?
Thanks, Eric

The best way is to use hoverIntent plugin. This deals with the issues above. It also adds a slight delay to the animation so if a user happens to quickly move the mouse over all the links you do not get an ugly animation flow of all the links.

One way to prevent such problems occuring is to use stop() in conjunction with fadeTo(), as in the snippet below:
$(function() {
$('.delete').fadeTo(0, 0);
$('#photos img').hover(function() {
$(this).parents('li').children('.delete').stop().fadeTo('fast', 1);
}, function() {
$(this).parents('li').children('.delete').stop().fadeTo('fast', 0);
});
});
Hope this solves your issue!

Related

How can I stop a CSS animation on scroll?

I want to show an animating arrow the first time a web page loads, and disable it when the user scrolls.
Normally I could do something like this:
jQuery(window).scroll(function() {
jQuery('.arrow').css("display", "none");
});
However my site has a few plugins to allow horizontal scrolling which I think is preventing this from working.
Is there a way to hide the animation that is not based on scrolling detection?
http://codepen.io/sol_b/pen/ORGKbP
Thanks.
EDIT: the plugins I'm using are jquery kinetic and jquery mousewheel.
You can do the following in your jquery.
jQuery(window).scroll(function() {
document.getElementById("animation").style.WebkitAnimationPlayState = "paused";
});
This will stop your animation while scrolling, but this will cause an issue that the animation won't be played when the scroll is stopped. Fot that you can use this function
$.fn.scrollStopped = function(callback) {
var that = this, $this = $(that);
$this.scroll(function(ev) {
clearTimeout($this.data('scrollTimeout'));
$this.data('scrollTimeout', setTimeout(callback.bind(that),250, ev));
});
};
And then on scroll stop you can start the animation again.
$(window).scrollStopped(function(ev){
document.getElementById("animation").style.WebkitAnimationPlayState = "running";
});
If the plugin, that allows horizontal scrolling, has an official documentation, you should look for a callback method. Like when the users is scrolling this called gets called. In the callback you could then hide the arrow (or .fadeOut() imo)...
I was able to fix this by replacing 'window' with my content wrapper. Like this:
jQuery('#wrapper').scroll(function() {
jQuery('.arrow').css("display", "none");
});

Mouse movement blocks 'transitionend'

Introduction
I'm using Semantic-UI's sidebar functionality, which gives you a button that triggers a sidebar that pushes the content from the left (in this case).
I want to unfold that same sidebar by hovering with the mouse on the left side. I realize there are several ways to do it (as these often do. Maybe just checking the X position of the mouse would work but that's beside the point); I chose to create a transparent div on the left side and make its :hover pseudo-class to trigger the sidebar:
// create sidebar and attach to menu open
$('.ui.sidebar').sidebar('attach events', '.toc.item');
// hover transparent div to trigger the sidebar too:
$('.sidebar-trigger').hover(function() {
$('.ui.sidebar').sidebar('show')
});
// hide() and show() the sidebar accordingly to use the sidebar:
$('.ui.sidebar').sidebar('setting', {
onShow: function() {
$('.sidebar-trigger').hide();
},
onHidden: function() {
$('.sidebar-trigger').show();
}
});
Problem
Now, it all works except for one occasion: when you don't stop moving the mouse as the sidebar opens. I've looked at $(document).on('transitionend', function(event) { ... } and that mouse effectively prevents the transition to finish.
Resources
I've put a blue background on my .sidebar-trigger and made a small video/gif so as to be clearer.
I moved the mouse like a crazy creature but with natural gestures the problem occurs as well.
I'm using Semantic-UI's guide on this thing: http://semantic-ui.com/modules/sidebar.html#/settings (I've also tried onVisible and onHide with no luck)
This is a OSX Yosemite 10.10.3 running Chrome 45.0.2454.101 (64-bit)
jsfiddle with the problem at hand
PS: It seems it might be an OSX Chrome bug?
I would try using one and mouseover:
$('.sidebar-trigger').one('mouseover', function() {
$('.ui.sidebar').sidebar('show')
});
Then, when it has finished animating, reattach the event:
$(document).on('transitionend', function(event) {
$('.sidebar-trigger').one('mouseover', function() {
$('.ui.sidebar').sidebar('show')
});
});
I think what is happening is that the hover event is getting called multiple times - every time the element is hovered, then goes over a child element, and then goes back over the hover element, and things are getting mixed up at some point. So you need to only call show if it's not already shown.
Here is a working example: Fiddle
I believe when the element was hovered, it was adding a classes 'uncover' and 'visible', and another called 'animating' which wouldn't fire until the mouse stopped moving. I changed the jQuery slightly to only add classes 'uncover' and 'visible', and it still animated okay. However, the body was pushing right too far by 175px, so I had to edit the class that was causing that (noted below) from 260px to 85px. This DOES get the menu acting properly though from my understanding.
$('.sidebar-trigger').mouseenter(function() {
$('.ui.sidebar').addClass('uncover, visible');
$('body').addClass('mleft175');
});
$('body').click(function() {
$('.ui.sidebar').removeClass('uncover, visible');
$('body').removeClass('mleft175');
});
and then add overriding class
.ui.visible.left.sidebar ~ .pusher
{
-webkit-transform: translate3d(85px, 0, 0);
transform: translate3d(85px, 0, 0);
}
Right now it is set to hide the menu when the body is clicked. Alternatively you can hide it when the mouse leaves the sidebar menu:
$('.ui.sidebar').mouseleave(function(){
$(this).removeClass('uncover, visible')
});
Ok, my first answer was (of course) way too much work for what it really needed. The onVisible seems to work perfectly. Was that not working for you? Demo HERE
Simply change 'onShow' to 'onVisible' in your sidebar setting:
$('.ui.sidebar').sidebar('setting', {
onVisible: function() {
$('.sidebar-trigger').hide();
},
onHidden: function() {
$('.sidebar-trigger').show();
}
});
As shown on the Semantic UI site, the onVisible fires when the animating starts. The onShow fires when the animating finishes. So what you were doing was hiding that blue / transparent bar when the animation was finally done (the .animating class noted in my previous answer), as opposed to when it starts. If you need further explanation please let me know.

jQuery SlideDown() is not waiting for delay on animation

I use jQuery function that should animate divs (Slide down and up) like a dynamic menu or something.
The problem is even I set up delay() - when mouse goes over it, no matter how long the cursor stays over one div it will slidewon and up.
To clarify. If I put a mouse over the certain div, it works well, it waits the delay and then slide. But if I fast goes over all divs in the example it will make a weird reaction, like the divs start to slide down but then suddenly stops and go up. Try my fiddle and you'll see.
This is the FIDDLE
jQuery(".subdiv").hide();
jQuery(".mydiv").hover(function(){
jQuery(this).find(".subdiv").stop().delay(800).slideDown("slow");
}, function(){
jQuery(this).find(".subdiv").stop().delay(200).slideUp("slow");
});
So something like this:
http://jsfiddle.net/GzxJf/12/
jQuery(".subdiv").hide();
jQuery(".mydiv").hover(function(){
jQuery(".subdiv").each(function() {
if(jQuery(this).attr('display') !== "none") {
jQuery(this).stop(true).slideUp("slow");
}
});
jQuery(this).find(".subdiv").slideDown("slow");
}, function(){
jQuery(this).find(".subdiv").slideUp("slow");
});

jQuery hover stuck

When I hover over an img which fades to another img and sroll off too fast, the fadeOut gets stuck and the fade stays. I've tried the .stop() as I've seen in other responses, but still won't work. Is there something else I can put instead of the .stop()?
<div class="grid big-square">
<a href="#"><img id="image2" src="img/fade/creo.png">
<img id="image1" src="img/creo.jpg"></a>
</div>
<script>
$("#image1").mouseenter(function () {
$(this).stop(true, true).fadeOut(1000);
});
$("#image2").mouseleave(function () {
$("#image1").stop(true, true).fadeIn(500);
});
</script>
I seem to remember having a similar problem when I was creating this website.
The solution is to use a combination of .hover() and .stop() to ensure that only one animation is running at a time, which I think you have. Also ensure that the mouseover image is on top of the other image, and just fade that one in and out. The image fading out gets 'stuck' because at some opacity the .mouseleave() stops firing and the .mouseenter() starts firing on the other image.
Something like:
$$ = $("#image1");
$$.hover(function () {
$$.stop().animate({
opacity: 0
}, 1000);
}, function () {
$$.stop().animate({
opacity: 1
}, 1000);
});
#image1 must be above #image2 for this to work, #image1 fades out to 'reveal' #image2 behind it. The code uses .animate() rather than .fadeIn() and .fadeOut() but the effect is the same.
Edit- to fade in another div after the end of the fadeoout animation use the complete call back of the animate function.
Something like:
$$ = $("#image1");
$$.hover(function () {
$$.stop().animate({
opacity: 0
}, 1000);
}, function () {
$$.stop().animate({
opacity: 1
}, 1000, function() {
$("#finalDiv").animate({ opacity: 1, 500 });
});
});
#finalDiv needs to be after the 2 <img />s in your html to appear above them.
I'm not sure how you're trying to accomplish this but I do know how it should be done.
Try this http://jsfiddle.net/xy5dj/
Make sure to listen for both events on the same element (preferably a wrapper element).
Take note that fadeOut actually removes the element from the rendered content (display: none) making sure that the mouse events won't fire on that element.
Side note:
A dirty trick that I used once (if you have to do this then you're doing something wrong) is to clear the style of the element after animation using the callback ability of the animate function i.e.
$('el').animate({opacity:0}, 500, function(){$(this).attr('style', '')});
fiddle
You should use the animation/transition in form:
.fadeTo( duration, opacity, complete )
where complete is callback function.

animate christmas ornaments with Jquery ui effects

hi i am playing with jquery ui effects and trying to animate some christmas ornaments. the idea is that they would swing if you hover over them. and swing from the midpoint of the top of the image (the top of the string) like a real ornament and not just the whole image moving back and forth.
what i have so far is here:
http://jsfiddle.net/9ceeW/
its displaying on click, when i do it on hover they dont work as well or realistically.
this is my first foray into jquery animation and i am not really sure how to proceed next. any help would really be appreciated.
thanks!
You can use the plugin from
http://www.zachstronaut.com/posts/2009/02/17/animate-css-transforms-firefox-webkit.html
add a custom animation queue as in A non-nested animation sequence in jQuery?
and you end up with animated christmas balls at http://jsfiddle.net/gaby/9ceeW/8/
update
updated to allow multiple balls to animate at the same time.. http://jsfiddle.net/gaby/9ceeW/9/
Check out the jQuery Path plugin for animating elements along curves. See the author's demo page.
Not really my thing, but you need to add something like this:
$('#ball1').click(function () {
$(this).effect("bounce", { direction:'left', times:1, distance:60 }, 500);
$(this).effect("bounce", { direction:'left', times:1, distance:30 }, 750);
$(this).effect("bounce", { direction:'left', times:1, distance:15 }, 1000);
$(this).effect("bounce", { direction:'left', times:1, distance:5 }, 1250);
});
Updated fiddle: http://jsfiddle.net/N7qM9/

Categories