Stop the running script - javascript

I run a script in the browser that scrolls the page down. I run it from the browser console (ctrl + shift + j).
var popWys = 0;
var terazWys = 0;
var proba = 0;
function scrollowanie() {
if(popWys == document.body.scrollHeight)
{
proba++;
if(proba > 10)
{
window.alert("To juz chyba wszystko, w razie czego odpal ponownie.");
return;
}
}
else
{
proba = 0;
}
popWys = document.body.scrollTop;
terazWys += 1000;
window.scrollTo(0,terazWys);
setTimeout(scrollowanie, 100);
}
setTimeout(scrollowanie, 100);
Question. How to stop it at any time from the command line? Can I write something, press to stop? Sam will never stop and blocks the browser. I tried with different: return; break; Stop. anything and nothing works.
Can it be done at all?

You can use clearTimeout([variable name]) to stop the setTimeout(scrollowanie, 100);
Just assign setTimeout(scrollowanie, 100); to global variable like following:
globalVar = setTimeout(scrollowanie, 100);
And in the console type clearTimeout(globalVar) and the execution will finish

You could wrap desired behaviour in an object that handles the process.
e.g.:
var script = (function () {
var timeout;
var DESIRED_TIME = 100;
function scrollowanie() {
console.log('::Testing');
// Desired behaviour here
clearTimeout(timeout);
timeout = setTimeout(scrollowanie, DESIRED_TIME)
}
return {
start: function() {
timeout = setTimeout(scrollowanie, DESIRED_TIME);
},
stop: function () {
clearTimeout(timeout);
}
}
})();
Then in the command line you will just need to start the process
script.start();
and to end it
script.stop();

Related

update a delayed function in javascript

I have a simple javascript function that loads on document ready:
var start = 1;
var speed = 1000;
$(document).ready(function () {
go();
setInterval(function () {
go();
}, speed);
This is the function in details:
function go() {
$("#score").html(start.toLocaleString());
start += 1;
}
This is basically a counter which starts from number 1 to infinite, at 1000 milliseconds speed. Here is the thing , now: I have another function:
function modify() {
speed = 500;
}
which regulates the setIntval speed on the main function. The problem is it applies on page refresh only. How do I update it in real time without refreshing page?
You can't update the current one, you have to stop it and set a new timer, which does the same but with a different delay.
var speed = 1000;
var start = 1;
function go() {
$("#score").html(start.toLocaleString());
start += 1;
}
function startGoTimer(){
return = setInterval(function () {
go();
}, speed);
}
function modifyTimer( previousTimer, newDelay=500) {
clearInterval(previousTimer);
speed = newDelay;
startGoTimer();
}
var timer = startGoTimer();
// Some code
modifyTimer(timer, 500);
For fun I just tested what would hapopen if you just change the time:
var timing = 1000;
var interval = setInterval(function(){console.log("test")}, timing);
// Now we get a log every 1000ms, change the var after some time (via console):
timing = 10;
// still an interval of 1000ms.
A really simple solution is to make use of the setInterval's parameters,
var intervalID = scope.setInterval(func, delay[, param1, param2, ...]);
and also pass the speed as param1.
Then, at each interval, check if it changed, and if, clear the existing timer and fire up a new.
Stack snippet
var start = 1;
var speed = 1000;
var timer;
$(document).ready(function() {
go();
timer = setInterval(function(p) {
go(p);
}, speed, speed);
// for this demo
$("button").click(function(){ speed = speed/2});
})
function go(p) {
if(p && p != speed) {
clearInterval(timer);
timer = setInterval(function(p) {
go(p);
}, speed, speed);
}
$("#score").html(start.toLocaleString());
start += 1;
}
div {
display: inline-block;
width: 40px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="score">0</div>
<button>Modify</button>

Sequencing consecutive functions and adjust for-loop in javascript/jquery

Background: the code below picks either a word or an image and displays it in my 'abc' div. It measures the reaction time.
Aim: I want to have the function run only 8 times (not 8 keypresses), record the time for each run regardless the keypress event (i.e. a time of 2000 when no key is pressed), and I want this function run first, and after it has finished I want to run a second function.
I researched the $deferred method and seem to have failed to adopt it. Furthermore, my 8 function runs, are not eight at all, but seem more like 8 simultaneous runs.
So basically I want to run my function 8 times, then run a next function, and record the time from appearance of a stimulus to the next if not interrupted by keypress.
I'm stuck with it for some time now and have probably lost the overview.
var reac_arr = [];
var t1;
function firstFunction(){
var def = $.Deferred();
for (var i = 1; i <= 8; i++) {
$(function cit(){
var timeout = 0;
function showNext(){
t1 = (new Date()).getTime();
if (Math.random() < 0.5) {
var new_word = stim.name;
$("#abc").text(new_word);
}
else {
var new_img = stim.path;
$("#abc").empty();
var prox_img = $('<img id="abcimg">');
prox_img.attr('src', new_img);
prox_img.appendTo('#abc');
}
timeout = setTimeout(function(){
showNext()
}, 2000);
}
$(document).keypress(function(e){
if ($(e.target).is('input, textarea')) {
return;
};
clearTimeout(timeout);
if (e.which === 97 || e.which === 108 || e.which === 32) {
setTimeout(function(){
showNext();
}, 300);
var t2 = (new Date()).getTime();
var reac_time = t2 - t1;
reac_arr.push(reac_time);
}
});
});
};
setTimeout(function() {
def.resolve();
}, 1000);
return def.promise();
}
function secondFunction(){
var def = $.Deferred();
alert("It works!")
};
setTimeout(function() {
def.resolve();
}, 1000);
return def.promise();
}
firstFunction().pipe(secondFunction);
Your code seems a bit bloated but if I understood correctly all you need is setInterval().
var counter = 0;
var ticker = setInterval(myFunction,2000);//Setup a function to run every 2000ms
function myFunction()
{
//do your thing
counter++;//
if(counter==8){
//on the 8th time run next function...
}
}
$(document).keypress(function(e){
clearInterval(ticker);//Stop the ticker on keypress
});

setTimeOut + window.onblur+ window.onfocus

I´m trying to use setTimeout to recall a function. When window is not on focus so we will set that function to take a pause until window is on focus again. Let see my script
(function() {
var time = 10000,
delta = 100,
tid;
tid = setInterval(function() {
if ( window.blurred ) { return; }
time -= delta;
if ( time <= 0 ) {
clearInterval(tid);
dosomething (user_id); // function to do something
}
}, delta);
})();
window.onblur = function() { window.blurred = true; };
window.onfocus = function() { window.blurred = false; };
Actually it work as I expected BUT
My question is :
I'm trying to change the method to-----> setTimeout and clearTimeout Why it doesn't work ?
After many test I found that this function doesn't work in IE, do we have any solution ?

How to know browser idle time?

How can I track the browser idle time? I am using IE8.
I am not using any session management and don't want to handle it on server side.
Here is pure JavaScript way to track the idle time and when it reach certain limit do some action:
var IDLE_TIMEOUT = 60; //seconds
var _idleSecondsTimer = null;
var _idleSecondsCounter = 0;
document.onclick = function() {
_idleSecondsCounter = 0;
};
document.onmousemove = function() {
_idleSecondsCounter = 0;
};
document.onkeypress = function() {
_idleSecondsCounter = 0;
};
_idleSecondsTimer = window.setInterval(CheckIdleTime, 1000);
function CheckIdleTime() {
_idleSecondsCounter++;
var oPanel = document.getElementById("SecondsUntilExpire");
if (oPanel)
oPanel.innerHTML = (IDLE_TIMEOUT - _idleSecondsCounter) + "";
if (_idleSecondsCounter >= IDLE_TIMEOUT) {
window.clearInterval(_idleSecondsTimer);
alert("Time expired!");
document.location.href = "logout.html";
}
}
#SecondsUntilExpire { background-color: yellow; }
You will be auto logged out in <span id="SecondsUntilExpire"></span> seconds.
​This code will wait 60 seconds before showing alert and redirecting, and any action will "reset" the count - mouse click, mouse move or key press.
It should be as cross browser as possible, and straight forward. It also support showing the remaining time, if you add element to your page with ID of SecondsUntilExpire.
The above code should work fine, however has several downsides, e.g. it does not allow any other events to run and does not support multiply tabs. Refactored code that include both of these is following: (no need to change HTML)
var IDLE_TIMEOUT = 60; //seconds
var _localStorageKey = 'global_countdown_last_reset_timestamp';
var _idleSecondsTimer = null;
var _lastResetTimeStamp = (new Date()).getTime();
var _localStorage = null;
AttachEvent(document, 'click', ResetTime);
AttachEvent(document, 'mousemove', ResetTime);
AttachEvent(document, 'keypress', ResetTime);
AttachEvent(window, 'load', ResetTime);
try {
_localStorage = window.localStorage;
}
catch (ex) {
}
_idleSecondsTimer = window.setInterval(CheckIdleTime, 1000);
function GetLastResetTimeStamp() {
var lastResetTimeStamp = 0;
if (_localStorage) {
lastResetTimeStamp = parseInt(_localStorage[_localStorageKey], 10);
if (isNaN(lastResetTimeStamp) || lastResetTimeStamp < 0)
lastResetTimeStamp = (new Date()).getTime();
} else {
lastResetTimeStamp = _lastResetTimeStamp;
}
return lastResetTimeStamp;
}
function SetLastResetTimeStamp(timeStamp) {
if (_localStorage) {
_localStorage[_localStorageKey] = timeStamp;
} else {
_lastResetTimeStamp = timeStamp;
}
}
function ResetTime() {
SetLastResetTimeStamp((new Date()).getTime());
}
function AttachEvent(element, eventName, eventHandler) {
if (element.addEventListener) {
element.addEventListener(eventName, eventHandler, false);
return true;
} else if (element.attachEvent) {
element.attachEvent('on' + eventName, eventHandler);
return true;
} else {
//nothing to do, browser too old or non standard anyway
return false;
}
}
function WriteProgress(msg) {
var oPanel = document.getElementById("SecondsUntilExpire");
if (oPanel)
oPanel.innerHTML = msg;
else if (console)
console.log(msg);
}
function CheckIdleTime() {
var currentTimeStamp = (new Date()).getTime();
var lastResetTimeStamp = GetLastResetTimeStamp();
var secondsDiff = Math.floor((currentTimeStamp - lastResetTimeStamp) / 1000);
if (secondsDiff <= 0) {
ResetTime();
secondsDiff = 0;
}
WriteProgress((IDLE_TIMEOUT - secondsDiff) + "");
if (secondsDiff >= IDLE_TIMEOUT) {
window.clearInterval(_idleSecondsTimer);
ResetTime();
alert("Time expired!");
document.location.href = "logout.html";
}
}
The refactored code above is using local storage to keep track of when the counter was last reset, and also reset it on each new tab that is opened which contains the code, then the counter will be the same for all tabs, and resetting in one will result in reset of all tabs. Since Stack Snippets do not allow local storage, it's pointless to host it there so I've made a fiddle:
http://jsfiddle.net/yahavbr/gpvqa0fj/3/
Hope this is what you are looking for
jquery-idletimer-plugin
Too late to reply, but this might help someone to write clean and practical solution. This is an ideal solution, when you do not need to display time left for session expire. Good to ignore setInterval(), which keeps on running the script through out the application running time.
var inactivityTimeOut = 10 * 1000, //10 seconds
inactivitySessionExpireTimeOut = '';
setSessionExpireTimeOut();
function setSessionExpireTimeOut () {
'use strict';
clearSessionExpireTimeout();
inactivitySessionExpireTimeOut = setTimeout(function() {
expireSessionIdleTime();
}, inactivityTimeOut);
}
function expireSessionIdleTime () {
'use strict';
console.log('user inactive for ' + inactivityTimeOut + " seconds");
console.log('session expired');
alert('time expired');
clearSessionExpireTimeout();
document.location.href = "logout.html";
}
function clearSessionExpireTimeout () {
'use strict';
clearTimeout(inactivitySessionExpireTimeOut);
}
Running example: Timeout alert will be popped up in 10 seconds
Here's an approach using jquery as I needed to preserve existing keyboard events on the document.
I also needed to do different things at different idle times so I wrapped it in a function
var onIdle = function (timeOutSeconds,func){
//Idle detection
var idleTimeout;
var activity=function() {
clearTimeout(idleTimeout);
console.log('to cleared');
idleTimeout = setTimeout(func, timeOutSeconds * 1000);
}
$(document).on('mousedown mousemove keypress',activity);
activity();
}
onIdle(60*60,function(){
location.reload();
});
onIdle(30,function(){
if(currentView!=='welcome'){
loadView('welcome');
}
});
I needed a similar thing and created this :https://github.com/harunurhan/idlejs
It simple, configurable and powerful in a way, without any dependencies. Here's an example.
import { Idle } from 'idlejs/dist';
// with predefined events on `document`
const idle = new Idle()
.whenNotInteractive()
.within(60)
.do(() => console.log('IDLE'))
.start();
You can also use custom event targets and events
const idle = new Idle()
.whenNot([{
events: ['click', 'hover'],
target: buttonEl,
},
{
events: ['click', 'input'],
target: inputEl,
},
])
.within(10)
.do(() => called = true)
.start();
(Written in typescript and compiled to es5)

How to stop a setTimeout loop?

I'm trying to build a loading indicator with a image sprite and I came up with this function
function setBgPosition() {
var c = 0;
var numbers = [0, -120, -240, -360, -480, -600, -720];
function run() {
Ext.get('common-spinner').setStyle('background-position', numbers[c++] + 'px 0px');
if (c<numbers.length)
{
setTimeout(run, 200);
}else
{
setBgPosition();
}
}
setTimeout(run, 200);
}
so the out put is looks like this
http://jsfiddle.net/TTkre/
I had to use setBgPosition(); inside else to keep this running in a loop so now my problem is how to stop this loop once I want [load finished]?
setTimeout returns a timer handle, which you can use to stop the timeout with clearTimeout.
So for instance:
function setBgPosition() {
var c = 0,
timer = 0;
var numbers = [0, -120, -240, -360, -480, -600, -720];
function run() {
Ext.get('common-spinner').setStyle('background-position', numbers[c++] + 'px 0px');
if (c >= numbers.length) {
c = 0;
}
timer = setTimeout(run, 200);
}
timer = setTimeout(run, 200);
return stop;
function stop() {
if (timer) {
clearTimeout(timer);
timer = 0;
}
}
So you'd use that as:
var stop = setBgPosition();
// ...later, when you're ready to stop...
stop();
Note that rather than having setBgPosition call itself again, I've just had it set c back to 0. Otherwise, this wouldn't work. Also note that I've used 0 as a handle value for when the timeout isn't pending; 0 isn't a valid return value from setTimeout so it makes a handy flag.
This is also one of the (few) places I think you'd be better off with setInterval rather than setTimeout. setInterval repeats. So:
function setBgPosition() {
var c = 0;
var numbers = [0, -120, -240, -360, -480, -600, -720];
function run() {
Ext.get('common-spinner').setStyle('background-position', numbers[c++] + 'px 0px');
if (c >= numbers.length) {
c = 0;
}
}
return setInterval(run, 200);
}
Used like this:
var timer = setBgPosition();
// ...later, when you're ready to stop...
clearInterval(timer);
All of the above notwithstanding, I'd want to find a way to make setBgPosition stop things itself, by detecting that some completion condition has been satisfied.
I know this is an old question, I'd like to post my approach anyway. This way you don't have to handle the 0 trick that T. J. Crowder expained.
var keepGoing = true;
function myLoop() {
// ... Do something ...
if(keepGoing) {
setTimeout(myLoop, 1000);
}
}
function startLoop() {
keepGoing = true;
myLoop();
}
function stopLoop() {
keepGoing = false;
}
SIMPLIEST WAY TO HANDLE TIMEOUT LOOP
function myFunc (terminator = false) {
if(terminator) {
clearTimeout(timeOutVar);
} else {
// do something
timeOutVar = setTimeout(function(){myFunc();}, 1000);
}
}
myFunc(true); // -> start loop
myFunc(false); // -> end loop
You need to use a variable to track "doneness" and then test it on every iteration of the loop. If done == true then return.
var done = false;
function setBgPosition() {
if ( done ) return;
var c = 0;
var numbers = [0, -120, -240, -360, -480, -600, -720];
function run() {
if ( done ) return;
Ext.get('common-spinner').setStyle('background-position', numbers[c++] + 'px 0px');
if (c<numbers.length)
{
setTimeout(run, 200);
}else
{
setBgPosition();
}
}
setTimeout(run, 200);
}
setBgPosition(); // start the loop
setTimeout( function(){ done = true; }, 5000 ); // external event to stop loop
var myVar = null;
if(myVar)
clearTimeout(myVar);
myVar = setTimeout(function(){ alert("Hello"); }, 3000);
Try something like this in case you want to stop the loop from inside the function:
let timer = setInterval(function(){
// Have some code to do something
if(/*someStopCondition*/){
clearInterval(timer)
}
},1000);
You can also wrap this inside a another function, just make sure you have a timer variable and use clearInterval(theTimerVariable) to stop the loop
As this is tagged with the extjs tag it may be worth looking at the extjs method: http://docs.sencha.com/extjs/6.2.0/classic/Ext.Function.html#method-interval
This works much like setInterval, but also takes care of the scope, and allows arguments to be passed too:
function setBgPosition() {
var c = 0;
var numbers = [0, -120, -240, -360, -480, -600, -720];
function run() {
Ext.get('common-spinner').setStyle('background-position', numbers[c++] + 'px 0px');
if (c<numbers.length){
c=0;
}
}
return Ext.Function.interval(run,200);
}
var bgPositionTimer = setBgPosition();
when you want to stop you can use clearInterval to stop it
clearInterval(bgPositionTimer);
An example use case would be:
Ext.Ajax.request({
url: 'example.json',
success: function(response, opts) {
clearInterval(bgPositionTimer);
},
failure: function(response, opts) {
console.log('server-side failure with status code ' + response.status);
clearInterval(bgPositionTimer);
}
});
I am not sure, but might be what you want:
var c = 0;
function setBgPosition()
{
var numbers = [0, -120, -240, -360, -480, -600, -720];
function run()
{
Ext.get('common-spinner').setStyle('background-position', numbers[c++] + 'px 0px');
if (c<=numbers.length)
{
setTimeout(run, 200);
}
else
{
Ext.get('common-spinner').setStyle('background-position', numbers[0] + 'px 0px');
}
}
setTimeout(run, 200);
}
setBgPosition();
In the top answer, I think the if (timer) statement has been mistakenly placed within the stop() function call. It should instead be placed within the run() function call like if (timer) timer = setTimeout(run, 200). This prevents future setTimeout statements from being run right after stop() is called.
EDIT 2: The top answer is CORRECT for synchronous function calls. If you want to make async function calls, then use mine instead.
Given below is an example with what I think is the correct way (feel to correct me if I am wrong since I haven't yet tested this):
const runSetTimeoutsAtIntervals = () => {
const timeout = 1000 // setTimeout interval
let runFutureSetTimeouts // Flag that is set based on which cycle continues or ends
const runTimeout = async() => {
await asyncCall() // Now even if stopRunSetTimeoutsAtIntervals() is called while this is running, the cycle will stop
if (runFutureSetTimeouts) runFutureSetTimeouts = setTimeout(runTimeout, timeout)
}
const stopRunSetTimeoutsAtIntervals = () => {
clearTimeout(runFutureSetTimeouts)
runFutureSetTimeouts = false
}
runFutureSetTimeouts = setTimeout(runTimeout, timeout) // Set flag to true and start the cycle
return stopRunSetTimeoutsAtIntervals
}
// You would use the above function like follows.
const stopRunSetTimeoutsAtIntervals = runSetTimeoutsAtIntervals() // Start cycle
stopRunSetTimeoutsAtIntervals() // Stop cycle
EDIT 1: This has been tested and works as expected.
When the task is completed and you can display the task (image in your case), on the next refresh don't send the javascript. If your server is using PHP.
<?php if (!$taskCompleted) { ?>
<script language="javascript">
setTimeout(function(){
window.location.reload(1);
}, 5000);
</script>
<?php } ?>

Categories