Run URL one by one in For loop - javascript

I have several URLs in my array and I want to run it one by one,
but when I run it in a loop, it executes all at the same time and does not wait.
Here is what I tried:
<html>
<head>
<script>
function work(){
var otherStoryLinksArray = [];
otherStoryLinksArray[0] = 'http://google.com';
otherStoryLinksArray[1] = 'http://www.yahoo.com';
otherStoryLinksArray[2] = 'http://gmail.com';
for(var i=0;i<3;i++){
var openWindow = window.open(otherStoryLinksArray[i]);
setTimeout(function(){openWindow.close();},3000);
}
}
</script>
</head>
<body onload=work();>
</body>
</html>
I want it to open one URL, wait for 30 secs, close the popup, and then start another URL.
Waiting for your reply guys. Any help would be appreciated thanks...

Code: http://jsfiddle.net/WgR4y/1/
Demo: http://jsfiddle.net/WgR4y/1/show/ (make sure you disable popup blocker)
Works for unlimited number of URLs in array.
var otherStoryLinksArray = [
'http://google.com',
'http://www.yahoo.com',
'http://gmail.com'
],
timeToCloseWindow = 3000;
function work() {
if(otherStoryLinksArray.length==0) return;
var url = otherStoryLinksArray.shift();
var openWindow = window.open(url);
setTimeout(function () {
openWindow.close();
work();
}, timeToCloseWindow);
}
work();

You need to stagger your setTimeout calls and since setTimeout uses ms, 30 s = 30000 ms:
function work () {
var otherStoryLinksArray = [];
otherStoryLinksArray[0] = 'http://google.com';
otherStoryLinksArray[1] = 'http://www.yahoo.com';
otherStoryLinksArray[2] = 'http://gmail.com';
for(var i=0; i<3; i++) {
var openWindow;
setTimeout(function () {
openWindow = window.open(otherStoryLinksArray[i]);
}, 30000 * i); //Open this window
setTimeout(function () {
openWindow.close();
}, 30000 * i + 30000); //Close it 30 seconds from "now"
}
}

Use set interval instead of for-loop
function work(){
var otherStoryLinksArray = [];
otherStoryLinksArray[0] = 'http://google.com';
otherStoryLinksArray[1] = 'http://www.yahoo.com';
otherStoryLinksArray[2] = 'http://gmail.com';
var myVar=setInterval(function(){myTimer()},3000);
var i=0;
var openWindow;
function myTimer()
{
if(openWindow != null)
openWindow.close();
if(i < 3)
{
openWindow = window.open(otherStoryLinksArray[i]);
i++;
}
else
clearInterval(myVar);
}
}

var otherStoryLinksArray = [
'http://google.com',
'http://www.yahoo.com',
'http://gmail.com'];
var i = 0;
var openedWindow = null;
function loop(){
openedWindow && openedWindow.close();
if(otherStoryLinksArray[i]){
var openedWindow = window.open(otherStoryLinksArray[i]);
i++;
setTimeout(loop,30000);
}
}

Related

How to clearTimeout so that I can re use the function?

So far, this(code below) allows me to delay my function that displays a response for 4 seconds after I click a button. Now I would like to know how I would reset this timout so that I can re-click the button for the delay to occur.
js:
var ball = document.getElementById("ball");
function start(){
console.log("start");
ball.classList.toggle("shake");
};
ball.addEventListener("click", start);
function newResponse() {
var question = document.getElementById("question").value;
var response = ["..."];
for (var i = 0; i < question.length; i++) {
var randomResponse = Math.floor(Math.random() * response.length);
document.getElementById('quoteDisplay').innerHTML = response[randomResponse];
}
}
ball.addEventListener("click", newResponse)
Declare the function outside the timeout so you can reference it multiple times. Then, call setTimeout with the function, assign the result to a variable, and if you want to clear the timeout, call clearTimeout on that variable:
function newResponse() {
var question = document.getElementById("question").value;
var response = ["..."];
for (var i = 0; i < question.length; i++) {
var randomResponse = Math.floor(Math.random() * response.length);
document.getElementById('quoteDisplay').innerHTML =
response[randomResponse];
}
}
// Set the timeout once:
let timeout = setTimeout(newResponse,4000);
// Clear it:
clearTimeout(timeout);
// Set the timeout again:
timeout = setTimeout(newResponse,4000);
// etc
$('#test').click(function(){
var timer = setTimeout(function newResponse() {
alert('Click answered...');
clearTimeout(timer);
},4000)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="button" value="test" id='test'/>
You can do like this
var timer = setTimeout(function newResponse() {
var question = document.getElementById("question").value;
var response = ["..."];
for (var i = 0; i < question.length; i++) {
var randomResponse = Math.floor(Math.random() * response.length);
document.getElementById('quoteDisplay').innerHTML =
response[randomResponse];
}
clearTimeout(timer);
},4000)

Conflit between setInterval and setTimeout

With an educational purpose I wrote the follow pice of code in JavaScript. The goal is to simulate a teletype machine and after the content is written the machine makes a pause before starts again.
var str = 'Some text';
strArray = str.split("");
window.onload = function teleType() {
var ctrl = 0;
var wrapId = document.getElementById("wrap");
var type = setInterval(function() {
wrapId.innerHTML += strArray[ctrl];
if (ctrl == strArray.length) {
wrapId.innerHTML = "";
ctrl = 0;
clearInterval(type);
}
ctrl++;
}, 2000);
setTimeout(teleType, 3000);
}
But with these intervals (mlliseconds) the machine begin to have an odd behavior. It jumps letters (index) or it starts from the begining without reach the end of the string (array). What is happening between the setInterval and the setTimeout ?
After setInterval is called you call setTimeout immediatelly.
As the result, you will trigger teleType before your interval completes.
You can move your setTimeout in the end of your interval:
var str = 'Some text';
strArray = str.split("");
window.onload = function teleType() {
var ctrl = 0;
var wrapId = document.getElementById("wrap");
var type = setInterval(function() {
wrapId.innerHTML += strArray[ctrl];
if (ctrl == strArray.length) {
wrapId.innerHTML = "";
ctrl = 0;
clearInterval(type);
setTimeout(teleType, 300);
}
ctrl++;
}, 200);
}
<div id="wrap"></div>
Now, teleType function runs interval, and when it finishes writing text it clears HTML content and tells browser to run teleType again in 2 seconds.
By the way, you don't need to set ctrl to 0, because it is local and will be reset anyway.
A sample function which outputs the text to console,
function showTeleText(text, repeat) {
var textByChar = text.split(''),
intermText = '',
textPos = 0;
var interval = setInterval(function () {
intermText += textByChar[textPos++]
console.log(intermText);
if (textPos >= textByChar.length) {
clearInterval(interval);
if (repeat) {
setTimeout(function () {
showTeleText(text, repeat);
}, 2000);
}
}
}, 500);
}
on window.load call showTeleText('Some text!', true/false) like,
window.load = function() {
showTeleText('Some text!', true);
}

Javascript increasing animation

I have the following part of code:
<script>
$(function() {
var ele = $('#clients');
var clr = null;
var rand = 0;
(loop = function() {
clearTimeout(clr);
(inloop = function() {
ele.html(rand+=1);
if(clr==1000) {
return;
}
clr = setTimeout(inloop, 5);
})();
})();
});
</script>
How can i create a second function which will count until another number in the same page? Tried to do a few tests without success..
I tried this:
<script>
$(function() {
var ele = $('#products');
var clr = null;
var rand = 0;
(loop = function() {
clearTimeout(clr);
(inloop = function() {
ele.html(rand+=1);
if(clr==151) {
return;
}
clr = setTimeout(inloop, 5);
})();
})();
});
</script>
But the first function counts only until 2.
Two problems:
You shouldn't use the return value of setTimeout like this - it's not guaranteed to be an incrementing integer, and even when it is, it's global to the page and you can't reset it. Since you're already keeping a count in rand, you can use that to terminate your loop instead of clr.
As pointed out by #putvande, you're overwriting a global inloop variable with your second loop, and they will therefore interfere with each other - you need to declare a local variable.
Also your clearTimeout isn't doing anything useful, and you don't actually need your clr variable...
$(function() {
var ele = $('#clients');
var rand = 0;
var inloop;
(loop = function() {
(inloop = function() {
ele.html(rand+=1);
if(rand==1000) {
return;
}
setTimeout(inloop, 5);
})();
})();
});
$(function() {
var ele = $('#products');
var rand = 0;
var inloop;
(loop = function() {
(inloop = function() {
ele.html(rand+=1);
if(rand==151) {
return;
}
setTimeout(inloop, 5);
})();
})();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="clients"></div>
<div id="products"></div>
Now you can extract the common code and reuse it:
function countTo(ele, count) {
var rand = 0;
var inloop;
(inloop = function() {
ele.html(rand += 1);
if(rand == count) {
return;
}
setTimeout(inloop, 5);
})();
}
$(function() {
countTo($('#clients'), 1000);
countTo($('#products'), 151);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="clients"></div>
<div id="products"></div>
It's because inloop is not defined anywhere and will therefore be defined on a global scope. In your second function, you override this variable. So your first function runs once, and then your second one will run until it stops.
So you should define the inloop inside your loop function:
...
(loop = function() {
var inloop;
clearTimeout(clr);
(inloop = function() {
...
Fiddle
But what you probably want is to rewrite it so you could just call your same functionality twice with some parameters.

how to use setTimeout or setInterval properly

I am using google maps and i am trying to put a pause in execution to prevent QUERY_LIMIT usage issue. My function that plots the addresses looks like this.
The code works, however i want to try setTimeout or setInterval to see if its going to look better on UI.
How do i call it, what should be the first argument?
Thanx alot.
vLocations = [];
for (var i = 0; i < vAddresses.length; i++) {
//pause to prevent OVER_QUERY_LIMIT issue
//geocode "free" usage limit is 5 requests per second
//setTimeout(PlotAddressesAsUnAssigned, 1000);
//sleep(500);
//this will resolve the address and store it in vLocations
AddWaypointAndUnassigned(vAddresses[i]);
var z = i % 4;
if (z==0 && i != 0) {
//sleep after every 5th geocode call
//alert('going to sleep...i: ' + i);
//sleep(3000);
}
}
Doing a pause (asynchronous execution) inside a loop (synchronous) will usually result in a lot of trouble.
You can use recursive calls that are done only when a timeout ends.
var vLocations = [];
// Manages the timeout and recursive calls
function AddWaypointAndUnassignedWithPause(index){
setTimeout(function(){
// When the timeout expires, we process the data, and start the next timeout
AddWaypointAndUnassigned(vAddresses[index]);
// Some other code you want to execute
var z = i % 4;
if (z==0 && i != 0) {
//sleep after every 5th geocode call
//alert('going to sleep...i: ' + i);
//sleep(3000);
}
if(index < vAddresses.length-1)
AddWaypointAndUnassignedWithPause(++index);
}, 1000);
}
// Start the loop
AddWaypointAndUnassignedWithPause(0);
JSFiddle example.
Try this, hope this will help
vLocations = [];
for (var i = 0; i < vAddresses.length; i++) {
//pause to prevent OVER_QUERY_LIMIT issue
setTimeout(function(){
//this will resolve the address and store it in vLocations
AddWaypointAndUnassigned(vAddresses[i]);
}, 500);
var z = i % 4;
if (z==0 && i != 0) {
//sleep after every 5th geocode call
//alert('going to sleep...i: ' + i);
//sleep(3000);
}
}
What about a waiting line, thats fired when an item is added and stopped when there are no items left.
With setTimeout:
var INTERVAL = 1000 / 5;
var to = null;
var vLocations = [];
function addAddress(vAddress) {
vLocations.push(vAddress);
startTimeout();
}
function startTimeout() {
if( to === null ) {
to = setTimout(processLocation, INTERVAL);
}
}
function processLocation() {
if( vLocations.length ) {
var vAddress = vLocations.shift();
AddWaypointAndUnassigned(vAddress);
to = setTimout(processLocation, INTERVAL);
} else {
to = null;
}
}
With setInterval:
var INTERVAL = 1000 / 5;
var to = null;
var vLocations = [];
function addAddress(vAddress) {
vLocations.push(vAddress);
startInterval();
}
function startInterval() {
if( to === null ) {
to = setInterval(processLocation, INTERVAL);
}
}
function processLocation(cb) {
if( vLocations.length ) {
var vAddress = vLocations.shift();
AddWaypointAndUnassigned(vAddress);
} else
clearInterval(to);
to = null;
}
}

JavaScript Sleep Function

I have a banner rotator that refreshes every 60 seconds however I would also like each banner to be displayed for 20 seconds as there are 3 of them. I know where to put the setInterval code as indicated by my comment but I can't seem to get it to work. Any help or suggestions are very much appreciated.
var banners1 = {
0:
{
'href': 'http://www.example.com/banner1.html',
'src': 'http://www.example.com/banner1.gif'
},
1:
{
'href': 'http://www.example.com/banner2.html',
'src': 'http://www.example.com/banner2.gif'
},
2:
{
'href': 'http://www.example.com/banner3.html',
'src': 'http://www.example.com/banner3.gif'
}
}
window.addEvent('domready', function() {
function banner1()
{
var banner = $('banner1');
var banner1Link = $('banner1').getElement('a');
var banner1Image = $('banner1').getElement('img');
for (var keys in banners1) {
var object = banners1[keys];
for (var property in object) {
if (property == 'href') {
var href = object[property];
}
if (property == 'src') {
var src = object[property];
}
}
banner1Link.setProperty('href', href);
banner1Image.setProperty('src', src);
console.log(href);
console.log(src);
/** wait 20 seconds **/
}
}
var periodical = banner1.periodical(60000);
});
Try this instead:
function banner1()
{
var banner = $('banner1');
var banner1Link = $('banner1').getElement('a');
var banner1Image = $('banner1').getElement('img');
var delay = 0;
for (var keys in banners1) {
var func = (function(key) { return function() {
var object = banners1[key];
for (var property in object) {
if (property == 'href') {
var href = object[property];
}
if (property == 'src') {
var src = object[property];
}
}
banner1Link.setProperty('href', href);
banner1Image.setProperty('src', src);
console.log(href);
console.log(src);
}; })(keys);
setTimeout(func, delay);
delay += 20000;
}
}
JavaScript does not have a sleep-style function, because the document will not respond while JavaScript is running. This means the user would not be able to interact with the page while the script is sleeping.
This approach schedules all three updates in one shot. They will execute at 0 seconds (immediately), 20 seconds, and 40 seconds from the time the script runs.
you could use the javascript timeout
setTimeout('', 20000);
This would be added right after the 20 sec comment. The first variable is any code/function you want called. and the second is the amount of time required before it is called in milliseconds (20 secs).
EDITED ANSWER
<script type="text/javascript">
var imgs1 = new Array("http://www.omniadiamond.com/images/jwplayer/enel_culture.png","http://www.omniadiamond.com/images/jwplayer/evas_srm.png","http://www.omniadiamond.com/images/jwplayer/jackolantern.png");
var lnks1 = new Array("http://test.com","http://test.com","http://test.com");
var alt1 = new Array("test","test","test");
var currentAd1 = 0;
var imgCt1 = 3;
function cycle1() {
if (currentAd1 == imgCt1) {
currentAd1 = 0;
}
var banner1 = document.getElementById('adBanner1');
var link1 = document.getElementById('adLink1');
banner1.src=imgs1[currentAd1]
banner1.alt=alt1[currentAd1]
document.getElementById('adLink1').href=lnks1[currentAd1]
currentAd1++;
}
window.setInterval("cycle1()",20000);
</script>
<a href="http://test.com" id="adLink1" target="_top">
<img src="http://www.omniadiamond.com/images/jwplayer/enel_culture.png" id="adBanner1" border="0"></a>
This does cycle through all three in 60 secs at a 20 sec interval. and can be viewed at http://jsfiddle.net/jawilliams346614/wAKGp/ (it is set to a 1 sec interval)

Categories