Scrolling when idle? - javascript

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.

Related

SetInterval loop relatively confusing to me

HTML
<div id="backspace" ng-click="deleteString(''); decrementCursor();">
JS
<script>
$scope.deleteString = function() {
if($scope.cursorPosVal > 0){
//$scope.name = $scope.name - letter;
$scope.name = [$scope.name.slice(0, $scope.cursorPosVal - 1) + $scope.name.slice($scope.cursorPosVal)].join('');
console.log($scope.name);
setTimeout(function(){ setCaretPosition("inputBox", $scope.cursorPosVal); }, 30);
} else {
$scope.cursorPosVal = 1;
}
};
</script>
I am designing an on screen touchscreen keyboard. This is my backspace button. I am going to make it so that when you click and hold the backspace button, it starts removing characters automatically. I don't know where to begin with creating a setInterval, and I know a setInterval is exactly what I need to use here.
If I'm not wrong, you want that while you're keeping your button pressed, a function repeats itself.
You're right with setInterval(). However, the way you manage the event is wrong.
Take a look at this fiddle (It's not your code, but a simple example is the best way to understand):
http://jsfiddle.net/daq9atdd/1/
$(function(){
var interval = null;
$('#myButton').mousedown(function(){
interval = setInterval(function(){
console.log('Hello !');
}, 250);
});
$('#myButton').mouseup(function(){
clearInterval(interval);
});
});
I start the interval when the button is pressed, store it, and clear it when the button is released.
You’re so sure about setInterval.
If browser briefly hangs for whatever reason (say some background task), setInterval would go on queueing your backspace calls until it has some CPU time. This means user may see no change and hold backspace longer than needed, and then see a whole bunch of characters suddenly vanish when browser is back to normal.
Thus by setting a timeout after every call you’re making sure user won’t remove more characters than needed. Might be important if the goal is to improve UX.
Example implementation with AngularJS directives and setTimeout
See also:
setTimeout or setInterval?
noKid’s fiddle updated with setTimeout in mind

Starting, stopping & refreshing timer javascript

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/

Image flickering with setInterval() function

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 am having trouble adding a delay to a jquery script

I am using a mega menu script I got from here. It works perfectly except seeing as how I have a few of these on my page I would like there to be a delay that the user has to hold their mouse over the link before the menu opens.
I know I need to do this with a setTimeout() tag and a clearTimeout() for when the user does takes their mouse off the link. I just can not figure out where to put this. I've tried just guessing at it but no matter where I put this it seems to either break the function or not matter.
Thank you for any help anyone might be able to provide me with, it is much appreciated.
The basic idea is something like this?
var timeout;
$('#menuID').mouseenter(function(){
clearTimeout(timeout);
$(this).children().show();
}).mouseleave(function(){
timeout = setTimeout(function(){
$(this).children().hide();
},400);
});
Note that the maker used the same way as above:
"p.s: Inside the .js file, there are two variables you may wish to fine tune:"
effectduration: 300, //duration of animation, in milliseconds
delaytimer: 200, //delay after mouseout before menu should be hidden, in milliseconds
Use this function to add a delay on whatever you want
// Function declatation
var delay = (function()
{
var timer = 0;
return function(callback, ms)
{
clearTimeout(timer);
timer = setTimeout(callback, ms);
};
})();
usage:
delay(function()
{
// Do thing you want delayed
}, 1000 );
Replace 1000 with amount of ms you want to delay
EDIT
$("#menuitem").mouseenter(function()
{
delay(function()
{
if($(this).is(':hover'))
// Show menu
}, 1000 );
});

jCarouselLite reset autoscroll interval

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.

Categories