I have an animation every one second and I have a button Stop, when I click to the button the animation is stopped but it continues after. There is not another way to remove the animation ?
This is my code.
$(document).ready(function() {
setInterval(function() {
$("#myImg").animate({top: '50%',left: '50%',width: '174px',height: '174px',padding: '10px'}, 500);
$("#myImg").animate({ marginTop: '0',marginLeft: '0',top: '0',left: '0',width: '70px',height: '70px',padding: '5px'}, 600);
},1000);
});
$("#stop").click(function(){
$("#myImg").stop();
});
Thank you
jsFiddle demo
-You don't need setInterval, you can use the .animate() callback to loop your anim function.
-Nest your animate functions
-Use the .stop() method on your first .animate() iteration just to prevent animation buildups and clear some animation memory ;)
$(document).ready(function() {
function anim(){
$("#myImg").stop().animate({top: '50%',left: '50%',width: '174px',height: '174px',padding: '10px'}, 500, function(){
$(this).animate({ marginTop: '0',marginLeft: '0',top: '0',left: '0',width: '70px',height: '70px',padding: '5px'}, 600, anim); // <-- the 'anim' callback
}); // SCROLL THERE --> TO FIND THE CALLBACK :D -->
}
anim(); // run!!
$("#stop").click(function(){
$("#myImg").stop();
});
});
The setInterval() call is continuously adding in new calls to .animate() to your elements. That means that you succeed in stopping the animation, then the setInterval() calls it again, making the animation run again.
Why do you have this on setInterval()?
In any case, you'll have to cancel the schedule as well. You can do that by doing something similar to the following:
var schedule = setInterval(fn, 1000);
clearInterval(schedule);
Related
I have an image on my site that has a jquery hover action assigned to it. But it's easy to accidentally mouse over that area, and if you do it more than once, the hover keeps appearing, disappearing, appearing, etc, until it's shown and disappeared once for every time you moused over it. Is there a way to make it so the action doesn't fire unless you hover for a few seconds? I don't want to just delay the action, because it would still happen for every mouseover, I want to see if there's a way the mouseover doesn't count unless you're on the image for a few seconds.
Script so far:
$("img.badge").hover(
function() {
$("h3.better").animate({"left": "125px"}, 1200);
},
function() {
$("h3.better").animate({"left": "-500px"}, 800);
});
You could use setTimeout to launch the action and bind a function calling clearTimeout on the mouseout event :
$('img.badge').hover(function(){
window.mytimeout = setTimeout(function(){
$("h3.better").animate({"left": "125px"}, 1200);
}, 2000);
}, function(){
clearTimeout(window.mytimeout);
});
Or you could use a plugin for that, like hoverintent.
Use a .stop() before animate, to cancel the previous animation. I believe this is what you are looking for, and will solve your current problem.
$("img.badge").hover(
function() {
$("h3.better").stop().animate({"left": "125px"}, 1200);
},
function() {
$("h3.better").stop().animate({"left": "-500px"}, 800);
});
You can use a timer to not fire the hover action until you've been hovered a certain amount of time like this and then, if the hover leaves before the timer fires, you clear the timer so nothing happens if you're only hovered a short period of time:
$("img.badge").hover(function() {
var timer = $(this).data("hover");
// if no timer set, set one otherwise if timer is already set, do nothing
if (!timer) {
// set timer that will fire the hover action after 2 seconds
timer = setTimeout(function() {
$("h3.better").stop(true).animate({"left": "125px"}, 1200);
$(this).data("hover", null);
}, 2000);
// save timer
$(this).data("hover", timer);
}
}, function() {
var timer = $(this).data("hover");
if (timer) {
clearTimeout(timer);
$(this).data("hover", null);
} else {
// probably would be better to make this an absolute position rather
// than a relative position
$("h3.better").stop(true).animate({"left": "-500px"}, 800);
}
});
Note: I also added .stop(true) to your animation so animations will never pile up.
I'm looking to get the most efficient way to produce a latest news ticker.
I have a ul which can hold any number of li's and all I need to to loop through them fading one in, holding it for 5 seconds and then fading it out, one li at a time. The list is displaying with an li height of 40px and the well it displays in is also 40px which with overflow: hidden which produces the desired effect. Also to be able to hold the li in place if the cursor hovers over it while its being displayed would be great to build it.
I know there is the jQuery ticker plugin that is widely used (ala the old BBC style) but I've tried to use it and it seems so bulky for the simplicity I need and it plays havoc with the styling I use.
I've been using this so far:
function tickOut(){
$('#ticker li:first').animate({'opacity':0}, 1000, function () {
$(this).appendTo($('#ticker')).css('opacity', 1); });
}
setInterval(function(){ tickOut () }, 5500);
But it doesn't actually fade in the next li so the effect is a bit messy.
If someone could suggest some alternations to help produce the effect I need that would be so useful.
Thanks
hide() and call fadein() the element after it becomes the top of the list.
function tickOut(){
$('#ticker li:first').animate({'opacity':0}, 1000, function () {
$(this).appendTo($('#ticker'))
$('#ticker li:first').hide()
$('#ticker li:first').fadeIn(1000)
$('#ticker li:not(:first)').css('opacity', '1')
});
}
setInterval(function(){ tickOut () }, 5500);
see:
http://codepen.io/anon/pen/lHdGb
I woudl do it like that:
function tickOut(){
$('#ticker li:first').animate({'opacity':0}, 1000, function () {
$(this).appendTo($('#ticker')).css('opacity', 1); });
}
var interval;
$(function() {
interval = setInterval(function(){ tickOut () }, 5500);
$('#ticker').hover(function() {
if(interval)
clearInterval(interval);
$('#ticker li:first').stop();
$('#ticker li:first').css('opacity', 1).stop();
}, function(){
interval = setInterval(function(){ tickOut () }, 5500);
});
});
See $('#ticker').hover which clears interval and stops animation and returns opacity to 1 when mouse got inside UL (may be changed to do that when only some special element inside LI is under mouse) and starts it again once it left that UL. Demo: http://jsfiddle.net/KFyzq/6/
I'm having a problem with setInterval and jquery animate. Here is my code:
function slides1() {
...
$("table#agah1").animate({
"left": first1
}, "slow");
$("table#agah2").animate({
"left": first2
}, "slow");
}
$(function () {
cyc = setInterval("slides1()", 3000);
});
When switch to another browser tab, and return after a time, the animation keep doing it without delay, for the time I've been away from the tab, and then act correct. I've added these also without any luck:
$(window).focus(function () {
jQuery.fx.off = false;
cyc = setInterval("slides1()", 3000);
});
$(window).blur(function () {
jQuery.fx.off = true;
window.clearInterval(cyc);
});
Newer versions of jQuery use requestAnimationFrame callbacks to handle effects, and browsers don't process those on hidden tabs.
In the meantime, your setInterval events are still happening, causing more animations to get queued up.
Rather than use setInterval to schedule the animations, use the "completion callback" of the last animation to trigger the next cycle, with a setTimeout if necessary.
function slides1() {
...
$("table#agah1").animate({
"left": first1
}, "slow");
$("table#agah2").animate({
"left": first2
}, "slow", function() {
setTimeout(slides1, 2000); // start again 2s after this finishes
});
}
$(function () {
setTimeout(slides1, 3000); // nb: not "slides1()"
});
This will ensure that there's a tight coupling between the interanimation delay and the animations themselves, and avoid any issues with setTimeout getting out of sync with the animations.
jQuery code:
target.animate({top:500},{queue: false,duration: 500});
How to use JavaScript to realize the "queue: false" effect?
e.g. window.onscroll event, I just want to be in the end of the event performs some method.
Is this reasonable?:
var timer;
window.onscroll = function(){
console.log('scrolling');
clearTimeout(timer);
timer = setTimeout(function(){console.log('complete');},600);
}
If you're only wanting to perform actions after the animation is complete, then provide a function as the last argument in the animation.
target.animate({top:500}, {queue: false, duration: 500}, function(){
// Animation complete do something else.
});
I have a drop down menu. Now when it's slided down to multiple levels, I'd like it to add wait time for like 2 secs, before it disappears, so the user can get back in, when he breaks the .hover() by mistake.
Is it possible?
my code for the slide:
$('.icon').hover(function() {
$('li.icon > ul').slideDown('fast');
}, function() {
$('li.icon > ul').slideUp('fast');
});
This will make the second function wait 2 seconds (2000 milliseconds) before executing:
$('.icon').hover(function() {
clearTimeout($(this).data('timeout'));
$('li.icon > ul').slideDown('fast');
}, function() {
var t = setTimeout(function() {
$('li.icon > ul').slideUp('fast');
}, 2000);
$(this).data('timeout', t);
});
It also clears the timeout when the user hovers back in to avoid crazy behavior.
This is not a very elegant way of doing this, however. You should probably check out the hoverIntent plugin, which is designed to solve this particular problem.
personally I like the "hoverIntent" plugin:
http://cherne.net/brian/resources/jquery.hoverIntent.html
from the page: hoverIntent is a plug-in that attempts to determine the user's intent... like a crystal ball, only with mouse movement! It works like (and was derived from) jQuery's built-in hover. However, instead of immediately calling the onMouseOver function, it waits until the user's mouse slows down enough before making the call.
Why? To delay or prevent the accidental firing of animations or ajax calls. Simple timeouts work for small areas, but if your target area is large it may execute regardless of intent.
var config = {
sensitivity: 3, // number = sensitivity threshold (must be 1 or higher)
interval: 200, // number = milliseconds for onMouseOver polling interval
over: makeTall, // function = onMouseOver callback (REQUIRED)
timeout: 500, // number = milliseconds delay before onMouseOut
out: makeShort // function = onMouseOut callback (REQUIRED)
};
$("#demo3 li").hoverIntent( config )
Configuration Options
sensitivity:
If the mouse travels fewer than this number of pixels between polling intervals, then the "over" function will be called. With the minimum sensitivity threshold of 1, the mouse must not move between polling intervals. With higher sensitivity thresholds you are more likely to receive a false positive. Default sensitivity: 7
interval:
The number of milliseconds hoverIntent waits between reading/comparing mouse coordinates. When the user's mouse first enters the element its coordinates are recorded. The soonest the "over" function can be called is after a single polling interval. Setting the polling interval higher will increase the delay before the first possible "over" call, but also increases the time to the next point of comparison. Default interval: 100
over:
Required. The function you'd like to call onMouseOver. Your function receives the same "this" and "event" objects as it would from jQuery's hover method.
timeout:
A simple delay, in milliseconds, before the "out" function is called. If the user mouses back over the element before the timeout has expired the "out" function will not be called (nor will the "over" function be called). This is primarily to protect against sloppy/human mousing trajectories that temporarily (and unintentionally) take the user off of the target element... giving them time to return. Default timeout: 0
out:
Required. The function you'd like to call onMouseOut. Your function receives the same "this" and "event" objects as it would from jQuery's hover method. Note, hoverIntent will only call the "out" function if the "over" function has been called on that same run.
The general idea is to use setTimeout, like so:
$('.icon').hover(function() {
$('li.icon > ul').slideDown('fast');
}, function() {
setTimeout(function() {
$('li.icon > ul').slideUp('fast');
}, 2000);
});
But this may do counterintuitive things if the user mouses out and then mouses in again quickly—this doesn't account for clearing the timeout when the user hovers over it again. That would require additional state.
The following will stop the sliding from triggering by 2 seconds:
$('.icon').hover(function() {
$('li.icon > ul').delay(2000).slideDown('fast');
}, function() {
$('li.icon > ul').slideUp('fast');
});
$('.icon').on("mouseenter mouseleave","li.icon > ul",function(e){
var $this = $(this);
if (e.type === 'mouseenter') {
clearTimeout( $this.data('timeout') );
$this.slideDown('fast');
}else{ // is mouseleave:
$this.data( 'timeout', setTimeout(function(){
$this.slideUp('fast');
},2000) );
}
});
or you could simply use
transition:all 2s ease-in-out.
make sure that you add -webkit, -moz and -o for different browsers.
I think this is code your need:
jQuery( document ).ready( function($) {
var navTimers = [];
$('.icon').hover(function() {
var id = jQuery.data( this );
var $this = $( this );
navTimers[id] = setTimeout( function() {
$this.children( 'ul' ).slideDown('fast');
navTimers[id] = "";
}, 300 );
},
function () {
var id = jQuery.data( this );
if ( navTimers[id] != "" ) {
clearTimeout( navTimers[id] );
} else {
$( this ).children( "ul" ).slideUp('fast');
}
}
);
});
var timer;
var delay = 200;
$('#hoverelement').hover(function() {
on mouse hover, start a timeout
timer = setTimeout(function() {
Do your stuff here
}, delay);
}, function() {
Do mouse leaving function stuff here
clearTimeout(timer);
});
//edit: instert code
I would like to add to Paolo Bergantino that you can do this without the data attribut:
var timer;
$('.icon').hover(function() {
clearTimeout(timer);
$('li.icon > ul').slideDown('fast');
}, function() {
timer = setTimeout(function() {
$('li.icon > ul').slideUp('fast');
}, 2000);
});