jQuery | Is calling setTimeout on mousemove bad practice/inefficient? - javascript

This code determines if the user is online :
/* User online status */
var online = true;
var activeTimeout = setTimeout(_setUserInactive, 5000);
$(document).on("mousemove keydown keyup click", function () {
clearTimeout(activeTimeout);
activeTimeout = setTimeout(_setUserInactive, 5000);
if (!online) {
_setUserActive();
}
});
Pretty simple. But, is this going to cause performance issues? It will call every time the mouse is moved. Thanks.

Related

When does a click become a hold?

I'm making a web app where a button's behavior is different if the user clicks vs holds the button. I have been experimenting with different timings and it got me wondering if there is any established standard for this kind of thing.
For clarification: I am wondering if there is an exact timing that is standard. Below is the code I am using with 150ms being the threshold for a hold.
function onMouseDown()
{
var holdTimeout = setTimeout(function()
{
//Hold code (also cancels click event)
}, 150);
var cancelHold = function()
{
clearTimeout(holdTimeout);
};
window.onmouseup = cancelHold;
}
function onClick()
{
//Click code
}
Answering exactly your question, hold becomes click. You could set the click event (it's release in fact), inside the mousedown event. Run the code below and try holding and release the mouse button.
document.getElementById("click").addEventListener('mousedown', (e) => {
var i = 0;
var int = setInterval(() => {
console.log("hold " + i++);//<-- actions when we hold the button
}, 200)
document.getElementById("click").addEventListener("click", () => {
clearInterval(int);
console.log("release")//<-- actions when we release the button
})
});
<div id="click">click</div>
In this case, if we hold the button less that 200 milliseconds, just the click (release) event is fired.

setTimeout function if user not active

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();

need to set a timer for in javascript , then clear

I want to create a timer in JavaScript. I see the setTimeout(fn, 100) but unclear how to wrap this so it will clear itself at the end.
I tried doing
var buttonTimer = null;
$scope.backButton = function() {
if(buttonTimer === null){
$history.back();
}
buttonTimer = setTimeout(function(buttonTimer){
buttonTimer = null;
}, 100);
}
The whole point is to prevent the user from hitting this function too quickly.. and ignoring all subsequent clicks within that 100ms window, at the end of the window, clear the timer and resume accepting clicks
Since you are doing angular, I prepared a plnkr for demonstration:
http://plnkr.co/edit/5qrslKpmkglXTvEyYgBr?p=preview
Your code is almost Ok, the only problem is that you start a new timeout on every click. The effect is, that the callback fires multiple times and resets buttonTimer.
So the only change is:
var blocker = null;
$scope.backButton = function() {
if(blocker == null) {
blocker = setTimeout(function(){
blocker = null;
}, 1500);
// DO YOUR STUFF HERE
}
};
You can use throttle from lodash/underscore or Ramdajs.
for example
$scope.backButton=_.throttle(100,function(){/* do something here */});

Close popup after x minutes unless there was activity

I have a link that when clicked, opens a new window using:
var win = window.open(url,....);
This window contains a flash game.
I want to close the window after 20 minutes of inactivity.
I know I can create a timeout using:
var t = setTimeout("dosomething()", 5000)
But how can I figure out if there was activity or not on the popup?
If the user interacts with the flash, can I get this information still via the dom events?
I want to avoid the situation of closing the window while they are playing :)
This is in a IE based environment.
theInterval = 0;
function doSomething(){
do something;
}
function ScheduleDoSomething(){
theInterval = setInterval(function () {
doSomething();}, timeToClose);
}
jQuery(document).keydown(function (e) {
clearInterval(theInterval);scheduleDoSomething();
});
I hope this helps.
How about adding a listening event for the mousemove, keypress, and click events and clearing the timer every time the events happen.
var t = setTimeout(closeWindow, 5000);
$(document).on('mousemove keypress click', function(){
clearTimeout(t);
t = setTimeout(closeWindow, 5000);
});
function closeWindow(){
window.close();
}

Jquery ajax live validation / timeout question

I'm still kindof new to jQuery, so there probably is an easy solution, but I can't find anything.
I've made this registration form, that checks if the username or email is taken as the user is typing in the username. Basically it just makes a json request that returns true or false depending on if the username / email is already taken.
The problem is, that now it makes a request on basically every keypress that the user makes while focused on the field if the input text is more than 3 characters long. For now, that works, but that's a lot of server requests. I'd like it to make a request only when the user has not typed for, say, a half second.
Any ideas on how I might be able to do that ?
$(document).ready(function() {
$("#user_username").keyup(function () {
var ln = $(this).val().length;
if (ln > 3) {
$.getJSON("/validate/username/",
{value:$(this).val()},
function(data){
if (data.reg == true) {
$("#status-for-username").html("Username already in use");
} else {
$("#status-for-username").html("Username available");
}
});
}
});
$("#user_email").keyup(function () {
var ln = $(this).val().length;
if (ln > 3) {
$.getJSON("/validate/email/",
{value:$(this).val()},
function(data){
if (data.reg == true) {
$("#status-for-email").html("E-mail already in use");
} else {
$("#status-for-email").html("");
}
});
}
});
});
For waiting an amount of time since the last keystroke, you could do something like the jQuery.typeWatch plugin does.
Here I post you a light implementation of the concept:
Usage:
$("#user_username").keyup(function () {
typewatch(function () {
// executed only 500 ms after the last keyup event.
}, 500);
Implementation:
var typewatch = function(){
var timer = 0; // store the timer id
return function(callback, ms){
clearTimeout (timer); // if the function is called before the timeout
timer = setTimeout(callback, ms); // clear the timer and start it over
}
}();
StackOverflow uses the plugin I mention, for syntax coloring the code on edition.
You can use window.setTimeout and window.clearTimeout. Basically trigger a function to invoke in x milliseconds and if another keypress event is fired beforehand then you clear that handler and start a new one.
//timeout var
var timer;
$('#username').keyUp( function(){
//clear any existing timer
window.clearTimeout( timer );
//invoke check password function in 0.5 seconds
timer = window.setTimeout( checkPasswordFunc, 500 );
});
function checkPasswordFunc(){
//ajax call goes here
}

Categories