I am checking for a change in a CSS class. I want the check to happen every 1000 milliseconds. Currently in the Google Chrome console, I can see it checking without any delay, causing the webpage to crash. What is the issue with the below setTimeout function? Perhaps there is another way of checking for a change in a CSS class also?
var itemInfo = null;
itemInfo = document.getElementById('option-item-info');
while (itemInfo.className == "disabled") {
console.log("Test 1");
getOptionItemInfo();
}
function getOptionItemInfo() {
setTimeout(function() {
console.log("Checking...");
itemInfo = document.getElementById('option-item-info');
}, 1000);
}
Your while loop isn't going to wait for the setTimeout async callback, it's just going to trigger tons of setTimeouts until your browser crashes. Instead, just kick off the setTimeout once and then only call it again from within the callback if you haven't met the desired condition.
getOptionItemInfo();
function getOptionItemInfo() {
setTimeout(function() {
console.log("Checking...");
var itemInfo = document.getElementById('option-item-info');
if (itemInfo.className == "disabled") {
getOptionItemInfo();
} else {
console.log("done!");
}
}, 1000);
}
Related
On my site I have an addEventListener that executes the following code. The variables/constants are defined like this: const header_search_form = document.querySelector('.header-search-form');.
What I need is that this part of the code is executed with a delay of 2 seconds: document.getElementById("header-search-field-input").focus();. The other code should be executed normally, with the if condition also being respected. I already tried some things, but that didn't work.
header_search_button.addEventListener('click', onClickOpensearch);
function onClickOpensearch(){
if(header_search_container.classList.contains('open')){
header_parent.classList.remove('open');
header_search_background.classList.remove('open');
document.getElementById("header-search-field-input").blur();
document.getElementById("header-search-field-input").value = "";
} else {
header_parent.classList.add('open');
header_search_background.classList.add('open');
document.getElementById("header-search-field-input").focus();
}
}
It would be great if someone could show me how to change the code!
This should works straight away:
} else {
header_parent.classList.add('open');
header_search_background.classList.add('open');
setTimeout(function(){
document.getElementById("header-search-field-input").focus();
}, 2000)
}
The same stuff using an arrow function:
} else {
header_parent.classList.add('open');
header_search_background.classList.add('open');
setTimeout(() => {
document.getElementById("header-search-field-input").focus();
}, 2000)
}
Notice, it might blocks user interaction for 2 seconds, this isn't the best of the best practice.
setTimeout(function() {
document.getElementById("header-search-field-input").focus();
}, 2000);
you could use javascript setTimeout method which calls a function after a specified number of milliseconds
header_search_button.addEventListener('click', onClickOpensearch);
function onClickOpensearch(){
if(header_search_container.classList.contains('open')){
header_parent.classList.remove('open');
header_search_background.classList.remove('open');
document.getElementById("header-search-field-input").blur();
document.getElementById("header-search-field-input").value = "";
} else {
header_parent.classList.add('open');
header_search_background.classList.add('open');
var headerSearchField =document.getElementById("header-search-field-input");
setTimeout(() => headerSearchField.focus(), 2000);
}
}
So my hmtl eventhandeling button is
<input type="button" value="Stop" onclick="stop()">
and the javascript function stop() is:
function stop()
{
stop.called = true;
}
and I call this function here:
....
var interval = setInterval(function ()
{
// call generation again for each generation, passing in the previous generations best offspring
best_offspring = generation(best_offspring, characters, amount_offspring, mutation_rate, target_text);
document.getElementById("output_text").value = best_offspring;
document.getElementById("generations").value = generations;
if (score_met)
{
clearInterval(interval);
}
}, delay);
if (stop.called)
{
return;
}
// so that we know that the program has been run atleast once
start = true;
}
Do you need more of the code?
Anyway, what I want is to stop the execution when the function is called. But my interval loop continues even though the stop() function is called. I have also tried to put the ´if(stop.called)insidevar interval` loop. But that didnt work either.
Any ideas? Do I need to provide more info?
if (stop.called)
{
clearInterval(interval);
}
¿?
var interval = setInterval(function ()
{
// call generation again for each generation, passing in the previous generations best offspring
best_offspring = generation(best_offspring, characters, amount_offspring, mutation_rate, target_text);
document.getElementById("output_text").value = best_offspring;
document.getElementById("generations").value = generations;
if (score_met || stop.called)
{
clearInterval(interval);
}
}, delay);
if (stop.called)
{
clearInterval(interval);
return;
}
// so that we know that the program has been run atleast once
start = true;
}
SetInterval returns an Id so you can simply call clearInterval(id);. Return break etc. Doesnt work because it is not really a loop like for and while.
I'm writing javascript code to update the interface from the user.
This task has to be done in the background and shouldn't block anything.
The code is currently blocking/crashing the browser, the while loop is causing the issue.
What i would like is to wait till the checking and installing are complete and then perform other actions also in between. I want to avoid to write the scenario: TimeOut in a TimeOut in a TimeOut, which does work but it makes the code a mess.
updateChecking();
function updateChecking() {
setTimeout(function() {
if (settings.IsChecking === "True") {
var isChecking = false;
var isInstalling = false;
// PROBLEM, Wait till checking is completed
while (isChecking) {
var timerUpdateChecker = setInterval(function() {
getIsCheckingUpdates().done(function(resultIsChecking) {
if (resultIsChecking === "False") {
isChecking = true;
clearInterval(timerUpdateChecker);
}
});
}, 1000);
checkForSystemUpdates();
startCheckingDownloads();
// PROBLEM, Wait till installing is completed
while (isInstalling) {
setInstallerInterface();
var timerInstallChecker = setInterval(function() {
getIsInstallingUpdates().done(function(resultIsUpdating) {
if (resultIsUpdating === "False") {
isInstalling = true;
clearInterval(timerInstallChecker);
}
});
}, 1000);
}
viewUpdateInstalledAlert();
getAvailableUpdates();
unsetInstallerInterface();
};
}
}, 0);
}
Any suggestions that could solve my issue?
While loops run until the condition if false. Now you're setting the variable to false and call while. So I'm not sure how the while will work. From what I understand it should be while(!isChecking).
That said, you should maybe try to replace your setTimeout and setInterval and replace with events. You can create custom event, dispatch and listen. I think it would be much more efficient. Something like this:
var event = new Event('isInstalled');
In your installed function you dispatch the event:
window.dispatchEvent(event);
And you listen to the event to trigger wanted functions.
window.addEventListener('isInstalled', function(){
//whatever needs to happen when installed is done
})
I have this function Offline.check(); , which takes 1 seconds to execute..So below function is not waiting for it and it always return false on first time.I used set time out..but thats always returning null.
function checkstats()
{
Offline.check(); // This returns Offline.state=up or down and it takes 1 seconds to complete.
if(Offline.state=="up")
{
return true;
}
else
{
return false;
}
}
var a = checkstats();
Ideally you could set a callback function with Offline.check, but I understand it is external, so that won't work.
You can use a timeout to wait for Offline.state to get set, but then you'll need to do any actions involving the variable a asynchronously too:
function checkstats(callBack){ // checkstats() now takes a callback
Offline.check(); // Start Offline.check() as usual
setTimeout(function(){ // Set a timeout for 1 second
if(Offline.state=="up") // After 1 second, check Offline.state as usual
{
callBack(true); // ...but we call the callback instead of returning
}
else
{
callBack(false); // ...but we call the callback instead of returning
}
}, 1000);
}
checkstats(function(a){ // This anonymous function is the callback we're using
// Now you can use "a" normally
});
If you're not sure that Offline.check() will take exactly 1 second, you can use an interval instead of a timeout, and try every second for, say, 5 seconds:
function checkstats(callBack){
Offline.check();
var attempt = 0, maxAttempts = 5;
var checkStatsInterval = setInterval(function(){
if(++attempt > maxAttempts){
// Ran out of attempts, just give up
clearInterval(checkStatsInterval);
alert('Waited '+maxAttempts+' seconds for Offline data. Giving up!');
return;
}
if(Offline.state){
clearInterval(checkStatsInterval);
// It's loaded! Now confidently check Offline.state
if(Offline.state=="up")
{
callBack(true);
}
else
{
callBack(false);
}
}
}, 1000);
}
checkstats(function(a){
// Now you can use "a" normally
});
You can use Asynchronous JavaScript to address the issue. There are several ways of implementing asynchronous behaviour in JavaScript. You can use Callbacks, Listeners or Promises.
Anyway, if you are certain that it only takes 1 second, setTimeout in a callback function and allow Offline.check() to complete. (If it's external or lazy to implement async there)
doOfflineCheck(function(){
if(Offline.state=="up")
{
return true;
}
else
{
return false;
}
});
function doOfflineCheck(cb){
setTimeout(function(){
Offline.check();
},1000);
}
I want to be able to call the function work() every 6 seconds. My jQuery code is
function looper(){
// do something
if (loopcheck) {
setInterval(work,6000);
}
else {
console.log('looper stopped');
}
}
The problem I am running into is that it loops over work twice quickly, and then it will wait for 6 seconds. i tried using setTimeout with similar results.
What could be causing work to be called twice before the delay works?
setInterval should be avoided. If you want work to be repeatedly called every 6 seconds, consider a recursive call to setTimeout instead
function loopWork(){
setTimeout(function () {
work();
loopWork();
}, 6000);
}
Then
function looper(){
// do something
if (loopcheck) {
loopWork()
}
else {
console.log('looper stopped');
}
}
And of course if you ever want to stop this, you'd save the value of the last call to setTimeout, and pass that to clearTimeout
var timeoutId;
timeoutId = setTimeout(function () {
work();
loopWork();
}, 6000);
Then to stop it
clearTimeout(timeoutId);
Use old-style setTimeout()
var i=0;
function work(){
console.log(i++);
}
function runner(){
work();
setTimeout(runner, 6000);
}
runner();
I prefer the following pattern myself I find it easier to follow:
function LoopingFunction() {
// do the work
setTimeout(arguments.callee, 6000); // call myself again in 6 seconds
}
And if you want to be able to stop it at any point:
var LoopingFunctionKeepGoing = true;
function LoopingFunction() {
if(!LoopingFunctionKeepGoing) return;
// do the work
setTimeout(arguments.callee, 6000); // call myself again in 6 seconds
}
Now you can stop it at any time by setting LoopingFunctionKeepGoing to false.