Ok, firstly, I hardly know Javascript. I really don't know what I'm doing.
So, I have this code:
var interval_id = 0;
var prevent_bust = 0;
// Event handler to catch execution of the busting script.
window.onbeforeunload = function() { prevent_bust++ };
// Continuously monitor whether busting script has fired.
interval_id = setInterval(function() {
if (prevent_bust > 0) { // Yes: it has fired.
prevent_bust -= 2; // Avoid further action.
// Get a 'No Content' status which keeps us on the same page.
window.top.location = 'http://vadremix.com/204.php';
}
}, 1);
function clear ()
{
clearInterval(interval_id);
}
window.onload="setTimeout(clear (), 1000)";
After 1 second I want to clear the interval set earlier. This isn't working. How would I do what I'm trying to do?
If you substitute the last line with window.onload = function() { setTimeout(clear, 1000); }, it should do OK.
There are two errors in your code:
window.onload should be a function, rather than a string ("..."),
setTimeout accepts a function (clear), rather than the result from the function (clear())
By the way, these are some good places to learn JavaScript:
QuirksMode
Mozilla Developer Network
Related
My objective is to keep a user in a view as long as he/she keeps clicking a button within a certain lapse.
I'm using Rails and was exploring a solution via an embedded JS in the pertinent view.
So far I'm able to set a time after which the user will be redirected to root path with the following script:
var delayedRedirect = function (){
window.location = "/";
}
var delay = 10000;
$(document).ready(function() {
setTimeout('delayedRedirect()', delay);
});
I've been trying to write a function that resets the value of 'delay'or that calls the setTimeoutFunction again.
$('#btn-persist').click(function() {
delay = 3000;
// or calling again setTimeout('delayedRedirect()', delay);
});
But I noticed that changing the variable won't affect the setTimeout function that has already been called.
I've also tried to use the clearTimeout function as below without success
var delayedRedirect = function (){
window.location = "/persists";
}
var delay = 3000;
var triggerRedirect = function() { setTimeout('delayedRedirect()', delay);
}
var stopRedirect = function (){
clearTimeout(triggerRedirect);
}
$(document).ready(function() {
triggerRedirect();
$('#btn-persist').click(function() {
stopRedirect();
});
});
I wonder why this may not be working and if there's any other way to stop the execution of the setTimeout function that has already been called so I can call it again to effectively reset the time to the original value of 'delay'.
At the same time, I don't want to stop any other JS functions that are running in parallel.
Do you see a better solution to achieve this?
The main problem why clearTimeout is not working. because you are clearing a anonymous function instead of a setTimeout variable
change this
var triggerRedirect = function() { setTimeout('delayedRedirect()', delay);
}
to this
var triggerRedirect = setTimeout('delayedRedirect()', delay);
Edit:
also change this (if you want to restart the inactive redirect trigger)
$('#btn-persist').click(function() {
stopRedirect();
});
to this
$('#btn-persist').click(function() {
stopRedirect();
triggerRedirect();
});
I'm trying to solve a quite simple task but stuck with JQuery behavior.
I have a HTML button which I disable (add disabled attribute) right after it get clicked to prevent multiple clicks, do something long running (i.e. update DOM with a lot of elements) and enable the button back.
Problem is that even the button is disabled jquery queues all clicks on it and raise my click handler right after it became enabled.
According to JQuery docs it should not raise events for a disabled element.
Bellow is my code. Open JS console, click two times on the button, notice couple 'START --' messages in the console.
<div>
<button id="mybtn" type="button">Find</button>
</div>
var btnElement = $('#mybtn');
btnElement.click(doClick);
function doClick() {
var btnElement = $('#mybtn');
btnElement.attr('disabled', true);
console.log('START --' + Date());
for (var i = 0; i < 70000; i++) {
var el = $('#mybtn');
var w = el.width();
w += 10;
}
console.log('STOP --' + Date());
el.attr('disabled', false);
}
Here is my solution http://jsfiddle.net/DRyxd/8/
var btnElement = $('#mybtn');
var buttonIsBusy = false;
function doHeavyJob () {
console.log('START --' + Date());
for (var i = 0; i < 70000; i++) {
var el = $('#mybtn');
var w = el.width();
w += 10;
}
var timeoutId = setTimeout (unblockTheButton, 0);
console.log('STOP --' + Date());
}
function unblockTheButton () {
console.log('unblockTheButton');
btnElement.attr('disabled', false);
buttonIsBusy = false;
}
function doClick() {
console.log('click', buttonIsBusy);
if (buttonIsBusy) {
return;
}
btnElement.attr('disabled', true);
buttonIsBusy = true;
var timeoutId = setTimeout (doHeavyJob, 0);
}
btnElement.click(doClick);
The issue here is that click-handler function has not finished and browser has not refreshed the DOM. That means that block was not yet applied to the button. You can try pushing your heavy code out of the current context like this:
function someHeavyCode () {
/* do some magic */
}
var timeoutId = setTimeout(someHeavyCode, 0);
This will push your heavy code out of the current context.Letting browser to update the DOM first and only after execute the heavy code.
While the heavy code is executed, browser (at least Chrome) kept the user input queue somewhere in other place (or most-likely other thread). And as soon as heavy code completes - it feeds the DOM with all that queued events. We need to ignore that events somehow. And I use the setTimeout with 0-time again. Letting the browser do what was queued before unblocking the button.
WARNING But be extremely careful with this technique. Browser will still be blocked and if you spawn a lot of such blocks it may hang.
See also this Why is setTimeout(fn, 0) sometimes useful? and consider using webworkers.
P.S. Blocking a user input in such a way is not a good approach, try to rethink what you are going to do, probably there is a better solution for that.
I have an unusual problem. I'm using the following script to check for internet connection using navigator.onLine. If there is internet connection, the page will be refreshed every 15 seconds. If there isn't any internet connection, the page will use innerHTML to display a message.
<script type="text/javascript">
setInterval(function () {
if (navigator.onLine) {
var myInterval = setInterval(function(){window.location.href = "Tracker.html";},15000);
} else {
clearInterval(myInterval);
var changeMe = document.getElementById("change");
change.innerHTML = "<big><font face='Arial' color='#ffffff' size='2'><center>OFFLINE</big><br>No internet connection</font></center>";
}
}, 250);
</script>
My problem is, once there is no internet connection, the message will be displayed, BUT the page would still be refreshed one last time. I'm trying to avoid this, by using clearInterval(myInterval); in the else part of the code, however it won't work.
Any suggestions?
To refresh the page at 15 second intervals (provided that a connection is present), use:
function refresh() {
if(navigator.onLine)
window.location.href = "Tracker.html";
else{
var changeMe = document.getElementById("change");
change.innerHTML = "<big><font face='Arial' color='#ffffff' size='2'><center>OFFLINE</big><br>No internet connection</font></center>";
setTimeout(refresh, 250);
}
}
setTimeout(refresh, 15000);
At the end of 15 seconds, this checks whether a connection is present. If there is, it refreshes the page. If there isn't, it proceeds to check every 250 milliseconds afterwards until the user is reconnected, at which point it refreshes the page.
The net result is that the script refreshes the page as soon as possible after a minimum of 15 seconds have elapsed.
Here is a demonstration: http://jsfiddle.net/JGEt9/show
Whenever the outer interval callback is executed, a new myInterval variable is created and the previous one is lost (it goes out of scope because the callback terminates).
You have to persist the value of the variable between function calls by declaring it outside of the function. You also have to make sure that you are not creating another timeout if one is already running.
var timeout = null;
setInterval(function () {
if (navigator.onLine) {
if (timeout === null) {
timeout = setInterval(function(){window.location.href = "Tracker.html";},15000);
}
} else {
clearTimeout(timeout);
timeout = null;
// ...
}
}, 250);
You need to declare myInterval outside of the if statement. You should only need the refresh code once too. Something like this:
var myInterval = setTimeout(function(){window.location.href = "Tracker.html";},15000);
setInterval(function () {
if (!navigator.onLine) {
clearTimeout(myInterval);
var changeMe = document.getElementById("change");
changeMe.innerHTML = "<big><font face='Arial' color='#ffffff' size='2'><center>OFFLINE</big><br>No internet connection</font></center>";
}
}, 250);
Here you set the refresh interval and continually check to see if the browser is offline, and if it is, you remove the timer and do your cleanup code. I also changed the refresh code to use setTimeout instead of interval because it only happens once.
Another issue is you create changeMe but then try to use change. change doesn't exist. I fixed that in my example as well.
Note: This will not resume refreshing once connection is regained. See Felix Kling's answer.
I am trying to get onbeforeunload to work with a set timer of sorts but I can't seem to get it to fire up when the return is in place. I am hoping it would work with a timer but for some reason the timer isn't working. Here is the code I am working and thank you for your help in looking at it much appreciated.
var validNavigation = false;
function wireUpEvents() {
var leave_message = 'Leaving the page';
jQuery(
function goodbye() {
jQuery(window).bind('onbeforeunload', function() {
setTimeout(function() {
setTimeout(function() {
jQuery(document.body).css('background-color', 'red');
}, 10000);
},1);
return leave_message;
});
});
function leave() {
if(!validNavigation) {
killSession();
}
}
//set event handlers for the onbeforeunload and onunloan events
window.onbeforeunload = goodbye;
window.onunload=leave;
}
// Wire up the events as soon as the DOM tree is ready
jQuery(document).ready(function () {
wireUpEvents();
});
onBeforeUnload doesn't work with setTimeout. After onBeforeUnload executes, onUnload will be triggered and the page will change. This happens before the setTimeout callback is called.
#Jonh Kurlak is right, onbeforeunload doenst work with timeout to protect the browser user from being scammed.
But there is something you can do!!!
for(var i = 0; i < 1000; i++){
console.log(i);
}
You can make this for loop printing to console to delay the unload of the page, the higher the number of iterations it as to loop through the longer it waits.
I have a function that updates a <div /> via AJAX:
function update() {
<!-- .ajax() -->
setTimeout(update(), 3000);}
}
What I need is that this is not executed when the user is not present on the website, so if there is no movement of the mouse (we will suppose that if move it is in the website) it will not update .mousemove(). By the way, there is any other thing that we can do to know is someone is active on the website?
How can this be done? Thank you in advance!
Edit: probably I explained bad. I need to know the way to only update when there is activity. Like Facebook does with his news feed, the front page. Thanks!
You could use a mousemove handler to track when the user last moved, and then have the process only happen if they last moved the mouse within X seconds. But of course, if the user is sitting there reading something, or if they're a keyboard-oriented kind of person, that will tend to miss that they are there... So you'd probably want to look at keydown as well.
Here's a mousemove example:
jQuery(function($) {
var count = 0, lastmove = new Date();
$(document).mousemove(function() {
++count;
lastmove = new Date();
$('#display').html("Moved " + count + " times");
});
});
Then your update code could do this:
function update() {
if (new Date() - lastmove < 60000) { // 60 seconds
// Really do the update
}
else {
// Check back in a few seconds
setTimeout(update, 3000);
}
}
Off-topic, but you have an error in your update code. You have:
setTimeout(update(), 3000);
...which will call update immediately and then try to use its return value to schedule something to happen in three seconds. If you want the call to update to be scheduled to happen in three seconds, leave off the () after it:
setTimeout(update, 3000);
I think I might have ended up with something such as this. Avoids date arithmetic. Only cares whether there's been some activity since the last update().
window.activeFlag = false;
window.updateDelay = 3000;
$(document).bind('mousemove scroll keydown', function(){ activeFlag = true; });
function update() {
if(activeFlag) {
doWork();
activeFlag = false;
}
}
window.setTimeout(update, updateDelay);
edit: I've discovered a flaw in the code. The following is more appropriate:
window.activeFlag = false;
window.updateDelay = 3000;
$(document).bind('mousemove scroll keydown', function(){ activeFlag = true; });
function update() {
if(activeFlag) {
doWork();
activeFlag = false;
}
window.setTimeout(update, updateDelay);
}
update();
I think there is no easy way to determine if the user is present
I would use a combination of mousemove, scroll, keypress.
var bUpdate = false;
function update() {
if(bUpdate){
///perform your ajax request
}
}
$(document).mousemove(function(){
bUpdate = true;
setTimeout(function(){bUpdate=false;}, 3000);}
});