I have an animation that causes boxes to appear in sequence when clicking a link. I'm finding that the animation does not stop when clicking a new link and will often cause the it to appear out of sequence. You can see this here when clicking between guests rapidly. I thought something like $.animation.stop() would solve the issue but it hasn't. Any help would be appreciated.
var stepFade = function() {
if ($($this).data("known1") === undefined || null) {
$('.guest-data .known-for').css('display', 'none');
} else {
$('.guest-data .known-for').css('display', 'block');
$('.guest-data .known-for li').eq(0).delay(200).fadeIn( 300);
$('.guest-data .known-for li').eq(1).delay(300).fadeIn( 300);
$('.guest-data .known-for li').eq(2).delay(400).fadeIn( 300, function() { animating = false; });
}
}
//Fade guest
if (!featured) {
featured = true;
getData();
$('.featured').fadeOut( 500, function () {
$('.selected').animate({ opacity: 'toggle'}, 500, function() {
stepFade();
});
})
} else {
$('.selected, .guest-data .known-for, .guest-data .known-for li').fadeOut( 500, function () {
getData();
$('.selected').fadeIn( 500, function() {
stepFade();
});
});
}
Have you tried setting the queue option of .animate() to false?
This way, the animation won't be queued and will begin immediately:
$('.selected')
.animate({opacity: 'toggle'},
{duration: 500, queue: false,
complete: function() { stepFade(); }
});
...OR you could call .stop() right before you call .animate():
$('.selected')
.stop(true, false) //clear the queue and don't jump to the end
.animate({opacity: 'toggle'}, 500, function() {
stepFade();
});
Related
I've got a following code for fadeOut, load another content and fadeIn, but I've got a problem, that sometimes, when the load function is very fast, it switches the loaded content even before the timeline completely fadeOut, so the effect is a bit weird at this case. How can I prevent this?
Note
I want to load content immediately after click, so putting the load function into the first fadeTo callback function is not the solution. Thanks!
$(".switches li").click(function(evn) {
$(".switches li").removeClass("active");
$(evn.target).addClass("active");
$(".timeline").fadeTo(400, 0, function(){
$(this).css("visibility", "hidden");
});
$(".timeline").load("inc-timeline/"+evn.target.id+".html", function() {
$(this).fadeTo(400, 100, function() {
$(this).css("visibility", "visible");
if(evn.target.id === "data-girls") {
$(".data-girls-powered").fadeIn(400);
} else {
$(".data-girls-powered").fadeOut(400);
}
});
});
});
Use start option of .animate(), .finish()
// call `.load()` when `.fadeTo(400, 0)` starts
$(".timeline").finish().animate({opacity:0},{
start: function() {
// do asynchronous stuff; e.g., `.load()`
$(this).load("inc-timeline/"+evn.target.id+".html", function() {
// stop `.fadeTo(400, 0)` animation,
// start animating to `opacity:1`
$(this).finish().fadeTo(400, 1, function() {
// do stuff
});
});
},
duration: 400
});
$("button").click(function() {
// call `.load()` when `.fadeTo(400, 0)` starts
$(".timeline").finish().animate({opacity:0},{
start: function() {
var el = $(this);
// do asynchronous stuff; e.g., `.load()`
$.Deferred(function(dfd) {
setTimeout(function() {
dfd.resolveWith(el)
}, Math.floor(Math.random() * 3500))
}).promise().then(function() {
// stop `.fadeTo(400, 0)` animation,
// start animating to `opacity:1`
$(this).finish().fadeTo(400, 1, function() {
});
});
},
duration: 400
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>click</button>
<div class="timeline">abc</div>
What about changing the duration of the load..to be longer than 400 milliseconds, would that help?
I've got this code
var goRight = function() {
$(this).animate({'left:' '40px'}, 1000, goLeft);
};
var goLeft = function() {
$(this).animate({'left:' '-40px'}, 1000, goRight);
};
var main = function() {
$('.square').hover(function() {
$(this).toggleClass('active');
});
$('.square').goRight();
};
$(document).ready(main);
It supposed to move the square(a div) to the right then back to the left infinitely and make it blue when the user hovers over it. But it doesn't work. The problem is probably in the goRight and goLeft, functions. Since if I remove them completely the hover changes the color fine. And when these functions are there nothing works.
You need to do the chaining like this
$.fn.goRight = function() {
this.animate({
'left': '40px'
}, 1000, function() {
$(this).goLeft()
});
return this;
};
$.fn.goLeft = function() {
this.animate({
'left': '-40px'
}, 1000, function() {
$(this).goRight()
});
return this;
};
var main = function() {
$('.square').hover(function() {
$(this).toggleClass('active');
});
$('.square').goRight();
};
$(document).ready(main);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div style="width:100px;height:100px;background:black;position:relative;" class="square"></div>
For more about jQuery plugin development : https://learn.jquery.com/plugins/basic-plugin-creation/
$('#next').hover(function () {
$('#sliderWrapper').animate({
scrollLeft: "+=200px"
}, "fast");
});
$('#prev').hover(function () {
$('#sliderWrapper').animate({
scrollLeft: "-=200px"
}, "fast");
});
See fiddle. I'm trying to get the scrolling to be continuous while hovering .hover() function isn't working properly or as I thought it would.
maybe this help you
DEMO
function loopNext(){
$('#sliderWrapper').stop().animate({scrollLeft:'+=20'}, 'fast', 'linear', loopNext);
}
function loopPrev(){
$('#sliderWrapper').stop().animate({scrollLeft:'-=20'}, 'fast', 'linear', loopPrev);
}
function stop(){
$('#sliderWrapper').stop();
}
$('#next').hover(function () {
loopNext();
},function () {
stop();
});
$('#prev').hover(function () {
loopPrev();
},function () {
stop();
});
Source: Continuous scroll on hover [performance]
Try this jsFiddle
This will, on the next hover, start animating towards the width of the containing div. When you mouse out, it will stop. On the prev hover will start animating to 0 and when you mouse out it will stop.
$('#next').hover(function () {
$('#sliderWrapper').animate({scrollLeft: $(this).siblings("#sliderWrapper").width()}, 5000);
}, function() {
$('#sliderWrapper').stop();
});
$('#prev').hover(function () {
$('#sliderWrapper').animate({scrollLeft: 0 }, 5000);
}, function() {
$('#sliderWrapper').stop();
});
I would suggest using the mouse over and out events. When the mouse goes over start animating and when the mouse goes out stop animating.
I'm using Jquery Collision to detect two objects overlapping each other. Here is a JSFiddle of the problem.
(apologies for including jquery collision script in HTML, couldn't find other way)
Click anywhere in the gray container to move the green div over the white div.
HTML Structure:
<div class="container">
<div class="test"></div>
<div class="menu"></div>
</div>
JS:
$(document).ready(function () {
var hit_list;
$(".container").click(function () {
$(".menu").stop().animate({
left: "+=100px"
}, 300, function () {
$(".menu").animate({
left: "0"
}, 800);
});
//Test for collision
hit_list = $(".menu").collision(".test");
if (hit_list.length != 0) {
alert("welcome Earthling!");
}
});
});
The problem with my method is that, it doesn't detect collision every time. Even though it passes over the white division fine, the alert isn't displayed everytime.
Am I going wrong anywhere in checking for collision? Is there a better/more efficient method to detect collisions during animation ?
jQuery animate has a step callback (https://api.jquery.com/animate/), it gets executed after each step of the animation.
Use it like this:
$(document).ready(function () {
var hit_list;
$(".container").click(function () {
$(".menu").stop().animate({
left: "+=100px"
}, {
duration: 300,
complete: function () {
$(".menu").animate({
left: "0"
}, 800);
},
step: function(){
//Test for collision
hit_list = $(".menu").collision(".test");
if (hit_list.length != 0) {
alert("welcome Earthling!");
}
}
});
});
});
Try this http://jsfiddle.net/aamir/y7PEp/6/
$(document).ready(function () {
var hit_list;
var hits=0;
$(".container").click(function () {
var $this = $(this);
function checkCollision() {
//Test for collision
hit_list = $(".menu").collision(".test");
if (hit_list.length != 0) {
hits++;
$(".menu").html(hits+ ' hits');
}
}
$(".menu").stop().animate({
left: "100px"
}, 300, function () {
checkCollision();
$(".menu").animate({
left: "0"
}, 800);
});
});
});
I developed a simple jQuery animation first and later I create a jQuery function for reusability which will do the same thing. Here is a demo: http://jsfiddle.net/SpMns/
My code is working but not reliably so: when I click on the button to run the code, nothing happens; clicking it two or three times will start the animation. Why wouldn't it work the first time?
Please have a look at my routine and tell me which area I need to rectify:
jQuery.fn.busyToggle = function(ImgLoadSrc, marginBottom, opacity, speed,
easing, callback) {
var oDiv = $("<div id='BusyBox'><img src='" + ImgLoadSrc
+ "' alt='Loading...'/><div><em>Loading Wait...</em></div></div>");
if ($("#BusyBox").exists() == false) {
//alert('div not exist');
oDiv.css("background", "-moz-linear-gradient(center top , #F1F2F2 0%, #F1F2F2 100%) repeat scroll 0 0 transparent");
oDiv.css("border-top-left-radius", "5px");
oDiv.css("border-top-right-radius", "5px");
oDiv.css("bottom", "0px");
oDiv.css("font-size", "0.8em");
oDiv.css("font-style", "normal");
oDiv.css("font-weight", "normal");
oDiv.css("left", "50%");
oDiv.css("margin-left", "-45px");
oDiv.css("padding-top", "20px");
oDiv.css("position", "fixed");
oDiv.css("text-align", "center");
oDiv.css("width", "90px");
oDiv.css("height", "50px");
oDiv.css("margin-bottom", "-70px");
oDiv.css("background-repeat", "no-repeat");
oDiv.css("background-position", "center center");
oDiv.data('IsUp', 1)
oDiv.appendTo('body');
}
// i work with jquery data function for achieving toggle behaviour
if (oDiv.data('IsUp') == 1) {
oDiv.data('IsUp', 0);
return this.stop(true).animate({
marginBottom: marginBottom,
opacity: opacity
}, {
queue: false,
duration: speed,
complete: callback
});
}
else {
oDiv.data('IsUp', 1);
return this.stop(true).animate({
marginBottom: marginBottom,
opacity: opacity
}, {
queue: false,
duration: speed,
complete: callback
});
}
};
$(document).ready(function() {
$("#Process").click(function() {
if (flag == 1) {
$('#BusyBox').busyToggle('images/loader.gif', 0, 1, 500, 0, function() {
alert('div visible')
});
flag = 0;
}
else {
$('#BusyBox').busyToggle('images/loader.gif', -70, 0, 500, 0, function(){
alert('div hide')
});
flag = 1;
}
return false;
});
});
What could be causing this to fail the first time it's run?
The problem are is the this usage in the #busyToggle
On the first call $('#BusyBox') becomes an empty Array, which means that this (in #busyToggle) is also empty Array.
A better solution to your probelm would be to call busyToggle this way:
$('#Process').busyToggle('images/loader.gif', 0, 1, 500, 0, function() {
alert('div visible')
});
and use $('#BusyBox') instead of this in your function.
You can find all the code over there: http://jsfiddle.net/ubmCt/8/
P.S: I've also added following line to the ready function, otherwise it won't run in most browsers
var flag = 1;