Change innerHTML color randomly in loop - javascript

I am trying to run a loop that will continuously change the color by randomly generating hex codes. I tried to search on here but couldn't find anything doing this.
I can't figure out how to get a loop to run and change the color continuously (until the end of a loop). I am new to JavaScript.
Here's my JSFiddle.
HTML
<body>
<div id="outer">
<div id="test">Generate colors.</div>
</div>
</body>
JS
for ( i = 0; i < 20000; i++ ) {
var t = document.getElementById('test');
var z = '#'+(Math.random()*0xFFFFFF<<0).toString(16);
t.style.color = z
}

You can't change colors in a loop, the color of the element won't change until you exit the code and return control to the browser.
You can use an interval to run code and return the control to the browser each time:
window.setInterval(function(){
var t = document.getElementById('test');
var z = '#'+(Math.random()*0xFFFFFF<<0).toString(16);
t.style.color = z
}, 100);
Demo: http://jsfiddle.net/et3qtr3t/

You were right with the commented setInterval you have on fiddle. It will make the colors change periodically (according to the milliseconds defined).
But you have to remove the for loop, because it will run instantly and you won't even see the changes... You'll have to manage your own variable counter, and clear the interval after it:
http://jsfiddle.net/kkfnjpsh/5/
var i = 0;
var runner = setInterval(function(){
if(i < 20000) {
var t = document.getElementById('test');
var z = '#'+(Math.random()*0xFFFFFF<<0).toString(16);
t.style.color = z;
i++;
}
else {
clearInterval(runner);
}
}, 3000);

I know it's already been answered, but mine includes the cleartimeout to set a timer.
var myVar = setInterval(function(){changeColor()}, 1000);
setTimeout(function(){clearInterval(myVar)}, 5000);
The second argument in the call to setTimeout could serve as your timer, so that the animation stops afterwards, in this case, it's set to 5 seconds.
function changeColor() {
var t = document.getElementById('test');
var z = '#'+(Math.random()*0xFFFFFF<<0).toString(16);
t.style.color = z;
console.log(z);
}
Result: Result

You don't loop - you interval:
var target= document.getElementById('test'),
colorChange = function() {
target.style.color = '#'+(Math.random()*0xFFFFFF<<0).toString(16);
};
// run interval
var d = setInterval(function() {
colorChange();
}, 500);
// clear after 5s
setTimeout(function() {
clearInterval(d);
}, 5000);
Working JSFiddle: http://jsfiddle.net/046q6ohf/

Related

Variable doesn't influence speed of setInterval loop

I want the speed of my loop to be influenced by a variable (x). This will influence how fast a value (t) is increased, when a button is clicked. I wrote my code, and it should work but it doesn't. Help.
var timeCounter = document.getElementById("time");
var x;
var t;
function timeOnLoad(){
time = 0;
x = 1000;
}
setInterval(function(){
t++;
timeCounter.innerHTML = t;
},x)
function changeSpeed(){
x = 2000;
}
function valueSpeed(){
alert(x);
}
body{
background-color:white;
}
<div onload="timeOnLoad()" id="time"></div>
<button onclick="changeSpeed()">Change x by 1 sec</button>
<button onclick="valueSpeed()">Get value of x</button>
That happens because interval uses x variable only on initialization. It's not dynamic. You have to stop the timer and reinstantiate it in order for it to work. Here's an example:
var timeCounter = document.getElementById("time");
var t = 0, x = 1000, interval;
function changeSpeed(){
x = x + 1000;
restartInterval();
}
function valueSpeed(){
alert(x);
}
function restartInterval() {
clearInterval(interval);
interval = setInterval(function(){
t++;
timeCounter.innerHTML = t;
}, x);
}
restartInterval();
body{
background-color:white;
}
<div id="time"></div>
<button onclick="changeSpeed()">Change x by 1 sec</button>
<button onclick="valueSpeed()">Get value of x</button>
Also, div doesn't have an onLoad event. You have to put this code elsewhere.
You need to cancel and re-instantiate the setInterval when you want to update it. The value set is not dynamic and once it is set it remains at that value.
var timeCounter = document.getElementById("time");
var x = 1;
var t = 0;
function timeOnLoad(){
time = 0;
x = 1000;
}
// Create a function to init the timer. Additionally, create a var to track the actual timeout.
var timer = null;
function setTimer() {
console.log("Setting time to: " + x);
timer = setInterval(function(){
t++;
timeCounter.innerHTML = t;
},x);
}
// Clear the timeout and update the value. Then call your timeout again.
function changeSpeed(){
clearTimeout(timer);
x = Math.floor(Math.random() * 5000);
setTimer();
}
function valueSpeed(){
alert(x);
}
setTimer();
<p id="time"></p>
<button id="updatetime" onclick="changeSpeed()">Cickme</button>
So basically what I did above was create an actual variable to track the timeout obj and then create a function to call it.
Next, inside of your changeSpeed function, clear the timeout to stop it from running and then set your new value. Finally call your setTimer again to restart it with the new value.
I made the x value a random number so you could more easily see the change multiple times.

How to implement setInterval with loop and onclick function correctly?

I learn Javascript, just trying to understand how to work with setInterval in different situations.
Now I have problem situation, please someone explain me where is the mistake, and how to do it correctly.
Problem situation:
I want by click to get new coordinate from counter and console log it.
For example I click on a button, and console shows me that:
0
after 2000 ms 1
after 2000 ms 2
after 2000 ms 3
and so on
for example we have a function that do something with coordinates, just console log it's enough:
var showUs = function(coordinate){
console.log(coordinate)
}
another function is a counter that increase it:
var increase = function(){
for(var i = 0; i < 50; i+=1){
showUs(i);
}
}
and the last is the function that should shows coordinate with interval:
somebuttom.onclick = function(){
setInterval(function(){ increase() }, 2000);
}
Just noticed your update. If you want to do it that way then try this:
DEMO
var somebutton = document.getElementById('somebutton');
var showUs = function(coordinate){
console.log(coordinate)
}
var increase = function(){
var i = 0;
var si = setInterval(function(){
if(i < 50){
showUs(i);
i++;
}else{
clearInterval(si);
}
}, 2000);
}
somebutton.onclick = function(){
increase();
}

How to run a javascript function X seconds?

I am using setInterval to run a Javascript function that generates a new, random integer in a div. the timer starts when I click on the div. I am having problems with stopping it form generating new numbers after five seconds.
Using setTimeout, I hide the div after 5 seconds; that stops random numbers, but I lose the div.
How can I efficiently stop the generating of numbers in the div, and not hide it?
HTML:
<div id="div" onmousedown='F();'>Click here</div>
JS:
function F(){
var div = document.getElementById("div");
setInterval(function(){
var number = Math.floor(Math.random()*28) ;
div.innerHTML = number;
}, 1000);
setTimeout(function(){
div.style.display = 'none';
},5000);
};
Just use a counter to keep track of the number of times the interval has ticked and then use clearInterval to stop it:
var count = 0;
var intervalID = setInterval(function() {
// generate your random number
count++;
if (count === 5) {
clearInterval(intervalID);
}
}, 1000);
Something hastily written, but what you want to do is keep track of your interval handle and then clear it. You can do this with a setTimeout
var forXsecs = function(period, func) {
var handle = setInterval(func, 1000);
setTimeout(function() { clearInterval(handle); }, period * 1000);
}
The timing is not perfect. Matt's answer would also work.
Another option is a slight change on Matt's answer that removes setInterval and just uses timeouts.
var count = 0;
var forXsecs = function(period, func) {
if(count < period) {
func();
count++;
setTimeout(function() {forXsecs(period, func);}, 1000);
} else {
count = 0; //need to reset the count for possible future calls
}
}
If you just want to simply let it run once each second and that 5 times you can do it like this:
HTML:
<div id="5seconds"></div>
JS:
var count= 0;
setInterval(function(){
if(count < 5){
document.getElementById('5seconds').innerHTML = Math.random();
count++
}
},1000);
This will generate a random number each second. until 5 seconds have passed
you should use clearInterval to stop the timer.
To do so, you pass in the id(or handle) of a timer returned from the setInterval function (which creates it).
I recommend clearing the interval timer (using clearInterval) from within the function being executed.
var elm = document.querySelector("div.container");
var cnt = 0;
var timerID;
function generateNumber()
{
cnt += 1;
elm.innerText = cnt;
if (cnt >= 5) {
window.clearInterval(timerID);
}
}
timerID = window.setInterval(generateNumber, 1000);
.container {display:block; min-width:5em;line-height:5em;min-height:5em;background-color:whitesmoke;border:0.1em outset whitesmoke;}
<label>1s Interval over 5s</label>
<div class="container"></div>

Canvas issues with updating

<canvas id="ctx" width="500" height="500" style="border:1px solid #000000;">
<script type="text/javascript">
window.onload = function() {
var ctx = document.getElementById("ctx").getContext("2d");
function createText(words) {
var LENGTH = words.length;
var LOOPS = LENGTH;
var reader = 0;
position = 10;
while( LOOPS > 0) {
letter = words.substr(reader,1);
setTimeout(ctx.fillText(letter,position,10),100);
position += 6;
reader += 1;
LOOPS -= 1;
}
}
createText("Hello, how are you?");
}
</script>
</canvas>
I want it to do kind of like a typing animation where it paused for a fraction of a second before each letter is printed, but instead it loads all at the same time. What am I doing wrong?
So there were a few things making this not work for you, for setTimeout your ctx.fillText was being called right away, as soon as the loop hit it. To stop that you need to wrap it in a function so it will be called during the timeout.
setTimeout(function(){
// your logic here.
}, 100);
However if you do that you will run into the common issue where you will only get the last letter due to the way variable scoping works in JavaScript. To fix that you need to wrap your function in a closure and pass the values to it.
// loop start
a++;
b++;
setTimeout(
(function (a,b) {
return function () {
// some logic that uses a and b
}
})(a, b), 100);
// loop end
The last thing that happens is your timeout is set to 100.. so it will all still happen at once. Meaning every timeout is going to fire after 100ms since the creation loop is so fast. In order to solve this you need to save the delay somewhere and increase that in the loop so they happen after one another. For example the first one will be delayed 100ms, and the next one 200ms, then 300, ect.
// loop start
a++;
b++;
// Increase the time delay each loop iteration
timeDelay += 100;
setTimeout(
(function (a,b) {
return function () {
// some logic that uses a and b
}
})(a, b), timeDelay);
// loop end
Full working code and demo
Live Demo
window.onload = function () {
var ctx = document.getElementById("ctx").getContext("2d");
function createText(words) {
var LENGTH = words.length;
var LOOPS = LENGTH;
var reader = 0;
var timeDelay = 100;
position = 10;
while (LOOPS > 0) {
letter = words.substr(reader, 1);
setTimeout((function (letter, position) {
return function () {
ctx.fillText(letter, position, 10);
}
})(letter, position), timeDelay);
position += 6;
reader += 1;
LOOPS -= 1;
timeDelay += 100;
}
}
createText("Hello, how are you?");
}

Adding content using Javascript before other content

So I'm trying to make a little "Matrix" themed program, I want the user to input their name, and then the program will run through 20 numbers every second as it displays each character of their name every 1 second, from left to right. What am I doing wrong? All that's working so far is the number scrolling
<html>
<head>
<script type="text/javascript">
var name = prompt("Enter Your Name to be 'MatrixIzed!':", "");
function numberScroll(){
for (i=0;i<name.length;i++){
setInterval(function() {
var n = Math.floor(Math.random() * 9);
document.getElementById('txt2').innerHTML = n;
}, 50);
setInterval(function() {
document.getElementById('txt1').innerHTML = name.charAt(i);
},1000);
}
}
</script>
</head>
<body onLoad="numberScroll()">
<div style="float:left" id="txt1"></div>
<div id="txt2"></div>
</body>
</html>
The setInterval is the loop, you don't need additional for loop. Also, you should set variable to store return value from set interval so you can clear it later when you want it to stop running.
function numberScroll(){
// no need to loop i, just set it and increment it in the interval
var i = 0;
// store interval as variable, so you can stop it later
var numbers = setInterval(function(){
var n = Math.floor(Math.random() * 9);
document.getElementById('txt2').innerHTML = n;
}, 50);
var letters = setInterval(function(){
// `+=` rather than `=` to incrementally add to the div's inner html
// use and increment i in one step with `i++`
document.getElementById('txt1').innerHTML += name.charAt(i++);
// when it has reached the end of the name, clear the intervals and empty the second div
if(i >= name.length){
clearInterval(numbers);
clearInterval(letters);
document.getElementById('txt2').innerHTML = '';
}
},500);
}
Fiddle (demo) here: http://jsfiddle.net/jW8hZ/
you need to iterate through all the letters inside the setInterval.
function numberScroll(){
setInterval(function() {
var n = Math.floor(Math.random() * 9);
document.getElementById('txt2').innerHTML = n;}
, 50);
var i=0;
setInterval(function() {
document.getElementById('txt1').innerHTML = name.charAt(i);
i = (i+1)%name.lenghth;
}
,1000);
}

Categories