EDIT: the issue has been resolved. Apparently, the page didn't load fast enough for the id referenced to to be in place. Adding a event listener as follows solved the issue:
window.addEventListener('load', function() {stuff that's supposed to happen})
on my clueless journey to creating a little game I'm currently battling saving to and loading from the user's local storage. While saving appears to be working, loading doesn't, unless I manually put the respective commands into the console.
Here's the code snippet that's acting up:
//definition of variables
var dayLength = 10;
//if function to check if there's stored data, loading it and changing the document accordingly
if ( localStorage.saveExists === "true" ) {
dayLength = Number(localStorage.dayLength);
document.getElementById("displayDayLength").innerHTML = dayLength.toFixed(3);
}
var loadingAttempted = "true";
//function to save which occurs every 15 seconds (or through a button click)
function saveAuto() {
if ( loadingAttempted === "true" ) {
var saveExists = "false";
localStorage.saveExists = "true";
localStorage.dayLength = dayLength;
}
When no data are in the local storage (in other words, if saveExists = "false") the site won't attempt to load something and works as intended. The moment there is data in the local storage, the file attempts to load it (so thus far it works).
However, I'll get an error in the line supposed to change the document according to the loaded data, claiming that dayLength is "null".
If I then manually input localStorage.dayLength into the console, it returns "10", as it should. I know that storing the data into the local storage works, because otherwise the if function for loading wouldn't know (saveExists === "true") and thus not do anything. For whatever reason though, it fails to load any other data correctly and returns "null", unless I manually put the exact same code into the console.
Best part is, that I got the whole idea from another little game that does the exact same thing and there it works flawlessly.
I'm at a total loss as to why it works at the other project, but not with mine.
Educate me, if you will. And thank you in advance.
PS: I tried to use localStorage.setItem and localStorage.getItem also, but the issue remained.
I have a dashboard that presents some stats and until now it was quite static, i.e. if I wanted a fresh data I had to refresh the page. I have since moved to a more dynamic way with jquery to load stats on an interval. It works pretty good, I don't need to refresh the page anymore.
However, I noticed that if I leave the page open for some time the memory usage goes up and up with no signs of stopping.
It starts at about 50MB then in couple of hours (maybe only 1) saw it reach 1.2GB. Refreshing the page doesn't reclaim the memory!
And the obvious question... What am I doing wrong?
Samples:
#app.route("/getstats")
def getstats():
return jsonify({'data': render_template('stats.html', stats=stats())})
<script type="text/javascript">
$(function poll() {
var isMenuClosed = document.querySelector('.mdl-menu__container.is-visible') == null;
if (isMenuClosed) {
$.getJSON('/getstats',
function(data) {
$("tbody#stats").empty().append(data.data);
componentHandler.upgradeDom();
});
$.getJSON('/getwidgets',
function(wdata) {
$("div#widgets").empty().append(wdata.data);
});
}
setTimeout(poll,5000);
return false;
});
</script>
I have very limited knowledge on Python and especially JavaScript.
I have a website where each pages need to check if user close the browser, in this case I run some code (releaseLocking).
So on these pages I have implemented this code:
$(window).on('beforeunload', function () {
return "Are you sure you wanna quit ?";
});
$(window).unload(function () {
releaseLocking();
});
It works but I noticed that if I navigate to multiple pages where this code is implemented, when closing the browser, I'll have multiple call to releaseLocking (for each previously visited pages).
I would prefer only run this code for the last page really active. Do you see what I mean?
Do you have any idea how to proceed?
Thanks.
I suggest using localStorage for this. Since localStorage stores variables per domain, it will allow you to check if the code was already executed. Localstorage is also bound to the session, so after the browser is fully closed, your session is gone, causing the localStorage to be cleared so it wont interfere with the next session.
$(window).on('beforeunload', function () {
return "Are you sure you wanna quit ?";
});
$(window).unload(function () {
if ( !localStorage.getItem('lockReleased') ) {
releaseLocking();
localStorage.setItem('lockReleased', true)
}
});
The code above will set localStorage variable lockReleased to true for the first window that closes. The other windows will see the value, and won't call releaseLocking.
In my knowledge it is impossible to detect a browser close separately
from a browser navigation. the browser does not provide the
window with that information.
SEE HERE ALSO
I am not sure this is the only way to do it(neither the best), anyway you should be able to save a sort of session of the user and ask everytime to the server if the page is the last opened.
//the var declaration goes at the beginning of the script
var isLastPage = false;
$(window).on('beforeunload', function () {
//ajax request, the callback will set isLastPage to true if it is the last page opened by the user with that session.
});
$(window).unload(function () {
if(isLastPage) releaseLocking();
});
Server side you should create a session wich stores all the pages of the user(remember to update it via JS when the user closes a page or opens a new one). I think that only via JS is not possible to do it, you need to be helped by the server.
Is there any way to know how far browser loaded the page?
Either by using JavaScript or browser native functions.
Based on the page status i want to build progress bar.
I'm not 100% sure this will work, but.. here is the theory:
First of all, don't stop JavaScript running until the page has loaded. Meaning, don't use window.ready document.ready etc..
At the top of the page initialise a JavaScript variable called loaded or something and set it to 0.
var loaded = 0;
Throughout the page increment loaded at different points that you consider to be at the correct percentages.
For example, after you think half the page would have been loaded in the code set loaded = 50;.
Etc..
As I say, this is just a concept.
Code:
function request() {
showLoading(); //calls a function which displays the loading message
myRequest = GetXmlHttpObject();
url = 'path/to/script.php';
myRequest.open('GET',url,true);
myRequest.onreadystatechange = function() {
if(myRequest.readyState == 4 && myRequest.status == 200) {
clearLoading(); //calls a function which removes the loading message
//show the response by, e.g. populating a div
//with the response received from the server
}
}
myRequest.send(null);
}
At the beginning of the request I call showLoading() which uses Javascript to dynamically add the equivalent of your preLoaderDiv. Then, when the response is received, I call clearLoading() which dynamically removes the equivalent of your preLoaderDiv.
You'll have to determine it yourself, and to do that you'll have to have a way to determine it. One possibility is to have dummy elements along the page, know their total, and at each point count how many are already present. But that will only give you the amount of DOM obtained, and that can be a very small part of the load time - most often than not, the browser is idle waiting for scripts and images.
I am needing to detect when a user is inactive (not clicking or typing) on the current page for more than 30 minutes.
I thinking it might be best to use event blubbling attached to the body tag and then just keep resetting a timer for 30 minutes, but I'm not exactly sure how to create this.
I have jQuery available, although I'm not sure how much of this will actually use jQuery.
Edit: I'm more needing to know if they are actively using the site, therefore clicking (changing fields or position within a field or selecting checkboxes/radios) or typing (in an input, textarea, etc). If they are in another tab or using another program, then my assumption is they are not using the site and therefore should be logged out (for security reasons).
Edit #2: So everyone is clear, this is not at all for determining if the user is logged in, authenticated or anything. Right now the server will log the user out if they don't make a page request within 30 minutes. This functionality to prevent the times when someone spends >30 minutes filling in a form and then submitting the form only to find out that they haven't been logged out. Therefore, this will be used in combination with the server site to determine if the user is inactive (not clicking or typing). Basically, the deal is that after 25 minutes of idle, they will be presented with a dialog to enter their password. If they don't within 5 minutes, the system automatically logs them out as well as the server's session is logged out (next time a page is accessed, as with most sites).
The Javascript is only used as a warning to user. If JavaScript is disabled, then they won't get the warning and (along with most of the site not working) they will be logged out next time they request a new page.
This is what I've come up with. It seems to work in most browsers, but I want to be sure it will work everywhere, all the time:
var timeoutTime = 1800000;
var timeoutTimer = setTimeout(ShowTimeOutWarning, timeoutTime);
$(document).ready(function() {
$('body').bind('mousedown keydown', function(event) {
clearTimeout(timeoutTimer);
timeoutTimer = setTimeout(ShowTimeOutWarning, timeoutTime);
});
});
Anyone see any problems?
Ifvisible.js is a crossbrowser lightweight solution that does just that. It can detect when the user switches to another tab and back to the current tab. It can also detect when the user goes idle and becomes active again. It's pretty flexible.
You can watch mouse movement, but that's about the best you're going to get for indication of a user still being there without listening to the click event. But there is no way for javascript to tell if it is the active tab or if the browser is even open. (well, you could get the width and height of the browser and that'd tell you if it was minimized)
I just recently did something like this, albeit using Prototype instead of JQuery, but I imagine the implementation would be roughly the same as long as JQuery supports custom events.
In a nutshell, IdleMonitor is a class that observes mouse and keyboard events (adjust accordingly for your needs). Every 30 seconds it resets the timer and broadcasts an state:idle event, unless it gets a mouse/key event, in which case it broadcasts a state:active event.
var IdleMonitor = Class.create({
debug: false,
idleInterval: 30000, // idle interval, in milliseconds
active: null,
initialize: function() {
document.observe("mousemove", this.sendActiveSignal.bind(this));
document.observe("keypress", this.sendActiveSignal.bind(this));
this.timer = setTimeout(this.sendIdleSignal.bind(this), this.idleInterval);
},
// use this to override the default idleInterval
useInterval: function(ii) {
this.idleInterval = ii;
clearTimeout(this.timer);
this.timer = setTimeout(this.sendIdleSignal.bind(this), ii);
},
sendIdleSignal: function(args) {
// console.log("state:idle");
document.fire('state:idle');
this.active = false;
clearTimeout(this.timer);
},
sendActiveSignal: function() {
if(!this.active){
// console.log("state:active");
document.fire('state:active');
this.active = true;
this.timer = setTimeout(this.sendIdleSignal.bind(this), this.idleInterval);
}
}
});
Then I just created another class that has the following somewhere in it:
Event.observe(document, 'state:idle', your-on-idle-functionality);
Event.observe(document, 'state:active', your-on-active-functionality)
Ifvisible is a nice JS lib to check user inactivity.
ifvisible.setIdleDuration(120); // Page will become idle after 120 seconds
ifvisible.on("idle", function(){
// do something
});
Using jQuery, you can easily watch mouse movement, and use it to set a variable indicating activity to true, then using vanilla javascript, you can check this variable every 30 minutes (or any other interval) to see if its true. If it's false, run your function or whatever.
Look up setTimeout and setInterval for doing the timing. You'll also probably have to run a function every minute or so to reset the variable to false.
Here my shot:
var lastActivityDateTime = null;
function checkActivity( )
{
var currentTime = new Date();
var diff = (lastActivityDateTime.getTime( ) - currentTime.getTime( ));
if ( diff >= 30*60*1000)
{
//user wasn't active;
...
}
setTimeout( 30*60*1000-diff, checkActivity);
}
setTimeout( 30*60*1000, checkActivity); // for first time we setup for 30 min.
// for each event define handler and inside update global timer
$( "body").live( "event_you_want_to_track", handler);
function handler()
{
lastActivityDateTime = new Date();
// rest of your code if needed.
}
If it's a security issue, doing this clientside with javascript is absolutely the wrong end of the pipe to be performing this check. The user could easily have javascript disabled: what does your application do then? What if the user closes their browser before the timeout. do they ever get logged out?
Most serverside frameworks have some kind of session timeout setting for logins. Just use that and save yourself the engineering work.
You can't rely on the assumption that people cannot log in without javascript, therefore the user has javascript. Such an assumption is no deterrent to any determined, or even modestly educated attacker.
Using javascript for this is like a security guard handing customers the key to the bank vault. The only way it works is on faith.
Please believe me when I say that using javascript in this way (and requiring javascript for logins!!) is an incredibly thick skulled way to engineer any kind of web app.
Without using JS, a simpler (and safer) way would simply be to have a lastActivity timestamp stored with the user's session and checking it on page load. Assuming you are using PHP (you can easily redo this code for another platform):
if(($_SESSION['lastAct'] + 1800) < time()) {
unset($_SESSION);
session_destroy();
header('Location: session_timeout_message.php');
exit;
}
$_SESSION['lastAct'] = time();
and add this in your page (optional, the user will be logged out regardless of if the page is refreshed or not (as he logs out on next page log)).
<meta http-equiv="refresh" content="1801;" />
You can add and remove classes to the document depending on the user active status.
// If the window is focused, a mouse wheel or touchmove event is detected
$(window).on('focus wheel touchmove', function() {
$( 'html' ).addClass('active').removeClass('inactive');
});
// If the window losses focus
$(window).on('blur', function() {
$( 'html' ).addClass('inactive').removeClass('active');
});
After that, you can check every while if the html has the "active" class and send an AJAX request to check the session status and perform the action you need:
setInterval( function() {
if ( $( 'html' ).hasClass('active') ) {
//Send ajax request to check the session
$.ajax({
//your parameters here
});
}
}, 60000 ); /* loops every minute */
If your concern is the lost of information for the user after a login timeout; another option would be to simply store all the posted information upon the opening of a new session (a new session will always be started when the older session has been closed/scrapped by the server) when the request to a page is made before re-routing to the logging page. If the user successfully login, then you can use this saved information to return the user back to where he was. This way, even if the user walk away a few hours, he can always return back to where he was after a successful login; without losing any information.
This require more work by the programmer but it's a great feature totally appreciated by the users. They especially appreciate the fact that they can fully concentrate about what they have to do without stressing out about potentially losing their information every 30 minutes or so.