jquery stop() doesn't work properly - javascript

I have some DIVs for products, and I have:
// mouseenter
$(document).on('mouseenter', '.productWrapper', function(){
$(this).stop(true,true);
$(this).find('.productWrapperContentVisible').animate({
height: '100px',
opacity: '1',
}, function(){
$(this).find('.productWrapperPrice').fadeIn();
$(this).find('.productWrapperByCompany').fadeIn();
});
});
// mouseleave
$(document).on('mouseleave', '.productWrapper', function(){
$(this).stop(true,true);
$(this).find('.productWrapperPrice').fadeOut('fast');
$(this).find('.productWrapperByCompany').fadeOut('fast');
$(this).find('.productWrapperContentVisible').animate({
height: '40px',
opacity: '.8',
});
});
and there are about 20 of products in each page, while I'm using stop(true,true), after I move my mouse on many of them many times, this doesn't work right, they continue to change height, and sometimes productWrapperPrice is still there while I don't have my mouse over there, it should go hidden.. .
sample: http://jsfiddle.net/gwsPB/
What's wrong with my code?
Thanks

Try this:
// mouseenter
$(document).on('mouseenter', '.productWrapper', function () {
$(this).find('.productWrapperContentVisible').stop(true, false).animate({
height: '100px',
opacity: '1'
}, function () {
$(this).find('.productWrapperPrice, .productWrapperByCompany').stop(true, true).fadeIn();
});
}).on('mouseleave', '.productWrapper', function () {
var $this = $(this);
$this.find('.productWrapperPrice, .productWrapperByCompany').stop(true, true).fadeOut('fast');
$this.find('.productWrapperContentVisible').stop(true, false).animate({
height: '40px',
opacity: '.8'
});
});
DEMO
The problem is: when you mouseenter and mouseleave immediately fast enough, your animate function in the mouseenter event is not finished yet. When your call $this.find('.productWrapperContentVisible').stop(true, true), the animation is stopped but the callback function is called which display them again
function () {
$(this).find('.productWrapperPrice, .productWrapperByCompany')
.stop(true, true).fadeIn();
}
By using stop(true, false), the callbacks are not called.

You need to call stop() on elements where are being animated, calling it on an ancestor element has no effect.
// mouseenter
$(document).on('mouseenter', '.productWrapper', function () {
$(this).find('.productWrapperContentVisible').stop(true, true).animate({
height: '100px',
opacity: '1'
}, function () {
$(this).find('.productWrapperPrice, .productWrapperByCompany').stop(true, true).fadeIn();
});
}).on('mouseleave', '.productWrapper', function () {
var $this = $(this);
$this.find('.productWrapperPrice, .productWrapperByCompany').stop(true, true).fadeOut('fast');
$this.find('.productWrapperContentVisible').stop(true, true).animate({
height: '40px',
opacity: '.8'
});
});

Related

How to add multiple event (mouseover/mouseout) into one selector

If I mouseover/mouseout very fast more than one time during animation times (here 900). Button is animating more than one time; even when I stopped mouse activity.
I want that it will take only one event for animation during animation times; even when multiple event triggered.
Other way I want to say if I triggered multiple mouseover event during 900 it will terminate immediately when I triggered mouseout and vice-versa.
$(document).ready(function () {
$("button").mouseover(function () {
$(this).css({
background: 'transparent',
color: '#09F'
});
$("button").animate({
width: "110%",
}, 900);
$(this).text("Show More >");
});
$("button").mouseout(function () {
$(this).css({
background: '#09F',
color: '#FFF'
});
$("button").animate({
width: "100%",
}, 900);
$(this).text("Show More");
});
});
Here's an JSFiddle to show you the behaviour
You need to use .stop()
Stop the currently-running animation on the matched elements.
Use
$(document).ready(function () {
$("button").mouseover(function () {
$(this).css({
background: 'transparent',
color: '#09F'
});
$("button").stop().animate({ //Here used stop
width: "110%",
}, 900);
$(this).text("Show More >");
});
$("button").mouseout(function () {
$(this).css({
background: '#09F',
color: '#FFF'
});
$("button").stop().animate({ //Here used stop
width: "100%",
}, 900);
$(this).text("Show More");
});
});
DEMO
Yes every time because you have some duration for example
$('somelemenent').animate({}, 400);
Your animation will stay in order if you hover element more quickly than your duration.
For this cases, you should set:
$('somelement').stop().animate(/* and your properties */);
Method .stop() stops all effects and orders which have connection with current element.
Use this : add another event after finishing previous one.
$(document).ready(function(){
$("button").mouseover(function() {
$( this ).css({background :'transparent',color : '#09F'});
$( "button").stop().animate({width: "110%",}, 900 );
$(this).text("Show More >");
}).mouseout(function() {
$( this ).css({background :'#09F',color : '#FFF'});
$( "button").stop().animate({width: "100%",}, 900 );
$(this).text("Show More");
});
});

Deny jQuery events during an animation

On hover, I want to animate an div. During the animation I want to disable the hover possibility to avoid the animation call, several times. I removed the mouseenter event with unbind. Once the animation is finished the mouseenter event should be added again, but I'm not able to get this work.
Here is the jQuery:
items.hover(function (e) {
$(e.currentTarget).unbind('mouseenter');
if ($(this).hasClass('xy')) {
$('div.block', this).addClass('xxx').removeClass('zzz').animate({
top: '0'
});
}
}, function (e) {
if ($(this).hasClass('xy')) {
$('div.block', this).animate({
top: topHeightVal
}, 200, function () {
$(e.currentTarget).bind('mouseenter');
}).addClass('zzz').removeClass('xxx');
}
});
Try .stop()
Stop the currently-running animation on the matched elements.
Your code becomes
items.hover(function (e) {
$(e.currentTarget).unbind('mouseenter');
if ($(this).hasClass('xy')) {
$('div.block', this).addClass('xxx').removeClass('zzz').stop(true, true).animate({
top: '0'
});
}
}, function (e) {
if ($(this).hasClass('xy')) {
$('div.block', this).stop(true, true).animate({
top: topHeightVal
}, 200).addClass('zzz').removeClass('xxx');
}
});

how to animate height of a div back-jquery

I'm trying to show some part of a div and animate it to 100% when the div is clicked.
and I want to animate it back to the initial height of the div if it's clicked again.
this is what i have so far,but it doesn't work. can anyone help?
#mydiv {
height:150px;
width: 100%;
overflow:hidden;
}
<script type="text/javascript">
$(document).ready(function(){
$("#mydiv").click(function(){
$(this).animate({height: '100%'}, 300);
}, function() {
$(this).animate({height: '150px'}, 300);
});
});
</script>
click() doesn't accept two function arguments, previously there was a toggle() function that performed how you need it but it has now been deprecated and removed from jQuery.
Since your use case is pretty simple, I believe something like this would be enough:
$("#mydiv").click(function () {
var $this = $(this);
$this.animate({
height: $this.height() == 150 ? '100%' : 150
}, 300);
});
Demo fiddle
This should do the job for you.
jQuery:
$(document).ready(function() {
$("#mydiv").toggle(
function() {
$(this).animate({height: '100%'}, 300);
};
function() {
$(this).animate({height: 150}, 300);
});
});

How to get `morpha.start()` after 2sec `mouseenter`?

Mootools: How to get morpha.start() after 2sec mouseenter?
window.addEvent('domready',function() {
var morph = new Fx.Morph('resize',{duration:700,delay:400});
$$('#resize').addEvent('mouseenter',function(e){
e.stop();
morpha.start({
width: '200px',
height: '100px'
});
}//It does not work on adding ',2000' here
);
<div id="resize" class="resize">DIV will get bigger after 2sec on mouseenter</div>
use delay.
http://www.jsfiddle.net/dimitar/m6JKt/ example
document.id('resize').set("morph", {duration:700,delay:400}).addEvents({
mouseenter: function(){
this.store("timer", (function() {
this.morph({
width: '200px',
height: '100px'
});
}).delay(2000, this));
},
mouseleave: function() {
$clear(this.retrieve("timer"));
}
});
this has also been refactored to use element.morph which does the class instance for you - and it will cancel the transition if you mouseout within the 2 seconds starting period grace.

Animate an Image after hovering an item a second

after some tries to get this to work, i ask you, if you know where my mistake is.
This is my code until now:
$(".menu a").hover( function () {
$(this).data('timeout', setTimeout( function () {
$(this).hover(function() {
$(this).next("em").animate({opacity: "show", top: "-65"}, "slow");
}, function() {
$(this).next("em").animate({opacity: "hide", top: "-75"}, "fast");
});
}, 1000));
}, function () {
clearTimeout($(this).data('timeout'));
});
i would be happy about some help.
I tried this but it doesn't work. one more information perhaps it will make it more clear. i had the function like this before:
$(".menu a").hover(function() {
$(this).next("em").animate({opacity: "show", top: "-65"}, "slow");
}, function() {
$(this).next("em").animate({opacity: "hide", top: "-75"}, "fast");
});
it worked but so it will be viewed imidiately. so i found this to set a timer that it show the popup only after in this example one second:
$("#hello").hover( function () {
$(this).data('timeout', setTimeout( function () {
alert('You have been hovering this element for 1000ms');
}, 1000));
}, function () {
clearTimeout($(this).data('timeout'));
});
both worked it self but if i put them together it does nothing
Inside the setTimeout callback, this does not refer to the hovered element.
To fix this, you need to make a separate variable in the event handler, like this: (pun intended)
$(".menu a").hover( function () {
var me = $(this);
me.data('timeout', setTimeout( function () {
me.hover(function() {
me.next("em").animate({opacity: "show", top: "-65"}, "slow");
}, function() {
me.next("em").animate({opacity: "hide", top: "-75"}, "fast");
});
}, 1000));
}, function () {
clearTimeout($(this).data('timeout'));
});
You don't need to use me inside the inner hover handlers, but you might as well.
Theres a nice plugin that does this: hoverIntent. Replace .hover with .hoverIntent, and you wont have to deal with setting and clearing the timeout manually.

Categories

Resources