set variable different time interval in set interval - javascript

i have a function named checkInactivity i want to execute this function in variable time interval . i am fetching the time interval getInactiveTimePeriod and is tored in variable timeInMilliseconds. this varibale (timeInMilliseconds) holds different timings in each time its a value selected from database. i want to run the function checkInactivity with this variable time time interval ie depends on the value of timeInMilliseconds.
Please help me to solve this. Thank you in advance.
window.setInterval(function() {
setInactiveMode();
setInactiveTimePeriod();
getInactiveTimePeriod();
} , 100000);
var applicationsopend = [];
var applicationTabId = {};
var timeInseconds;
function getInactiveTimePeriod() {
chrome.storage.local.get("user_inactive_time", function (obj) {
timeInMinuts = obj.user_inactive_time;
timeInMilliseconds = timeInMinuts *(60000);
setTimeout(() => {
checkInactivity();
}, timeInMilliseconds);
});
}
// getInactiveTimePeriod();
function checkInactivity() {
chrome.storage.local.get("user_inactive_mode", function (obj) {
inactiveStatusMode = obj.user_inactive_mode;
if(inactiveStatusMode == 'true') {
var timeInseconds = timeInMilliseconds / 1000;
chrome.idle.queryState(timeInseconds, function (state) {
if (state === "active") {
chrome.storage.local.get( "appList", function (obj) {
appList = obj.appList.split(",");
var queryInfo = {
// active: false,
currentWindow: false
};
chrome.tabs.query(queryInfo, function (tabs) {
for (var i = 0; i < tabs.length; i++) {
var taburl = tabs[i]['url'];
currentApp = findApp(taburl);
currentHashUrl = CryptoJS.SHA1(currentApp).toString(CryptoJS.enc.Hex);
if($.inArray(currentHashUrl, appList) != -1 && currentApp != 'onionid' ) {
var tabid = tabs[i]['id'];
currentApp = findApp(taburl);
applicationTabId[currentApp] = tabid;
}
}
//console.log(applicationTabId);
getapplicationlogouturl(applicationTabId);
});
});
}
});
}
});
}

Once you've retrieved the time you want to use for interval, use setInterval() to call the function indefinately every given milliseconds:
function getInactiveTimePeriod() {
chrome.storage.local.get("user_inactive_time", function (obj) {
let timeInMinutes = obj.user_inactive_time;
let timeInMilliseconds = timeInMinutes * (60000);
setInterval(() => {
checkInactivity();
}, timeInMilliseconds);
});
}
Note that if you want to use this value in some other place, it should be declared in the higher scope:
// global declaration
var timeInMilliseconds;
function getInactiveTimePeriod() {
chrome.storage.local.get("user_inactive_time", function (obj) {
let timeInMinutes = obj.user_inactive_time;
timeInMilliseconds = timeInMinutes * (60000); // setting the globally declared variable
setInterval(() => {
checkInactivity();
}, timeInMilliseconds);
});
}
function checkInactivity() {
var timeInseconds = timeInMilliseconds / 1000; // use the globally declared variable
// ...
}

Related

setInterval Function does not execute

I am working on a game using HTML and Javascript. And I need a function to be called every 2 seconds. I tried using setInterval but the function is not being called. And the browser console does not show any errors.
function Apples() {
this.Apples = [];
this.indexCount = 0;
this.CurrentTime;
this.createApples = function() {
this.Apples[this.indexCount] = new Apple();
this.indexCount++;
}
this.updateApples = function() {
for (var i = 0; i < this.indexCount; i++) {
this.Apples[i].positionY += 1;
this.Apples[i].drawApple();
}
}
}
var apples = new Apples;
setInterval(apples.createApples, 200);
It does not work because of the context of this and your code is 200 milliseconds, not 2 seconds.
function Apple () {
return {
positionY: 0,
drawApple: function () {}
}
}
function Apples() {
this.Apples = [];
this.indexCount = 0;
this.CurrentTime;
this.createApples = function() {
this.Apples[this.indexCount] = new Apple();
this.indexCount++;
console.log("new index", this.indexCount);
}
this.updateApples = function() {
for (var i = 0; i < this.indexCount; i++) {
this.Apples[i].positionY += 1;
this.Apples[i].drawApple();
}
}
}
var apples = new Apples;
// use bind
// setInterval(apples.createApples.bind(apples), 2000);
// or use function
setInterval(() => apples.createApples(), 2000);
//setInterval(function () { apples.createApples(); }, 2000);

JavaScript pause setInterval on mouseover

Hi I have a script that cycles through an array of strings and displays them on a specific class using innerHTML.
The arrays setup looks something like:
var myArray = [
"TextString1",
"TextString2",
"TextString3",
"TextString4"
]
var AnotherArray = [
"AnotherArray1",
"AnotherArray2",
"AnotherArray3",
"AnotherArray4"
]
And the SetInterval function itself looks like this
function ArrayPlusDelay(array, delegate, delay) {
var i = 0
// seed first call and store interval (to clear later)
var interval = setInterval(function() {
// each loop, call passed in function
delegate(array[i]);
// increment, and if we're past array, clear interval
if(i++ >= array.length - 1) {
i = 0 //clearInterval(interval);
}
}, delay)
return interval
}
ArrayPlusDelay(myArray, function(obj) {
document.querySelector('.cycle_questions').innerHTML = obj
},2000)
ArrayPlusDelay(AnotherArray, function(obj) {
document.querySelector('.cycle_research').innerHTML = obj
},2000)
Where do I inject the AddEventListener to make the looping stop? And on mouseleave make make the loop continue?
Thanks!
Here is the solution.Here i've introduced two different array.For the purpose of segregation you need two separate interval object.First is intervalObjOne and second is intervalObjTwo.Two object for two different array.If want to use a third array create a third one.You can even make it dynamic,but for the purpose of simplicity i kept them static.
domSelectorByClass and domSelectorByQuery is just a shorter version for document.GetElemensByClassName and document.querySelector to keep the codebase clean.
then the intervalArr is introduced which contain both intervalObjOne and intervalObjTwo.
Then run a forEach loop to iterate over the intervalArr and call attachInterval,addMouseLeaveEvent and addMouseOverEvent functions and pass respective intervalObj to each of them as parameter.
attachInterval event will initiate a setInterval on respective intervalObj's interval property.
addMouseLeaveEvent function will attach a mouseleave event on the respective div element.
addMouseOverEvent function will attach a mouseover event on respective div which will call clearInterval to stop the setInterval.
var myArray = ["TextString1","TextString2","TextString3","TextString4"]
var anotherArray = ["TextString5","TextString6"]
var intervalObjOne = {array: myArray,interval : 'undefined',tick:0,className:'cycle_questions'}
var intervalObjTwo = {array: anotherArray,interval: 'undefined',tick:0,className:'cycle_research'}
var domSelectorByClass = document.getElementsByClassName.bind(document)
var domSelectorByQuery = document.querySelector.bind(document)
var intervalArr = [intervalObjOne,intervalObjTwo]
function ArrayPlusDelay(delegate, delay,intervalObj) {
var interval = setInterval(function() {
delegate(intervalObj.array[intervalObj.tick])
if(intervalObj.tick++ >= (intervalObj.array).length - 1) {
intervalObj.tick=0
}
}, delay)
return interval
}
intervalArr.forEach(function(elem,index){
attachInterval(elem)
addMouseLeaveEvent(elem)
addMouseOverEvent(elem)
})
function attachInterval(intervalObj){
intervalObj.interval = ArrayPlusDelay(function(obj) {
domSelectorByQuery('.'+intervalObj.className).innerHTML = obj
},2000,intervalObj)
}
function addMouseOverEvent(intervalObj){
domSelectorByClass(intervalObj.className)[0].addEventListener('mouseover',function(event){
clearInterval(intervalObj.interval);
});
}
function addMouseLeaveEvent(intervalObj){
domSelectorByClass(intervalObj.className)[0].addEventListener('mouseleave',function(event){
attachInterval(intervalObj)
});
}
<div class='cycle_questions' style='display:inline-block;border:1px solid red;width:100px;height:40px;'></div>
<div class='cycle_research' style='display:inline-block;border:1px solid green;width:100px;height:40px;'></div>
What you can do here is:
1. having an object which store your state
2. Generate a scope to store the position of i:
I slighly modified your code to have something easyer to test:
var myArray = [
"TextString1",
"TextString2",
"TextString3",
"TextString4"
];
var myArrayFoo = [
"TFoong1",
"TFoong2",
"TFoong3",
"TFoong4"
]
// Used to generate your scope
var myFnGenerator = function(array, delegate, interval) {
var i = 0;
return function() {
if (interval.stop) {
return false;
}
delegate(array[i]);
if(i++ >= array.length - 1) {
i=0
}
};
}
function ArrayPlusDelay(array, delegate, delay) {
// The object which store your state
var interval = {
stop: true
};
var fn = myFnGenerator(array, delegate, interval);
interval.timeout = setInterval(fn, delay);
interval.stop = false;
return interval;
}
var interval = ArrayPlusDelay(myArray, function(obj) {
console.log(obj);
},2000)
var intervalFoo = ArrayPlusDelay(myArrayFoo, function(obj) {
console.log(obj);
},2000)
document.getElementById('foo').addEventListener('mouseenter',function(event){
interval.stop = true;
});
document.getElementById('foo').addEventListener('mouseout',function(event){
interval.stop = false;
});
document.getElementById('foo').addEventListener('mouseenter',function(event){
intervalFoo.stop = true;
});
document.getElementById('foo').addEventListener('mouseout',function(event){
intervalFoo.stop = false;
});
I think this way is easyer to read than clearTimeout then relaunch it inside mouseout (less copy paste), but I guess it is more a code's style. If you prefer having clearTimeout:
var myArray = [
"TextString1",
"TextString2",
"TextString3",
"TextString4"
];
var myArrayFoo = [
"TFoong1",
"TFoong2",
"TFoong3",
"TFoong4"
]
var myFnGenerator = function(array, delegate) {
var i = 0;
return function() {
delegate(array[i]);
if(i++ >= array.length - 1) {
i=0
}
};
}
function launchInterval(interval, delay) {
if (interval.timeout === null) {
interval.timeout = setInterval(interval.fn, delay);
}
}
function clearMyInterval(interval) {
if (interval.timeout !== null)
clearInterval(interval.timeout);
interval.timeout = null;
}
function ArrayPlusDelay(array, delegate, delay) {
var interval = {
timeout: null
};
var fn = myFnGenerator(array, delegate);
interval.fn = fn;
launchInterval(interval, delay);
return interval;
}
var interval = ArrayPlusDelay(myArray, function(obj) {
console.log(obj);
},2000)
var intervalFoo = ArrayPlusDelay(myArrayFoo, function(obj) {
console.log(obj);
},2000)
document.getElementById('foo').addEventListener('mouseenter',function(event){
clearMyInterval(interval);
});
document.getElementById('foo').addEventListener('mouseout',function(event){
launchInterval(interval, 2000);
});
document.getElementById('foo').addEventListener('mouseenter',function(event){
clearMyInterval(intervalFoo);
});
document.getElementById('foo').addEventListener('mouseout',function(event){
launchInterval(intervalFoo, 2000);
});
Must meet your needs. I let interval accessible from the function of your setInterval to be able to use clearInterval inside the callback.

Javascript Total Duration of Function Execution?

//this is a loop every 10 seconds it will run again and again.
function GetSomthing(){
start = new Date().getTime()
//do someting
end = new Date().getTime()
}
TotalTime = (end - start);//Total Time reset every time the function restart execution
We will get total time taken to execute the GetSomthing function on the variable "TotalTime".
When The GetSomthing function calls again the "TotalTime" Starts Again from Zero.
I need to save "TotalTime" to a variable that shows overall the Time taken by Main Function regardless of GetSomthing Function.
Can We save
TotalTime = (end - start); to an array and sum all array values to a new variable?
I created a function for a similar question here on SO today. This one automatically calculates very accurate average execution times of global functions. You can modify it to suit your needs:
function testFunc(test) {
for(var i=0;i<100000000;i++) { i = i+test; }
};
function testFunc2(test) {
for(var i=0;i<100000000;i++) { i = i+test; }
};
var getPerfResults = (function(){
var timeRecords = {}, xTr = 0, name;
var setPerfRecords = function(oFn, fnIdentity) {
timeRecords[fnIdentity] = [];
return function(){
var xTime = performance.now();
var xResult = oFn.apply(this, arguments);
xTime = performance.now()-xTime;
timeRecords[fnIdentity].push(xTime);
return xResult;
};
};
for (name in window) {
try { window[name]; // Security exception may occur here
if (typeof window[name] === 'function')
window[name] = setPerfRecords(window[name], name);
}
catch(err) { }
}
return function() {
var resultObj = {}, n, i;
for(i in timeRecords) {
if(timeRecords.hasOwnProperty(i)
&& timeRecords[i].length > 0) {
resultObj[i] = 0;
for(n=0;n<timeRecords[i].length;n++) {
resultObj[i] = resultObj[i]+timeRecords[i][n];
}
resultObj[i] = resultObj[i]/timeRecords[i].length;
}
}
return resultObj;
};
}());
testFunc(1);
testFunc(10);
testFunc(100);
testFunc(1000);
testFunc(10000);
testFunc2(0);
document.body.innerHTML = JSON.stringify(getPerfResults());

Simple counter with a listener and callback

I have a simple class below that starts and then updates a count every second. How would I go about adding functionality for it to listen for a specific value and then fire a callback?
function Counter() {
this.currentCount = 0;
}
Counter.prototype.start = function() {
setInterval(this.update, 1000);
};
Counter.prototype.when = function(value, callback) {
callback(value);
};
Counter.prototype.update = function() {
this.currentCount++;
};
In my mind it would work something like this.
var counter = new Counter();
counter.when(50, function(value) {
console.log('We arrived at ' + value + ', the requested value.');
});
counter.start();
This is just a nice homework, I'll do that for you ;) Please have a look on my solution:
function Counter() {
this.currentCount = 0;
this.conditions = [];
this.interval = undefined;
}
Counter.prototype.start = function() {
if (!this.interval) {
var that = this;
this.interval = setInterval(function () {
that.update();
}, 1000);
}
};
Counter.prototype.stop = function () {
if (this.interval) {
clearInterval(this.interval);
this.interval = undefined;
}
this.currentCount = 0;
};
Counter.prototype.when = function(value, callback) {
var that = this;
this.conditions.push(function () {
if (that.currentCount === value) {
callback.call(that, value);
}
});
};
Counter.prototype.update = function() {
this.currentCount++;
for (var i = 0, l = this.conditions.length; i < l; i++) {
var condition = this.conditions[i];
condition();
}
};
var counter = new Counter();
counter.when(50, function(value) {
console.log('We arrived at ' + value + ', the requested value.');
});
counter.when(60, function (value) {
console.log('Stop at ' + value + '!');
this.stop();
});
counter.start();
and it's fiddled!
Another answer here made a good argument in hiding private variables, but implemented it a bit too confused, so this is another way of doing it similar. Instead of shared prototype functions this is using instance functions. Some may say this needs more memory, but I don't believe it's significant, and allows to easily have privates in a real constructor function.
var Counter = function () {
var that = this, currentCount = 0,
conditions = [], interval;
var update = function () {
currentCount++;
for (var i = 0, l = conditions.length; i < l; i++) {
var condition = conditions[i];
condition();
}
};
this.start = function () {
if (!interval) {
interval = setInterval(function() {
update.call(that);
}, 1000);
}
};
this.when = function (value, callback) {
conditions.push(function () {
if (currentCount === value) {
callback.call(that, value);
}
});
};
this.stop = function () {
if (interval) {
clearInterval(interval);
interval = undefined;
}
currentCount = 0;
};
};
var counter = new Counter();
counter.when(50, function(value) {
console.log('We arrived at ' + value + ', the requested value.');
});
counter.when(60, function (value) {
console.log('Stop at ' + value + '!');
this.stop();
});
counter.start();
see it fiddled!
Notice also that in both examples, counter is instanceof Counter and Object,
whereas Counter is instanceof Function and Object (why I like to write so much code ;))
To support multiple whens:
Add an array of whens in your class:
function Counter() {
this.currentCount = 0;
this.whens = [];
}
Then let the when function push to that:
Counter.prototype.when = function(value, callback) {
this.whens.push({'time' : value, 'callback' : callback});
}
And check for these whens at update:
Counter.prototype.update = function() {
this.currentCount++;
for(var w in this.whens) {
if(this.currentCount == this.whens[w].time) {
this.whens[w].callback();
}
}
}
Try something more like:
function Counter(interval, val, func){
this.currentCount = 0;
setInterval(function(){
this.currentCount++;
if(this.currentCount === val)func();
}, interval);
}
var nc = new Counter(1000, 50, function(){
console.log('We have arrived at '+nc.currrentCount);
});
There is an argument to be made for something like this instead:
var Counter = (function() {
var update = function() {
var idx, callbacks;
this.currentCount++;
callbacks = this.callbacks[this.currentCount];
if (callbacks) {
for (idx = 0; idx < callbacks.length; idx++) {
callbacks[idx](this.currentCount);
}
}
};
var start = function() {
var counter = this;
setInterval(function() {update.call(counter)}, 1000);
};
var when = function(count, callback) {
(this.callbacks[count] || (this.callbacks[count] = [])).push(callback);
};
return function() {
var config = {currentCount: 0, callbacks: {}};
this.start = function() {return start.call(config);};
this.when = function(count, callback) {
return when.call(config, count, callback);
};
// this.stop = ... // if desired
};
}());
This is somewhat more memory intensive than the prototype-based version of the code. I wouldn't use it for something where you were expecting hundreds of thousands or millions of objects. But it has the advantage that it truly encapsulates the data you might like to keep hidden, such as currentCount and the list of callbacks. It doesn't expose an unnecessary update function. And it's not terribly more heavy than the prototype version. Each instance has its own start and when functions, but those are just thin wrappers around common functions.
It is a bit more difficult to add a stop function to this in the same manner, unless you don't mind exposing the the result of setInterval. But it is doable.

Why is my interval time is not get cleared?

This is my function, I wrote this for moving my div from left to right. After iter reach 5, the interval has to stop. But now it is keep on running. My interval is not clearing, what is wrong with my function?
var mydiv = document.getElementById('news-variety');
var iter = 0;
if (mydiv) {
var columns = mydiv.getElementsByTagName('DIV');
function animeColumn(index, col) {
var timerID = window.setInterval(function () {
var current = window.getComputedStyle(col);
var matrix = new WebKitCSSMatrix(current.webkitTransform);
col.style.webkitTransform = matrix.translate(10, 0);
if (iter++ == 5) {
window.clearInterval(timerID);
}
}, 50);
}
for (var i = 0; i < columns.length; i++) {
if (columns[i].className.toLowerCase() == "column") {
columns[i];
animeColumn(i, columns[i]);
}
}
}
There is a weird behavior (bug?) in firefox that requires you to specify the second parameter of getComputedStyle to 'null'. Try:
var current = window.getComputedStyle(col,null);
It is likely that in your current case, the code is throwing an 'argument count' error in the timeout handler, which prevents further execution and thus, never clears the timeout.
Alternatively, you may want to do your loop counting at the start of your loop, as such:
function animeColumn(index, col) {
var timerID = window.setInterval(function () {
if (iter++ == 5) {
window.clearInterval(timerID);
}
var current = window.getComputedStyle(col);
var matrix = new WebKitCSSMatrix(current.webkitTransform);
col.style.webkitTransform = matrix.translate(10, 0);
}, 50);
}
I think it is because your var timerID is not defined at window's level
var mydiv = document.getElementById('news-variety');
var iter = 0;
var timerID;
if (mydiv) {
var columns = mydiv.getElementsByTagName('DIV');
function animeColumn(index, col) {
timerID = window.setInterval(function () {
var current = window.getComputedStyle(col);
var matrix = new WebKitCSSMatrix(current.webkitTransform);
col.style.webkitTransform = matrix.translate(10, 0);
if (iter++ == 5) {
window.clearInterval(timerID);
}
}, 50);
}
for (var i = 0; i < columns.length; i++) {
if (columns[i].className.toLowerCase() == "column") {
columns[i];
animeColumn(i, columns[i]);
}
}
}
iter is global, so it will reach 5 for only one of multiple columns.
Try moving it into the function like this:
function animeColumn(index, col) {
var iter = 0;
var timerID = window.setInterval(function () {
// ...
if (iter++ == 5) {
window.clearInterval(timerID);
}
}, 50);
}
i have created a fiddle for this http://jsfiddle.net/DXSNp/

Categories