Trouble with setTimeout with addEventListener - javascript

I have a vimeo video that I want to play 3 seconds after a button is clicked. I can get the video to play on click, but I can't seem to get the setTimeout in the right spot... any suggestions?
var iframe1 = document.getElementById("prelearn-1");
var player1 = $f(iframe1);
var prelearnBtn = document.getElementById("prelearn-1-btn");
prelearnBtn.addEventListener("click", setTimeout(function(){player1.api("play")}, 3000));
I'm using the vimeo froogaloop API.

Just wrap it inside a function -
prelearnBtn.addEventListener("click", function(){
setTimeout(function(){
player1.api("play");
}, 3000);
});

The setTimeout function takes in a callback function. Just wrap your code in an anonymous function, then it should work. Also, you might have cross-domain issues if you're attempting to access the contents of an iFrame.
var iframe1 = document.getElementById("prelearn-1");
var player1 = $f(iframe1);
var prelearnBtn = document.getElementById("prelearn-1-btn");
prelearnBtn.addEventListener("click", function(){setTimeout(function(){player1.api("play")}, 3000)});

AddEventlistener takes anonymous function as the second argument. So you need to wrap the setTimeout inside the anonymous function. Whenever the click event happens, the setTimeout code will trigger and will play the video.
prelearnBtn.addEventListener("click", function () {
setTimeout(function () {
player1.api("play")
}, 3000)
}, false);

ES2015 shorter syntax + utilizing the 3rd argument of the setTimeout will make our code shorter and nicer while keeping it readiable:
document.querySelector('button').addEventListener("click",() =>
setTimeout(console.log, 1000, "play")
)
<button>Play</button>
The above example replaced OP's player1.api method with console.log for the sake of printing the argument, which illustrate the code works.

Related

is there a way to delay a window.onload event?

I am trying to create a pop-up that automatically appears after a delay. is this possible through javascript? if so how would I implement this into my code?
Here is a link to the code I am working on https://jsfiddle.net/hk2808/7cs4xdmg/
function openPopup() {
window.location.hash = 'openModal';
}
window.onload = openPopup;
You can use setTimeout. I would make a more generic function that runs on onload and simply call openPopup from there.
Try this:
function openPopup() {
window.location.hash = 'openModal';
}
function onPageLoad() {
setTimeout(() => {
openPopup()
}, 3000)
}
window.onload = onPageLoad;
The popup will load 3 seconds after the onload for example.
setTimeout will do what you are looking to do
https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout
No, there isn't a way to delay the window onload. You could try to add a lot of images and other things that take a long time to load, but that's not an ideal solution. Instead, you can use setTimeout to make code run after a period of time.
setTimeout(function(){
window.location.hash = 'openModal';
//or whatever else you want to happen after 1 second
},1000);
//the 1000 means after 1000 miliseconds, or after 1 second.
Hope this helps!

How to run a function with a setTimeout() callback inside iframe when this setTimeout() calls another setTimeout() in parent?

I have a dynamically created iframe on my page. Like this:
var iframe = document.createElement('iframe');
iframe.setAttribute("id","myIframe");
iframe.src = "iframePage.html";
document.body.appendChild(iframe);
Inside the "iframePage.html", I have the same scriptfile.js that runs on mainPage.html. So, I can call all the functions inside one or another page.
In this scriptfile.js, I have this function that is called by a button on "iframePage.html". The function removes the iframe from DOM in 1 second! Just like this:
function closeAndRemoveIframe() {
setTimeout(function() {
var myIframe = window.parent.document.getElementById("myIframe");
myIframe.parentNode.removeChild(myIframe);
},1000);
}
Ok.
But I added to this function a call to another function. But this function contains a setTimeout that generates a 3 second delay.
Just like this:
function closeAndRemoveIframe() {
setTimeout(function() {
var myIframe = window.parent.document.getElementById("myIframe");
myIframe.parentNode.removeChild(myIframe);
myNewFunction();
},1000);
}
The problem is:
This new function has a longer runtime setTimeout (3000 ms).
function myNewFunction() {
setTimeout(function() {
console.log("Hello world");
},3000);
}
The iframe is the one calling the "myNewFunction ()" function. And once it is removed from the DOM after 1 second, the new function doesn't happen because it has a 3 second delay!
The only solution I found was to put the same time in the setTimeout of the first function! But this is not the desirable behavior!
So, is there any way to solve this without having to increase the settimeout time of the first function?
P.s: I'm using vanilla JS.
Thanks a lot!
have you tried moving the myNewFunction call before the removeChild function call?

Setting variables using timer in JS

trying to figure out how to do this and I'm not too sure. I'm trying to update local GPS coordinates every 3 seconds using setTimeout and it's not working properly. I'm very new to js so any help is appreciated. This is what I have so far-
In my main JS file, I have this...
var lat_in={};
var long_in={};
var alt_in={};
$.getScript("test_points.js", function(){
console.log("TP script go");
});
$("#Initiate").click(function() {
if (coordinate=="GPS")
{
console.log("GPS go");
lat_out = lat_in;
long_out = long_in;
alt_out = alt_in;
console.log(lat_out, long_out, alt_out)
}
)}
I'm calling the lat/long/alt from another js document (test_points.js), where the setTimeout is...
setTimeout(function(){
var lat_in=5;
var long_in=5;
var alt_in=-5;
}, 3000);
I have a bunch of setTimeouts one after another, and what I'm trying to do is update the variables every 3 seconds and run them through the if statement again.
Am I even close to doing this properly? Thanks in advance
You have declared those variables with a "var" keyword which makes them local to the function passed to the timeout function. Please remove var and try again.
EDIT :
As other have pointed out, you should use interval instead of timeout and once the changes are reflected, then only you should try accessing them.
JavaScript has two kind of timers, one provides a timeout (delayed execution of a piece of code) called window.setTimeout (because setTimeout is a method of the window object) and a timer that runs a piece of code after a certain interval called window.setInterval.
Watch how both work
setTimeout(function(){
document.getElementById("showcase").innerHTML += "setTimeout fired only once after 3 seconds. <br />"}, 3000);
setInterval(function(){
document.getElementById("showcase").innerHTML += "setInterval fired every after 5 seconds. <br />"}, 5000);
//not part of the solution, just to demonstrate.
setInterval(function(){
document.getElementById("timer").textContent = 1 + parseInt(document.getElementById("timer").textContent);
}, 1000)
#showcase {
padding: 4px;
border: 1px solid grey;
background-color: #f3f3f3;
}
<span id="timer">0</span> seconds <br />
<div id="showcase"></div>
To let a timer run multiple times use setInterval.
On your case
setTimeout(function(){
var lat_in=5;
var long_in=5;
var alt_in=-5;
}, 3000);
When you replace setTimeout to setInterval it still won't work. As others commented, you are declaring the lat_in etc. inside the scope of the function. This means that the variables inside that function are only accessibele inside the function bound to the interval. The keyword is var. It tells the parser to "bind" the variables to the scope of the function. Leave the var and your timer function will overwrite the global variables declared outside the function. The sample below should be fine.
setInterval(function(){
lat_in=5;
long_in=5;
alt_in=-5;
}, 3000);
Also when you first declared the variables they are declared as an empty object.
var lat_in={};
var long_in={};
var alt_in={};
using {} is the same as doing lat_in = new Object(). However in your function you overwrite them with integers. Maybe this isn't meant to be. Check the documentation on your GPS coding to what input it needs.
While we are at it:
you can stop timers too with window.clearTimeout and window.clearInterval. Each referring to its own function of course.
To do this, you need to store the timer into a variable:
timer = window.SetInterval(function(){ ... }, 3000); //always in milliseconds.
clearInterval(timer); // this line will now clear the timer.
Also a smart person could remark: "I can let setTimeout behave like an interval."
window.setTimeout(myTimerFunction, 3000);
function myTimerFunction(){
//do stuff here
window.setTimeout(myTimerFunction, 3000); //call itself again in three seconds.
}
Since setTime out is asynchronous you should not start expressions like lat_out = lat_in; before initialising.
And also you are declaring the variables using Var which makes them local.so remove var.
Simply use setInterval function to call a function after an interval continuesly
$("#Initiate").click(function() {
var intervalCall = window.setInterval(myCallback, 3000);
)}
function myCallback(){
if (coordinate=="GPS")
{
console.log("GPS go");
lat_out = lat_in;
long_out = long_in;
alt_out = alt_in;
console.log(lat_out, long_out, alt_out)
}
}
For more information about setInterval, you can read here

setTimeout delay doesn't wait for the timeout

I trying to wrap my head around setTimeout, but I can't get it to work properly.
I have set up an example here: http://jsfiddle.net/timkl/Fca2n/
I want a text to countdown after an anchor is clicked - but my setTimeout seems to fire at the same time, even though I've set the delay to 1 sec.
This is my HTML:
Click me!
<span id="target"></span>
This is my JS:
$(document).ready(function() {
function foo(){
writeNumber = $("#target");
setTimeout(writeNumber.html("1"),1000);
setTimeout(writeNumber.html("2"),1000);
setTimeout(writeNumber.html("3"),1000);
};
$('a').click(function() {
foo();
});
});
setTimeout takes a function as an argument. You're executing the function and passing the result into setTimeout (so the function is executed straight away). You can use anonymous functions, for example:
setTimeout(function() {
writeNumber.html("1");
}, 1000);
Note that the same is true of setInterval.
You need to wrap your statements in anonymous functions and also stagger your timings -
setTimeout(function(){writeNumber.html("1")},1000);
setTimeout(function(){writeNumber.html("2")},2000);
setTimeout(function(){writeNumber.html("3")},3000);
If you set everything to 1000 the steps will pretty much run simultaneously as the setTimeout function will run the task 1 second after you called the function not 1 second after the previous call to the setTimeout function finished.
Demo - http://jsfiddle.net/JSe3H/1/
You need to use a function reference to be invoked later when the timer expires. Wrap each statement in an anonymous function so that it isn't executed immediately, but rather when the timer expires.
setTimeout(function() { writeNumber.html("1"); },1000);
Also, you want to use a different delay value for each one so that the timers don't expire at the same time. See an updated fiddle at http://jsfiddle.net/RqCqM/
You need tot use a functions to be called after the timeout is passed; you can use anonymous function too, then your function foo will look like this:
function foo(){
writeNumber = $("#target");
setTimeout(function() { writeNumber.html("1"); },1000);
setTimeout(function() { writeNumber.html("2"); },1000);
setTimeout(function() { writeNumber.html("3"); },1000);
};
There is a provision to pass arguments to the function. In your case, you can do it by
setTimeout(writeNumber.html,1000,1);
setTimeout(writeNumber.html,1000,2);
setTimeout(writeNumber.html,1000,3);
third argument to setTimeout function will be pass to writeNumber.html function
Just use setInterval(). Here's what I came up with. Here's your new javascript:
function foo(){
writeNumber = $("#target");
number = 0;
writeNumber.html(number);
setInterval(function(){
number = number+1;
writeNumber.html(number);
},1000);
};
$('a').click(function() {
foo();
});
I landed on this question. It has been answered adequately, and I think using setInterval as #Purag suggested is probably the best approach to get the desired functional behaviour. However the initial code example did not take JavaScript's asynchroneous behaviour into account. This is an often occurring error, which I've made myself on more than occasion :).
So as a side note I wanted to give another possible solution for this which mimics the initial attempt, but this time DOES consider Javascript's Asynchronousity:
setTimeout(function() {
writeNumber.html("1");
setTimeout(function() {
writeNumber.html("1");
setTimeout(function() {
writeNumber.html("1");
}, 1000);
}, 1000);
}, 1000);
Now ofcourse this is clearly terrible code!
I have given a working JSFiddle of it in my own SO question. This code exemplifies the so-called pyramid of doom. And this can be mitigated by using JavaScript promises, as shown in the answers to my question. It takes some work to write a version of WriteNumber() that uses Promises, but then the code can be rewritten to somehting like:
writeNumAsync(0)
.then(writeNumAsync)
.then(writeNumAsync)
.then(writeNumAsync);

Unable to get setTimeout to work in javascript

I am using jquery to slide up an down a div.
For some reason setTimeout is not working (looks like a function scope issue).
Not able to figure out what is wrong with the below code.
(both functions are inside $(document).ready(function(){ } )
$('.slider-thumb').click(function(){
var source = $(this).attr("src");
$('#image_view').css('background-image',"url("+source+")");
$('#image_view').slideDown(1000, calbck);
initiate_timeout();
function calbck(){}
});
function initiate_timeout(){
var time_out = setTimeout(function() {
$('#image_view').slideUp(1000, calbck);
},2000);
}
Indenting the source code shows that you indeed have some scoping issue. The calbck function is private to the click handler function, and is thus not visible to initiate_timeout function. Either make calbck a top-level function, or make initiate_timeout a function local to the click handler function.
$('.slider-thumb').click(function() {
var source = $(this).attr("src");
$('#image_view').css('background-image',"url("+source+")");
$('#image_view').slideDown(1000, calbck);
initiate_timeout();
function calbck(){}
});
function initiate_timeout(){
var time_out = setTimeout(function() {
$('#image_view').slideUp(1000, calbck);
}, 2000);
}
You have some JS errors and scoping issues. Why would you ever have debugging turned off when trying to troubleshoot an error? Change your code to this:
$('.slider-thumb').click(function(){
var source = $(this).attr("src");
$('#image_view').css('background-image',"url("+source+")");
$('#image_view').slideDown(1000);
setTimeout(function() {
$('#image_view').slideUp(1000);
},2000); // will start 2 seconds after slideDown starts (which is 1 second after it completes)
});
or even better, use the completion function of the first animation to set the timer:
$('.slider-thumb').click(function(){
var source = $(this).attr("src");
$('#image_view').css('background-image',"url("+source+")");
$('#image_view').slideDown(1000, setTimeout(function() {
$('#image_view').slideUp(1000);
},1000)); // will stay open for 1 second before sliding up again
});
Or, even better, using jQuery's delay/queuing, you can do this:
$('.slider-thumb').click(function(){
var source = $(this).attr("src");
$('#image_view').css('background-image',"url("+source+")");
$('#image_view').slideDown(1000).delay(1000).slideUp(1000); // delay 1 sec between effects
});
The calbck you were trying to pass to slideUp was not defined in the scope you were using it (inside of initiate_timout()). It was private to your click handler.
jQuery probably has better ways to chain effects than using your own timer, but I see no reason why this code shouldn't work if it matches your HTML.
Note: if your background image wasn't already pre-cached, it may not be loaded right away when your slideDown starts.
Are you getting any errors? You're passing an undefined value as calbck to slideUp in the setTimeout function.
It works for me (with my modified organization): http://jsfiddle.net/v3cjG/1/
And when I run your exact code ( http://jsfiddle.net/v3cjG/2/ ) I get an error for "Can't find variable calbck"--the var I said you were passing without defining.

Categories