How can I reset the auto-scroll interval on my jCarouselLite carousel after some event so that it lets you look at the content for the full interval, regardless of how far along the timer was when you clicked next or previous? Right now, if I click next or previous after 9 seconds, it scrolls again after 1 second.
In the jCarouselLite source code on lines 274-277 is where the auto-scroll is implemented using setInterval. I know you can use clearInterval if you have the ID returned by setInterval, but there isn't one I can get outside of modifying the source code, and I don't want to do that.
Any ideas? Thanks!
jCarouselLite itself doesn't provide any easy way to stop the auto-scrolling, which is an easier problem then do what you seem to want (?did I understand this right: You just want the autoscroll to temporarily stop on click and then continue)
Hacky + potentially buggy way to stop the autoscroll altogether
var x; //hold interval id
$(function() {
var y = window.setInterval; //backup original setInterval function
//overwrite with new function which stores the id for us
window.setInterval = function() {
x = y(arguments[0], arguments[1]);
return x;
};
//now construct carousel
$(".anyClass").jCarouselLite({
btnNext: ".next",
btnPrev: ".prev",
auto: 500
});
//now restore original setInterval function
//as we only needed the custom one for the carousel to capture the hidden
//internal call to setInterval
window.setInterval = y;
});
$("#stopAutoScrollButton").click(function() {
clearInterval(x);
});
Real solution
As we can't get jCarouselLite to do this on its own we simulate the auto behavior ourself.
$(function() {
var autoTime = 5000; //5s
$(".anyClass").jCarouselLite({
btnNext: ".next",
btnPrev: ".prev"
});
//simulate autoscroll by simulating "click" on next link
var x = setInterval("$('.next').trigger('click');", autoTime);
//if stopAuto is clicked the autoscroll is suspended for autoTime
//no matter how far along the timer already was
$("#stopAuto").click(function() {
clearInterval(x);
x = setInterval("$('.next').trigger('click');", autoTime);
});
});
Here's a version with a pause on mouseover built-in. Works nicely.
http://github.com/cheald/jcarousel-lite
None of these answers were what I was looking for, but this is what comes up when I Google 'jcarousellite reset timer', so for the next person looking to:
Make the timer reset when you click your previous/next slide buttons
Pause the slideshow on hover
Then this is what I put together that works for me:
(function($){$.fn.jCarouselLite=function(o){o=$.extend({btnPrev:null,btnNext:null,btnGo:null,mouseWheel:false,auto:null,speed:200,easing:null,vertical:false,circular:true,visible:3,start:0,scroll:1,beforeStart:null,afterEnd:null},o||{});return this.each(function(){var running=false,animCss=o.vertical?"top":"left",sizeCss=o.vertical?"height":"width";var div=$(this),a=$("#featuredlistings a.next"),ul=$("ul",div),tLi=$("li",ul),tl=tLi.size(),v=o.visible;if(o.circular){ul.prepend(tLi.slice(tl-v-1+1).clone()).append(tLi.slice(0,v).clone());o.start+=v;}var li=$("li",ul),itemLength=li.size(),curr=o.start;div.css("visibility","visible");li.css({overflow:"hidden",float:o.vertical?"none":"left"});ul.css({margin:"0",padding:"0",position:"relative","list-style-type":"none","z-index":"1"});div.css({overflow:"hidden",position:"relative","z-index":"2",left:"0px"});var liSize=o.vertical?height(li):width(li);var ulSize=liSize*itemLength;var divSize=liSize*v;li.css({width:li.width(),height:li.height()});ul.css(sizeCss,ulSize+"px").css(animCss,-(curr*liSize));div.css(sizeCss,divSize+"px");if(o.btnPrev)$(o.btnPrev).click(function(){resetAuto(); return go(curr-o.scroll);});if(o.btnNext)$(o.btnNext).click(function(){resetAuto(); return go(curr+o.scroll);});if(o.btnGo)$.each(o.btnGo,function(i,val){$(val).click(function(){return go(o.circular?o.visible+i:i);});});if(o.mouseWheel&&div.mousewheel)div.mousewheel(function(e,d){return d>0?go(curr-o.scroll):go(curr+o.scroll);});if(o.auto){autoScroll=setInterval(function(){go(curr+o.scroll);},o.auto+o.speed);function resetAuto(){clearInterval(autoScroll);autoScroll=setInterval(function(){go(curr+o.scroll);},o.auto+o.speed);};div.hover(function(){clearInterval(autoScroll);},function(){autoScroll=setInterval(function(){go(curr+o.scroll);},o.auto+o.speed);});}function vis(){return li.slice(curr).slice(0,v);};function go(to){if(!running){if(o.beforeStart)o.beforeStart.call(this,vis());if(o.circular){if(to<=o.start-v-1){ul.css(animCss,-((itemLength-(v*2))*liSize)+"px");curr=to==o.start-v-1?itemLength-(v*2)-1:itemLength-(v*2)-o.scroll;}else if(to>=itemLength-v+1){ul.css(animCss,-((v)*liSize)+"px");curr=to==itemLength-v+1?v+1:v+o.scroll;}else curr=to;}else{if(to<0||to>itemLength-v)return;else curr=to;}running=true;ul.animate(animCss=="left"?{left:-(curr*liSize)}:{top:-(curr*liSize)},o.speed,o.easing,function(){if(o.afterEnd)o.afterEnd.call(this,vis());running=false;});if(!o.circular){$(o.btnPrev+","+o.btnNext).removeClass("disabled");$((curr-o.scroll<0&&o.btnPrev)||(curr+o.scroll>itemLength-v&&o.btnNext)||[]).addClass("disabled");}}return false;};});};function css(el,prop){return parseInt($.css(el[0],prop))||0;};function width(el){return el[0].offsetWidth+css(el,'marginLeft')+css(el,'marginRight');};function height(el){return el[0].offsetHeight+css(el,'marginTop')+css(el,'marginBottom');};})(jQuery);
Just swap it out with your current jCarouselLite script and use it just the same.
If you are able/authorized to change the plugin code:
Add a variable to save the interval id to the plugins defaults
interval: null
Search for:
if(o.auto)
Take the code which is executed here and make an internal function with it like:
function runAuto() {
setInterval(function() {
go(curr+o.scroll);
}, o.auto+o.speed);
}
Now just save the interval to your defined variable but clear it first:
function runAuto() {
clearInterval(o.interval);
o.interval = setInterval(function() {
go(curr+o.scroll);
}, o.auto+o.speed);
}
Search for the go() function in the plugin and add a runAuto(), so each time the function go is called it resets the interval.
Of course you must also add the runAuto() call to if(o.auto) so the interval starts at first.
Related
So I'm building this modal / timed animation with slide navigation from scratch.
I have a function for the buttons that navigate the slides, and also a function to animate the frames every 5 secs. My problem is I'm not sure how to "break" the delay function if the user decides to take over by clicking the navigation buttons. As soon as the user clicks any of those buttons the delay based animation function needs to stop working.
// Timer for Animating Frames
// Need a kill timer function
var animateFramesTimer = function(){
$('#tour_1')
.delay(5000).fadeOut('fast', function() {
$('#tour_2')
.fadeIn('fade').delay(5000).fadeOut('fast', function() {
$('#tour_3')
.fadeIn('fade').delay(5000).fadeOut('fast', function() {
$('#tour_4')
.fadeIn('fade').delay(5000).fadeOut('fast', function() {
$('#tour_modal').fadeOut('fast');
// END
});
});
});
});
}
animateFramesTimer();
So I run animateFramesTimer and if a certain button is clicked I need the function to stop working, I tried a while loop which seemed like the correct path to go, but it kept breaking in the browser :(
var autoAnimate = true;
while(autoAnimate){
// delay animation
}
Do you know of a better way to accomplish this?
$('[id^="tour_"]').stop(true, true); // kills current animations
animateFramesTimer = function() {}; // removes function
I have a little fiddle here where I'm starting/stopping/resetting a javascript timer.
The functionality needs to be a timer runs on a page. When the timer is up, it sends a message, then restarts. The stop button will stop the timer completely.
The fiddle above has the functionality I just described, however I feel like I'm not doing this correctly. Is setTimeout the correct way to create this timer? Should I use setInterval instead?
Secondly, my reset code looks like :
var onReset = function() {
clearTimeout(timerHandle);
onStart();
};
Is there a more elegant way to reset a timer in javascript?
Thanks.
The only improvement I can offer is for you to put it all in an encapsulated object, ask if you want an example. Or if you want to keep the structure you've got then change your onStart function to this to remove a bit of un-needed code.
var onStart = function() {
timerHandle = setInterval(function() {
$("#console").append("timer fired.. <br />");
}, 2000);
};
Fiddle here http://jsfiddle.net/qx6CM/
I have made a carousel and using JavaScript setInterval() function for rotate image with fixed interval in carousel. Here's the script that I had used:
var timeOut = 4000;
function showSlide() {
//....script for showing image
}
function pauseSlide() {
setInterval(function(){showSlide();}, timeOut);
}
jQuery(document).ready(function() {
pauseSlide();
});
Now the problem is when I have change the browser tab and after few minute back again to carousel browser and what I seen carousel running too faster rather than default time interval, images going to change fast suppose 0 time interval. Please help me with how I can sort this out.
You must get rid of the first interval before starting another, or you start getting more than one interval working simultaneously (i.e. why you start seeing it go "faster")
Do this
var timeOut = 4000;
var interval = 0;
function showSlide() {
//....script for showing image
}
function pauseSlide() {
clearInterval(interval);
interval = setInterval(function(){showSlide();}, timeOut);
}
jQuery(document).ready(function() {
//NOW you can do multiple pauseSlide() calls
pauseSlide();
pauseSlide();
pauseSlide();
pauseSlide();
pauseSlide();
});
From what I know in newer versions of both firefox and chrome, background tabs have setTimeout and setInterval clamped to 1000ms to improve performance. So I think that your issue might relate to that.
Maybe this will help : How can I make setInterval also work when a tab is inactive in Chrome?
Image changing faster than expected may indicate that you have more than one call to pauseSlide(), in one way or another.
Is document ready the only place you call the function ? Any code in showslide or anywhere triggering a document ready event ? If you put an alert() in pauseSlide(), does it popup more than once ?
I’m having a setTimeout problem similar to this one. But that solution doesn't help me since I can’t use php in my file.
My site has a slider with a list of images that move every 8 seconds.However, when I have opened a few tabs in the browser and then switch back again, it goes nuts.
The slider proceeds to move the images one after the other immediately without the 8 second timedelay.
I'm only seeing it in Chrome and the latest Firefox.
**EDIT: I checked with console.log() and the setTimeout returns the same number before and after the clearTimeout. Not sure why. Maybe that also has something to do with it? **
EDIT 2: I added a fiddle: http://jsfiddle.net/Rembrand/qHGAq/8/
The code looks something like:
spotlight: {
i: 0,
timeOutSpotlight: null,
init: function()
{
$('#spotlight .controls a').click(function(e) {
// do stuff here to count and move images
// Don't follow the link
e.preventDefault();
// Clear timeout
clearTimeout(spotlight.timeOutSpotlight);
// Some stuff here to calculate next item
// Call next spotlight in 8 seconds
spotlight.timeOutSpotlight = setTimeout(function () {
spotlight.animate(spotlight.i);
}, 8000);
});
// Select first item
$('#spotlight .controls a.next:first').trigger('click');
},
animate: function(i)
{
$('#spotlight .controls li:eq(' + (spotlight.i) + ') a.next').trigger('click');
}
}
From the jQuery documentation:
Because of the nature of requestAnimationFrame(), you should never
queue animations using a setInterval or setTimeout loop. In order to
preserve CPU resources, browsers that support requestAnimationFrame
will not update animations when the window/tab is not displayed. If
you continue to queue animations via setInterval or setTimeout while
animation is paused, all of the queued animations will begin playing
when the window/tab regains focus. To avoid this potential problem,
use the callback of your last animation in the loop, or append a
function to the elements .queue() to set the timeout to start the next
animation.
I finally found my answer and it’s not at all what I was expecting.
It seems the culprit is jQuery’s .animate(), which I use to move the images in the slider.
I calculate and move my images positions with this:
$('.spotlight-inner')
.animate(
{ left: scrollToVal },
{duration: 'slow'}
)
;
Now the problem seems to be that in some browsers, after you switch to a new tab and back, jQuery’s .animate() saves up the animations and fires them all at once. So I added a filter to prevent queueing. That solutions comes from CSS-Tricks.com :
$('.spotlight-inner')
.filter(':not(:animated)')
.animate(
{ left: scrollToVal },
{duration: 'slow'}
)
;
The first slide you see when you go back can act a little jumpy but it’s better than the superspeed carousel from before.
Fiddle with the full code here
There is an easier way using the jquery animate queue property:
$(this).animate({
left: '+=100'
}, {duration:500, queue:false});
I don't know if this will help you, but it helped me with my slideshow. What I did was everytime I called an animation that was supposed to happen at a set interval because of the setTimeout, I called clearQueue() which would get rid of any other animations that had been set to happen. then i'd call the animation. That way when you come back to that tab, you don't have all these animations queued up and it goes crazy. at max you'll only have one set up.
So something like this:
spotlight.timeOutSpotlight = setTimeout(function () {
spotlight.clearQueue(); // get rid of other instances of the animation
spotlight.animate(spotlight.i);
}, 8000);
It may not work in all cases (depending on timing), but I hope that helps somebody!
You must also think you use clearTimeout.
As you call setTimeout function it returns an ID you can save this ID in a variable like
timeoutID = setTimeout(function () {
spotlight.animate(spotlight.i);
}, 8000);
and before setting a new timeout you can call the function like
clearTimeout(timeoutID)
My suspicion is that the browser queues input events like 'click' but only fires them when the tab where the event occurs actually has focus.
Perhaps you should try calling your click callbacks directly instead of using trigger('click').
Something like this:
spotlight: {
i: 0,
timeOutSpotlight: null,
clickFunc: function(element) {
// do stuff here to count and move images
// Clear timeout
clearTimeout(spotlight.timeOutSpotlight);
// Some stuff here to calculate next item
// Call next spotlight in 8 seconds
spotlight.timeOutSpotlight = setTimeout(function () {
spotlight.animate(spotlight.i);
}, 8000);
},
init: function()
{
$('#spotlight .controls a').click(function (e) {
// Don't follow the link
e.preventDefault();
spotlight.clickFunc(this);
});
// Select first item
spotlight.clickFunc($('#spotlight .controls a.next:first'));
},
animate: function(i)
{
var element = $('#spotlight .controls li:eq('+spotlight.i+') a.next');
spotlight.clickFunc(element);
}
}
What version of jQuery are you running? Apparently this problem was 'fixed' for version 1.6.3 - they reverted the change that caused this to happen. Discussions here and here.
Though this issue will likely have to be addressed in the future, it seems as though we're off the hook for now.
Can anyone point me to an example of code for a page that begins to automatically scroll when the user is idle for an amount of time? I think this is slightly beyond my skill set. I think JQuery or something similar might be appropriate but I just can't seem to figure it out. I'm designing a site for the nonprofit I work for and we don't have the money to hire a programmer. I wouldn't ask anyone to code anything for me, just to point me in the right direction. Thank you so much.
Julie K.
Here is something quick and dirty that will do what you want. I currently have it set to 2 seconds idle time, but you can change that as you wish.
var now = new Date();
setInterval(function(){
var nnow = new Date();
if(nnow.getTime() - now.getTime() >= 2000)
$('body').animate({scrollTop: '+=50'}, 2000, 'linear');
}, 2000);
$(document)
.mousemove(function(){ now = new Date(); $('body').stop(); })
.keypress(function(){ now = new Date(); $('body').stop(); });
Edit: added .stop in mousemove and keypress events to stop scrolling immediately when user moves mouse or presses a key, rather than waiting for animation to complete.
jQuery would definitely help here.
You should handle the keyboard and mouse events to catch user activity.
Then, whenever you see activity, call setTimeout to make your code run 2 minutes after the activity. Save the return value of the setTimeout call in a global variable, and call clearTimeout on it before setTimeout to clear the last timeout.
For example: (Using jQuery and the scrollTo plugin)
var timeout = false;
$(document.body).bind('keydown keyup mousemove mouseup', function() {
if (timeout) clearTimeout(timeout);
timeout = setTimeout(userIsIdle, 120000); //120,000 milliseconds
});
function userIsIdle() {
$(document.body).scrollTo('100%', 100000);
}
you could use a plugin like this, and set it to use JavaScripts setTimeout() function to trigger it, which could reset every time you detect certain user actions, such as keyDown and Click.
First you have to define what you mean by IDLE, I will assume that the user is not moving mouse for x amount of time.
Here are the steps pseudo js.
var lastTime=0;
var threshold=60000 ; // 1min
var howOftenToCheck = 1000;//1 sec
var inter = 0;
inter = setInterval(function() {
var delta=lastTime-currentTime;
if(delta>threashold){
clearInterval(inter);
window.scrollTo(xpos,ypos);
}
}, howOftenToCheck);
This should give you a general idea.
use the following jQuery functions to scroll the page's body
// Scrolling Down
$('body').animate({
scrollTop: '-=300px'
}, 2000);
// Scrolling Up
$('body').animate({
scrollTop: '+=300px'
}, 2000);
I think onBlur event is what you're looking for, so you can do like this :
<body onblur="$('html, body').animate({scrollTop:0}, 'slow');">
You can change the 0 to the vertical position where you want to scroll to.
Note: this will fire the scrolling when you go to other page or tab or where you can't see the page.