I would like to update the page only when there are no mouse events,
Such as:
function TimedRefresh(t) {
$('#colorbox').mousemove(event) {
if (mousemove != 0) { //(mousemove == false)
setTimeout("location.reload(false);", t);
}
}
}
It of course does not work. It's called by:
<body onload="JavaScript:TimedRefresh(5000);">
You'd do that like this
$('#colorbox').mousemove(function( event ) {
clearTimeout( $(this).data('timer') );
$(this).data('timer', setTimeout(function() {
window.location.reload();
}, 5000));
});
When the mouse moves within the #colorbox element, the timer is reset, and if no mouse movement is detected, it reloads the page in 5 seconds.
FIDDLE
You need to reverse the logic. Set the timer onload of the page and then clear/restart it when the mouse is moved. If the mouse is not moved for longer than 5 seconds, then the page will refresh:
$(document).ready(function() {
var timer;
resetTimer();
$('#colorbox').mousemove(function() {
resetTimer(timer);
});
function resetTimer() {
clearTimeout(timer);
timer = setTimeout(function() {
window.location.reload(false);
}, 5000);
}
});
Working example
I think you should do something likes this:
Create a hidden field with a default value (maybe 0).
When some MouseEvent is triggered then yo should change the value of the hidden field (maybe 1)
Then, for other side I think you could use a function like setTimeout for comparing and refresing your page. Here you can read more about this function
Related
i am trying to make a function that when clicking your mouse, can see that you are active or AFK. When the time runs out, this person must be offline. If the person clicks again after the time runs out, the person must come back online. Furthermore, the time must always be reset if he clicks again within the time so you can see that he is active on the page. Does anyone know what I need to adjust here to make it work?
var time;
window.addEventListener('click', function() {
time = setTimeout(function() {
SaveUrl('Save/SetIsOnlineUser', { isOnline: false });
}, 20000);
})
window.addEventListener("click", myFunction);
function myFunction() {
clearTimeout(time)
SaveUrl('Save/SetIsOnlineUser', { isOnline: true });
}
Your logic is flawed as you run opposing logic under two handlers which run under the same event.
To fix this you instead need to use a single event handler. You can set the user online immediately within the click handler, then set the timeout for N seconds later to mark them as offline, something like this:
var time;
window.addEventListener('click', function() {
clearTimeout(time)
SaveUrl('Save/SetIsOnlineUser', {
isOnline: true
});
time = setTimeout(function() {
SaveUrl('Save/SetIsOnlineUser', {
isOnline: false
});
}, 5000);
})
function SaveUrl(u, o) {
console.log('Online:', o.isOnline);
}
Note that I made the timer only 5 seconds to make the effect more obvious.
I can do something such as the following every 30 seconds to reload the page, and the backend logic will determine which session have been invalidated:
setInterval(function () {
location.reload()
}, 30000);
However, how would I only run this 30s location.reload() if the user is not active? For example, how banks will have a user-timeout if the user has not been active on the page (which only starts counting after the user is 'inactive'). How would this be done?
One way is to track mousemoves. If the user has taken focus away from the page, or lost interest, there will usually be no mouse activity:
(function() {
var lastMove = Date.now();
document.onmousemove = function() {
lastMove = Date.now();
}
setInterval(function() {
var diff = Date.now() - lastMove;
if (diff > 1000) {
console.log('Inactive for ' + diff + ' ms');
}
}, 1000);
}());
First define what "active" means. "Active" means probably, sending a mouse click and a keystroke.
Then, design your own handler for these situations, something like this:
// Reseting the reload timer
MyActivityWatchdog.prototype.resetReloadTimer = function(event) {
var reloadTimeInterval = 30000;
var timerId = null;
...
if (timerId) {
window.clearInterval(timerId);
}
timerId = window.setInterval( reload... , reloadTimeInterval);
...
};
Then, make sure the necessary event handler will call resetReloadTimer(). For that, you have to look what your software already does. Are there key press handlers? Are there mouse movement handlers? Without knowing your code, registering keypress or mousemove on document or window and could be a good start:
window.onmousemove = function() {
...
activityWatchdog.resetReloadTimer();
...
};
But like this, be prepared that child elements like buttons etc. won't fire the event, and that there are already different event handlers. The compromise will be finding a good set of elements with registered handlers that makes sure "active" will be recognized. E.g. if you have a big rich text editor in your application, it may be enough to register only there. So maybe you can just add the call to resetReloadTimer() to the code there.
To solve the problem, use window blur and focus, if the person is not there for 30 seconds ,it will go in the else condition otherwise it will reload the page .
setTimeout(function(){
$(window).on("blur focus", function(e) {
var prevType = $(this).data("prevType");
if (prevType != e.type) { // reduce double fire issues
switch (e.type) {
case "blur":
$('div').text("user is not active on page ");
break;
case "focus":
location.reload()
break;
}
}
$(this).data("prevType", e.type);
})},30000);
DEMO : http://jsfiddle.net/rpawdg6w/2/
You can check user Session in a background , for example send AJAX call every 30 - 60 seconds. And if AJAX's response will be insufficient (e.g. Session expired) then you can reload the page.
var timer;
function checkSession() {
$.ajax({
url : 'checksession.php',
success: function(response) {
if (response == false) {
location.reload();
}
}
});
clearTimeout(timer);
timer = setTimeout(checkSession,30 * 1000);
}
checkSession();
I am writing an infinite scroll function and having it run if the $(window).scrollTop() is almost as large as the documents height, and it works perfectly...
The issue is that it takes a couple seconds for the new posts to load, and in that time, if the page was scrolled, the function was called multiple times before the document got larger and therefore did not load the posts the way I intented.
Can I add a line to a function that will pause a specific event (in this case the scroll event) until the function has finished executing?
function f(){
//stop $(window).scroll
//execute code
//allow $(window).scroll
}
$(window).scroll(function(){
if(condition){
f();
}
});
John Resig did a post on this awhile ago
Here is the code he used
didScroll = false;
$(window).scroll(function() {
didScroll = true;
});
setInterval(function() {
if ( didScroll ) {
didScroll = false;
// Check your page position and then
// Load in more results
}
}, 250);
You can use $.off to unbind an event, but I would recommend to just use a variable to keep track if its been triggered or not.
This snippet will prevent f from being called until the scrolling has been set to false again.
$(window).scroll(function(){
if(this.scrolling == undefined)
this.scrolling = false;
if(this.scrolling == false){
this.scrolling = true;
f();
}
});
function f(){
//execute code
window.scrolling = false;
}
You can remove the scroll event once it's called, then reattach it if/when the load posts request is completed:
function loadPosts() {
if (condition) { // e.g. scrollTop almost equal to document height.
$(window).off('scroll', loadPosts);
$('[selector]').load('[URL-to-posts]', function(posts) {
bindScroll();
// Display posts.
});
}
}
// Binds the scroll event.
function bindScroll() {
$(window).on('scroll', loadPosts);
}
$(bindScroll); // Call on document ready.
Is there a way to stop setTimeout("myfunction()",10000); from counting up when the page isn't active. For instance,
A user arrives at a "some page" and stays there for 2000ms
User goes to another tab, leaves "some page" open.
myfunction() doesn't fire until they've come back for another 8000ms.
(function() {
var time = 10000,
delta = 100,
tid;
tid = setInterval(function() {
if ( document.hidden ) { return; }
time -= delta;
if ( time <= 0 ) {
clearInterval(tid);
myFunction(); // time passed - do your work
}
}, delta);
})();
Live demo: https://jsbin.com/xaxodaw/quiet
Changelog:
June 9, 2019: I’ve switched to using document.hidden to detect when the page is not visible.
Great answer by Šime Vidas, it helped me with my own coding. For completeness sake I made an example for if you want to use setTimeout instead of setInterval:
(function() {
function myFunction() {
if(window.blurred) {
setTimeout(myFunction, 100);
return;
}
// What you normally want to happen
setTimeout(myFunction, 10000);
};
setTimeout(myFunction, 10000);
window.onblur = function() {window.blurred = true;};
window.onfocus = function() {window.blurred = false;};
})();
You'll see that the window blurred check has a shorter time set than normal, so you can set this depending on how soon you require the rest of the function to be run when the window regains focus.
You can do something like:
$([window, document]).blur(function() {
// Clear timeout here
}).focus(function() {
// start timeout back up here
});
Window is for IE, document is for the rest of the browser world.
I use almost the same approach as Šime Vidas in my slider
but my code is based on document.visibilityState for page visibility checking:
document.addEventListener("visibilitychange", () => {
if ( document.visibilityState === "visible" ) {
slideshow.play();
} else {
slideshow.pause();
}
});
About Page Visibility
API: https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API
What you'd have to do is set up a mechanism to set timeouts at small intervals, keeping track of total elapsed time. You'd also track "mouseenter" and "mouseleave" on the whole page (the <body> or something). When the short-term timeouts expire, they can check the window state (in or out) and not restart the process when the window is not in focus. The "mouseenter" handler would start all paused timers.
edit — #Šime Vidas has posted an excellent example.
I've finally implemented a variation of #Šime Vidas' answer, because the interval was still running if I opened another program and the browser window was not visible, but the page executing the interval was the active browser tab. So, I've modified the condition to document.hidden || !document.hasFocus(). This way, if the document is hidden or the document doesn't have the focus, the interval function just returns.
(function() {
var time = 10000,
delta = 100,
tid;
tid = setInterval(function() {
if ( document.hidden || !document.hasFocus() ) { return; }
time -= delta;
if ( time <= 0 ) {
clearInterval(tid);
myFunction(); // time passed - do your work
}
}, delta);
})();
I wrote a Jquery function that blacks out the screen after a certain amount of inactivity, creates a pop-up that allows the user to click a button to stay logged in, and logs them out (closing the application window) if they do not respond in time.
The environment is ASP.NET (VB). We don't technically use master pages, but we do have a parent page in which our header, footer and nav reside, and my Jquery code is called from that window, loaded via an IFrame.
I've got a function in the child window that reports activity (currently keydown, mousedown and blur) to the parent window, and resets the timer. My code seems to be working fine, except in one scenario. If the user is prompted with the timeout warning, and then they click the button to continue their session, if they take no action on the page (mouseclick, keydown, etc.) then the timeout code is not running a second time.
Here is my main jquery function:
function pop_init() {
// show modal div
$("html").css("overflow", "hidden");
$("body").append("<div id='popup_overlay'></div><div id='popup_window'></div>");
//$("#popup_overlay").click(popup_remove); // removed to make sure user clicks button to continue session.
$("#popup_overlay").addClass("popup_overlayBG");
$("#popup_overlay").fadeIn("slow");
// build warning box
$("#popup_window").append("<h1>Warning!!!</h1>");
$("#popup_window").append("<p id='popup_message'><center>Your session is about to expire. Please click the button below to continue working without losing your session.</center></p>");
$("#popup_window").append("<div class='buttons'><center><button id='continue' class='positive' type='submit'><img src='images/green-checkmark.png' alt=''/> Continue Working</button></center></div>");
// attach action to button
$("#continue").click(session_refresh);
// display warning window
popup_position(400, 300);
$("#popup_window").css({ display: "block" }); //for safari using css instead of show
$("#continue").focus();
$("#continue").blur();
// set pop-up timeout
SESSION_ALIVE = false;
window.setTimeout(popup_expired, WARNING_TIME);
}
Here is the code from the parent window:
<script language="javascript" type="text/javascript">
var timer = false;
window.reportChildActivity = function() {
if (timer !== false) {
clearTimeout(timer);
}
//SESSION_ALIVE = true;
timer = window.setTimeout(pop_init, SESSION_TIME);
}
</script>
Here is the code from the child window:
<script type="text/javascript">
$(document).ready(function() {
window.parent.reportChildActivity();
});
</script>
<script type="text/javascript">
$(document).bind("mousedown keydown blur", function() {
window.parent.reportChildActivity();
});
The last script runs in a file (VB.NET ascx file) that builds the header/menu options for every page in our system.
The last line in the pop_init function clearly should be re-starting the timer, but for some reason it doesn't seem to be working.
Thanks for any help and insight you may have.
Forgot to add my code for the session_refresh function:
function session_refresh() {
SESSION_ALIVE = true;
$(".buttons").hide();
$("#popup_message").html("<center><br />Thank you! You may now resume using the system.<br /></center>");
window.setTimeout(popup_remove, 1000);
$("#popup_window").fadeOut("slow", function() { $('#popup_window,#popup_overlay').trigger("unload").unbind().remove(); });
var timer = false;
window.reportChildActivity = function() {
if (timer !== false) {
clearTimeout(timer);
}
timer = window.setTimeout(pop_init, SESSION_TIME);
}
}
use this: http://www.erichynds.com/jquery/a-new-and-improved-jquery-idle-timeout-plugin/
You need to restart your timer after the user clicks the button.
Well, I seem to have fixed the problem by changing this:
var timer = false;
window.reportChildActivity = function() {
if (timer !== false) {
clearTimeout(timer);
}
timer = window.setTimeout(pop_init, SESSION_TIME);
}
to this:
if (timer !== false) {
clearTimeout(timer);
}
timer = window.setTimeout(pop_init, SESSION_TIME);
I didn't need to re-declare the reportChildActivity function as I was.