Can someone tell me how to make my URLs properly loop into the window.open I created? I’m wondering if the loop is the right answer to make each URL rotate based on my setInterval? If yes, I was wondering if the loop needs to be under var rotate = []{for (var i = 0; i < urls.length; i++)};.
var urls = ["http://www.espn.com","http://www.disney.com","http://www.codingforums.com"];
var rotate = 0;
function goRandom()
{
var newwin = window.open(
urls[ rotate ],
"POPUP",
"height=400,width=600,scrollbars=yes"
);
}
var loop = setInterval(goRandom, 5000);
Just change
urls[ rotate ],
to
urls[ (rotate++) % urls.length ],
The index is incremented each iteration and % urls.length (% is used for getting the remainder after division, hence it ensures the result never grows beyond the array size). You can try it here (remember to allow popups).
You are not updating the value of rotate..
Try doing this
<script type="text/javascript">
var urls = ["http://www.espn.com","http://www.disney.com","http://www.codingforums.com"];
var rotate = 0;
function goRandom( )
{
rotate= (rotate+1) % urls.length;
var newwin = window.open(
urls[ rotate ],
"POPUP",
"height=400,width=600,scrollbars=yes" );
}
var loop= setInterval(goRandom, 5000);
</script>
While the other answers are technically correct, here's a simplied version if you're just starting out with js, all that % can be confusing.
// setup urls
var urls = ["http://www.espn.com","http://www.disney.com","http://www.codingforums.com"];
// rotate is a global variable so can be accessed anywhere
var rotate = 0;
function goRandom( )
{
var newwin = window.open(
urls[ rotate ],
"POPUP",
"height=400,width=600,scrollbars=yes" );
// move to the next array position
rotate++;
// Check if at the end of the array and move back to the beginning
if (rotate >= urls.length)
rotate = 0;
}
// Keep going indefinitely
setInterval(goRandom, 5000);
Now, your function is called goRandom() while this will goSequence() (or goNext()), so you can change this without any form of loop to pick a random url (though your loop var is called 'rotate' so maybe not what you wanted).
// setup urls (global so accessed from anywhere)
var urls = ["http://www.espn.com","http://www.disney.com","http://www.codingforums.com"];
function goRandom( )
{
// get a random url
var rotate = Math.floor(Math.random() * (urls.length - 1));
var newwin = window.open(
urls[ rotate ],
"POPUP",
"height=400,width=600,scrollbars=yes" );
}
// Keep going indefinitely
setInterval(goRandom, 5000);
Related
I have an array of strings that I'm passing to a for loop with a setTimeout inside.
I've tried to for(; ;) and while(true) the function but this just causes the browser to crash.
I've also tried adding an if statement inside the function
if (x == links.length) { loopUrls() }
Which works kind of but skips the entire interval section of the function, cycling the entire array infinitely with no wait.
function loopUrls() {
for (var x = 0, ln = links.length; x < ln; x++) {
setTimeout(function (y) {
document.getElementById('ifURLS').src = links[y];
},x * 500,x);
}
};
loopUrls();
The aim is to have a list of urls that infinitely assigned to the iframe to show reports on a sreen. (the time interval is just small for testing purposes)
There is no need to have multiple timeouts. You can achieve this using setInterval which executes a function every x amount of time. Then in that funciton you keep a state of the current url so you can show the next time the function is run
// creates a function that iterates over the array and every time its called returns the next element
function createIterator(array){
let sourceArray = [...array];
// starts at the end so it resets automatically
let topIndex = sourceArray.length;
let currentIndex = topIndex - 1;
return function (){
currentIndex++;
// if the limit is reached, its reseated
if (currentIndex === topIndex) {
currentIndex = 0;
}
return sourceArray[currentIndex];
}
}
// your urls
let urls = ["a", "b", "c"];
// uses the function to create the iterator
let iterator = createIterator(urls);
setInterval(function() {
let currentUrl = iterator();
document.getElementById('ifURLS').src = currentUrl;
},1000);
No need for loops, as the iterator handles seamlessly
If I understand correctly, you want for every link to have some function that is being executed every X milliseconds.
In order to achieve this I think it's better to use setInterval.
You can do something like:
links.forEach((link) => {
setInterval(() => {
//do something every X milliseconds
}, X)
})
a way to do that :
// const links = [ ... ]
const myImg = document.queryselector('#ifURLS')
function LoadImg()
{
let
indx = 0
, let refIntv =
setInterval( ()=>
{
myImg.src = links[indx++]
if (indx >= links.length)
clearInterval( refIntv )
}
, 5000 ) // 5s delay
}
I created an automatic slideshow in a html webpage, i want to display some text outside the images. This is the script I'm using currently, I had asked on quora they gave me this script
var words = ['beautiful', 'cool', 'amazing'];
var t = setInterval(function() {
var randomNumber = Math.round( Math.random() * (words.length-1) );
$('#changing').html( words[ randomNumber ] );
}, 2000);
But this is randomizing the caption, and I want it in sequence so that it displays it to the approp image. Can someone please help me?
This sounds like you want to keep track of the previous index used in the array, maybe try something like this?
var words = ['beautiful', 'cool', 'amazing'];
var i = 0;
var t = setInterval(function() {
$('#changing').html( words[i] );
i++
if (i >= words.length) i=0;
}, 2000);
I have written this code to change an image:
change = function(){
for (r=0; r<6; r++){
for (i = 0; i < 6 ; i++) {
setInterval(imgfile(number=i+1), 5000);
}
}
}
imgfile= function(number){
a = 'document.getElementById("imgdiv").src = "images/'+number+'.svg"';
eval(a);
}
The function change() is called when a button is clicked.
When I press the button the image changes straight to 6.svg, when I want it to go through the images 1, 2, 3, 4, 5, 6 and to repeat it 6 times. When I change setInterval to change.setInterval or imgfile.setInterval it doesn't work at all. How do I fix this?
change = function(i=0){
imgfile(i%6+1);//change image
if(i<36) setTimeout(change,5000,i+1);//next image in 5 seconds
}
imgfile= function(number){
document.getElementById("imgdiv").src = "images/"+number+".svg";//no need to use ev(i||a)l
}
Instead of loop/interval mess you can simply start a timeout that restarts itself after changing the image... This code will loop over 6 images with a delay of 5 seconds and that 6 times...
Something like this, perhaps?
var index, imgCount, loopCount, imgTag, countdown;
index = 0;
imgCount = 6;
loopCount = 6;
imgTag = document.getElementById('imgdiv');
countdown = function () {
if (index < imgCount * loopCount) {
imgTag.src = 'images/' + index % imgCount + '.svg';
index = index + 1;
setTimeout(countdown, 5000);
}
};
countdown();
Here we're avoiding the double loop and using modular math (index % imgCount) to get the right file number.
For another question I wrote a nice utility function that has quite a number of uses, but can also handle this scenario very easily. The main issue is that there is no time elapsing between the different delays being set. So you are setting 6 different actions to all happen within 5000ms, and all will occur at the same moment.
Here's my original answer
Here's the utility function for that answer, along with its application to your problem.
function doHeavyTask(params) {
var totalMillisAllotted = params.totalMillisAllotted;
var totalTasks = params.totalTasks;
var tasksPerTick = params.tasksPerTick;
var tasksCompleted = 0;
var totalTicks = Math.ceil(totalTasks / tasksPerTick);
var initialDelay = params.initialDelay;
var interval = null;
if (totalTicks === 0) return;
var doTick = function() {
var totalByEndOfTick = Math.min(tasksCompleted + tasksPerTick, totalTasks);
do {
params.task(tasksCompleted++);
} while(tasksCompleted < totalByEndOfTick);
if (tasksCompleted >= totalTasks) clearInterval(interval);
};
// Tick once immediately, and then as many times as needed using setInterval
if (!initialDelay) doTick();
if (tasksCompleted < totalTicks) interval = setInterval(doTick, totalMillisAllotted / totalTicks);
}
// Do 6 actions over the course of 5000 x 6 milliseconds
doHeavyTask({
totalMillisAllotted: 5000 * 6,
totalTasks: 6,
tasksPerTick: 1,
initialDelay: false, // Controls if the 1st tick should occur immediately
task: function(n) { console.log('Set image to "images/' + (n + 1) + '.svg"'); }
});
You want to do setTimeout().
setTimeout pauses for the millesecond value and then does the code. Where setInterval runs the code every whatever milleseconds.
Yeah, don't do change.setInterval or whatever, it is just setInterval.
An example for you would be this inside the for loop to replace the setInterval function.
setTimeout(imgfile(i+1), 5000);
var shots = Math.ceil(Math.random(0,1)*5);
var snd = new Audio("test.wav");
for (var i = 0; i < shots; i++){
snd.play();
}
Now, depending on how many "shots" are fired, i want to play the test.wav the same number of times with a randomized, very short delay in between and possible even "overlapping" sound effect in regards to each other.
How would i best go about doing this ?
- thanks
I would do it like ...
var shots = Math.ceil(Math.random()*5), // Math.random() --> always 0-1 range
src = 'http://upload.wikimedia.org/wikipedia/en/f/f9/Beatles_eleanor_rigby.ogg', // change to your source
maxStartTime = 1000;
for(var i=0;i<shots;i++){
setTimeout(function(){
(new Audio(src)).play();
}, 100 + maxStartTime*(Math.random())); // again you can calibrate the timeout value to what suits you best
}
I have three yellow bars and each of them needs to come from left to right. For that, I have produced this code, but it only works on the last one. Can anyone correct this code; I need to work with pure JavaScript. I am not using any framework. Thanks.
window.onload = function(){
var yellowTitles = document.getElementById('magazine-brief').getElementsByTagName('h2');
for(i=0; i< yellowTitles.length; i++) {
var header = yellowTitles[i];
var timer = i*500;
var yellowBar = setTimeout(animeYellowBar,timer);
function animeYellowBar(){
header.style.left= "0";
}
}
}
Here's how I'd solve the problem:
var yellows = document.getElementById('magazine-brief').getElementsByTagName('h2');
// this will force the header number to be bound correctly
// also animates the div across the page by tracking the current position of x
function createMotion(num){
var currPos = 0;//current x position
var delta = 10;//move by this amount
setInterval(function(){
currPos += delta
yellows[num].style.left = currPos;
}, num * 500);
}
for (var i = 1; i < yellows.length; i++)
{
createMotion(i);
}
Note the function "createMotion" - added so the number "i" is correctly reference in the setInterval function.
Shouldn't you be incrementing your CSS left value instead of just setting it to 0? Why have a timeout at all if you're just going to set the value without gradually incrementing or decrementing?
If you do actually want to use a gradual animation, look at this tutorial : http://www.schillmania.com/content/projects/javascript-animation-1/
Very descriptive and possibly what you want.
By the time your timeout function runs, header refers to your last h2.
Try editing your timeout function to this:
function animeYellowBar(){
var thisheader=header;
thisheader.style.left= "0";
}
var yellows = document.getElementById('magazine-brief').getElementsByTagName('h2');
for (var i = 0; i < yellows.length; i++)
{
(function(idx, el){
window.setTimeout(function(){
var interval = window.setInterval(function(){
el.style.left = parseInt(el.style.left) + 10; // adjust this movement step
if (parseInt(el.style.left) >= 0)
{
el.style.left = 0;
window.clearInterval(interval);
}
}, 100); // adjust this number for animation speed
}, (idx++) * 500);
})(i, yellows[i]);
}