This question already has answers here:
Why is my function call that should be scheduled by setTimeout executed immediately? [duplicate]
(3 answers)
Why is the method executed immediately when I use setTimeout?
(8 answers)
Closed 8 years ago.
This is my first real dive into JavaScript. Sure I've used it before, but I've never really written anything from scratch.
Anyway, I'm having a very strange problem that I hope someone can figure out for me.
I'm trying to make the text from a div fade from black to white. Simple, yeah?
The following code works. It will change the color to white, however, the setTimeout time of 500ms is being ignored.
If you use Chrome and look at the JS console, you'll easily see that the doFade() method is being called almost instantaneously, not every 500 milliseconds.
Can anyone explain this?
var started = false;
var newColor;
var div;
var hex = 0;
function fadestart(){
if (typeof fadestart.storedColor == 'undefined') {
div = document.getElementById('test');
fadestart.storedColor = div.style.color;
}
if(!started){
console.log('fadestart');
newColor = fadestart.storedColor;
started = true;
setTimeout(doFade(), 500);
}
}
function fadestop(){
console.log('fadestop');
div.style.color = fadestart.storedColor;
started = false;
hex = 0;
}
function doFade(){
if(hex<=238){
console.log(hex);
hex+=17;
div.style.color="rgb("+hex+","+hex+","+hex+")";
setTimeout(doFade(), 500);
}
}
You need to get rid of the parentheses on doFade().
The parentheses invoke the function instantly.
Just use this in stead: doFade
setTimeout(doFade(), 500);
This line says "execute doFade(), then pass whatever value it returns to setTimeout, which will execute this return value after 500 milliseconds." I.e., you're calling doFade() right there on the spot.
Skip the parentheses to pass the function to setTimeout:
setTimeout(doFade, 500);
I think you should use setTimeout(doFade, 500); or setTimeout("doFade()", 500);
Related
This question already has answers here:
'setInterval' vs 'setTimeout' [duplicate]
(5 answers)
Closed 1 year ago.
I am trying to use set time function if a class exists in the document and that class has some specific data-attributes.So I have started to code in the very generic way and also tried all the ways even using setTimeout in the function, but not working...
Here is the code
jQuery(document).ready(function(jQuery){
if( jQuery('.conversion-content').length > 0 ){
var thread_id = jQuery('.conversion-content').attr('data-thread-id');
var sender = jQuery('.conversion-content').attr('data-sender');
setTimeout(function(){
updateConversation(thread_id, sender);
}, 2000);
}
function updateConversation( thread_id, sender ){
console.log(thread_id,sender);
}
});
Its working for the first time but not working from 2nd time, I had pulled out setTImeout function out of the element checking but no work.
First of all you should assign your thread_id and sender inside the timer, so it would change in time.
Second thing... it does shoot only once, because you are not using setInterval(), but setTimeout(). Only the first one is repeating in time, the second one delays the execution (once).
Third thing is that if at start if( jQuery('.conversion-content').length > 0 ){ won't be met, the timer won't even get initialized. So you should put this inside the timer as well.
This question already has answers here:
How do I add a delay in a JavaScript loop?
(32 answers)
Closed 4 years ago.
I'm trying to have a 2 second delay in between when some p tags get added to the dom. This is what I've got so far.
var inputs = ['blah','blah blah', 'blah blah blah'];
function insertInput(input){
inputs.forEach(function(input){
var commandP = document.createElement('p'),
textNode = document.createTextNode(input),
newInput = document.getElementById('first_input');
commandP.appendChild(textNode);
commandP.className = 'inputs';
delayInsert(newInput, commandP);
})
}
function delayInsert(input, command){
setTimeout(function(){
input.appendChild(command);
}, 2000)
}
insertInput(inputs);
Don't usually use setTimeout often so the answer isn't readily apparent to me but all the dom nodes get added at the same time. If anyone has a solution as to how to go about spacing the insertion of the nodes apart, and to explain why this behavior is occurring in the first place as I'm pretty curious now, I'd greatly appreciate it.
Your forEach calls execute at the same time (give or take) so you get multiple calls to setTimeout at the same time with the same delay, so the functions all execute at the same time.
To tweak that, you just need to modify the delay given to the setTimeout
function insertInput(input) {
inputs.forEach(function (input, i) {
// ...
delayInsert(newInput, commandP, (i + 1) * 2000);
})
}
function delayInsert(input, command, delay) {
setTimeout(function () {
input.appendChild(command);
}, delay);
}
This question already has an answer here:
CasperJS posting only the last item multiple times from my for-loop
(1 answer)
Closed 6 years ago.
Im using phantomjs and casperjs to test out my website.
In my JavaScript I have a for loop using var i, and another var rando inside the loop which increments.
I am calling
console.log(i);
console.log(rando);
for testing, but it does not print the correct value to the command line. However, I know that the variable is changing, as the code does as intended, for example the for loop is incrementing.
I tried using
console.log("%d", i);
but no luck.
My Code using a suggested solution still no luck:
for (i=0; i<100000; i++) { //// first loop
casper.wait(13000, function () {
casper.then(function () {
console.log(String.valueOf(i));
console.log(String.valueOf(rando));
casper.click(x(('/html/body/div[2]/div/div[2]/div/article/div[2]/section[2]/a/span')));
console.log(timeStamp());
});
});
casper.then(function () {
casper.click(x(('/html/body/div[2]/div/div[1]/div/div/a[2]')));
});
if (rando == 14) {
casper.then(function () {
casper.click(x(('/html/body/div[2]/div/div[2]/div/article/header/span/button')));
console.log(timeStamp());
});
rando = 0;
} else {
rando++;
}
}
The result is printing i as 100000 and rando as 10 every time, even when they are incremented.
Try to use
console.log(String.valueOf(i))
If didn't work please show your code
You are probably not handling the promises that the methods to get values from the DOM return.
"Crawling" frameworks massively use promises, to retrieve values from the DOM, because most of the times those values are changed dynamically and are not available as soon as the DOM is retrieved to the client.
more info about Promises here
This is an old gist i made using webdriverjs wich is similar to casper/phantom: link to gist. I specifically made this gist to pratice promise handling.
This question already has answers here:
JS setInterval executes only once
(2 answers)
Closed 6 years ago.
I can't get this code to do anything beyond counting down to 29 from 30. Does anyone have any insight or hints as to what I am doing wrong to cause it to only run once? I checked to make sure that all the functions are being called with console.logs on game.time (except the clearInterval one since it stops already after the first time through). How do I get the setInterval to keep looping until 0? Thanks in advance for any help! :)
//game object to contain variables and methods
var game = {
// variable for time
time: 30,
// Start button onclick creates the time remaining object and calls the forloop to start
start: function() {
// $("#time").html(game.time);
game.countdown = setInterval(game.count(), 1000);
}, //end of start function
//what the set interval does which is subtract one second from game.time
count: function() {
game.time--;
// if statement to check when time gets to zero
if (game.time <= 0) {
game.stop();
}
// puts the current time left on the page
else {
$("#time").html(game.time);
}
}, // End of count function
// stops the set interval
stop: function() {
clearInterval(game.countdown);
}, // end of stop function
}; // end game object
// Start button click calls the start method
$("#start").click(game.start);
setInterval takes a function refererence as a parameter, it should look like:
setInterval(game.count, 1000)
When you write it as game.count(), you're calling the count() method once, which is evaluated immediately.
Then, setInterval's signature will use the return value from that method instead of a function reference:
setInterval(whatever_the_return_value_was, 1000);
By passing only the reference (as game.count), the timer should work as expected. It will call the reference by itself, every 1000ms.
(MDN docs)
This question already has answers here:
Why does the setInterval callback execute only once?
(2 answers)
JS setInterval executes only once
(2 answers)
Closed 6 months ago.
Guys!
I wanna ask about Javascript function setInterval().
My problem is that setInterval() works only one time, not repeating.
Here is my HTML Code
<button id = 'btun' name = 'btun' onclick = 'changecolor();' class = 'btn btn-success btn-block'>Color Change</button>
and Javascript Code
function below(t){
var button = document.getElementById('btun');
var quadrant = (t*t + 2*t + 1)+"px";
console.log('ye');
button.style.marginTop = quadrant;
document.write(pix);
}
var doBelow = setInterval(below(t++),1);
if(t > 50){
clearInterval(doBelow);
}
I can't find what is wrong.
setInterval expects a callback as first argument, but you are calling the actual function.
Call should be like below
setInterval(function() {
below(t++); }
,1);
So here you are creating an anonymous callback which will call your function below. And better put the exit condition t >= 50 inside below function
The setInterval doesn't work even one time. The reason that the function is called once is that you are calling it when trying to use setInterval, and the return value from the function (which is undefined) is used in the setInterval call.
Use a function expression to create an interval that calls below(t++). You would put the code that checks the t > 50 condition inside the function, otherwise that will also only run once.
function below(t){
var button = document.getElementById('btun');
var quadrant = (t*t + 2*t + 1)+"px";
console.log('ye');
button.style.marginTop = quadrant;
document.write(pix);
if(t >= 50){
clearInterval(doBelow);
}
}
var doBelow = setInterval(function() { below(t++); },1);
Note: Using document.write in the interval isn't a good idea. As it runs after the page is completed, it will open a new page to write to which replaces the current page.