I tried to make a progress bar in javascript, but it didnt load till my
program was finished. How can i make it updating while the program is still running?
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div id="main" onclick="my()">1</div>
<button onclick="myFunction()">start</button>
<script>
function myFunction() {
for(var i=0;i<1000000;i++){
document.getElementById("main").innerHTML=i;
}
}
</script>
</body>
</html>
Use setInterval method which runs in the background without blocking. Once reached the condition you can clear the interval using clearInterval method.
function myFunction() {
// get element reference and cache in a variable
let main = document.getElementById("main"),
// initialize i as 0
i = 0;
// keep interval reference for clearing once i reached 1000000
let intrvl = setInterval(() => {
// check value of i and increment, if reached 1000000 clear the interval
if (i++ === 1000000) clearInterval(intrvl);
// update the content of main element
main.innerHTML = i;
}, 1000); // set required delay in millisecond, any value lesser than 10 will be automatically converts to 10
}
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div id="main" onclick="my()">1</div>
<button onclick="myFunction()">start</button>
<script>
function myFunction() {
let main = document.getElementById("main"),
i = 0;
let intrvl = setInterval(() => {
if (i++ === 1000000) clearInterval(intrvl);
main.innerHTML = i;
},1000);
}
</script>
</body>
</html>
I used setInterval instead of for cicle and i used parseInt() to get integer value of your div innerHTML and then increment it
setInterval(myFunction, 1000) runs myFunction() every 1000 milliseconds
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div id="main" onclick="my()">1</div>
<button onclick="setInterval(myFunction, 1000)">start</button>
<script>
function myFunction(){
var value = parseInt(document.getElementById("main").innerHTML);
document.getElementById("main").innerHTML=value+1;
}
</script>
</body>
</html>
Related
I apologise if my question seems simple, I am still trying to figure out JavaScript. I am building a website where I want the contents of a <p> to constantly change. I want it to loop over the contents of an array defined in my javascript code. However, when I put everything in a while (true) (because I want it to happen constantly), the <p> content never changes and the page is stuck on loading.
Here is the code I have so far:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="about.css">
<meta charset="UTF-8">
<title>My Site</title>
</head>
<script>
function changeDynamicText() {
var descriptions = ['list', 'of', 'strings', 'to', 'loop', 'over'];
let i = 0;
while (true) {
window.setTimeout(function() {
document.getElementById("dynamicline").innerHTML = descriptions[i];
}, 600);
i = i + 1;
if (i >= descriptions.length) i = 0;
}
}
</script>
<body onload="changeDynamicText()">
<p id="dynamicline">Starting Text</p>
</body>
</html>
Help of any kind is greatly appreciated.
When you use while(true), it will block the JavaScript event loop and therefore no longer render the rest of the body.
You can achieve what you're trying to do by working asynchronously. You already did use setTimeout in there, but you could also use setInterval to trigger the method on a recurring basis.
function changeDynamicText() {
var descriptions = ['list','of','strings','to','loop','over'];
let i = 0;
setInterval(function () {
document.getElementById("dynamicline").innerHTML = descriptions[i];
i = i + 1;
if (i >= descriptions.length) i = 0;
}, 600);
}
You can use setInterval instead.
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="about.css">
<meta charset="UTF-8">
<title>My Site</title>
</head>
<script>
function changeDynamicText() {
var descriptions = ['list','of','strings','to','loop','over'];
let i = 0;
setInterval(() => {
document.getElementById("dynamicline").innerHTML = descriptions[i];
i = (i + 1) % descriptions.length;
}, 600)
}
</script>
<body onload="changeDynamicText()">
<p id="dynamicline">Starting Text</p>
</body>
</html>
You can easily do this with setInterval instead of setTimeout. Use setInterval when you need something to constantly do something in periods of time.
And I moved the i manipulation inside of the interval because you want that to execute each time the function gets called.
Also, it's just a really good habit to get into to put your script tags as the very last element of the body in the HTML document. This way you can ensure that all DOM content has loaded before attempting to manipulate the DOM.
Here is a JSFiddle with the code below: https://jsfiddle.net/mparson8/41hpLaqw/2/
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="about.css">
<meta charset="UTF-8">
<title>My Site</title>
</head>
<body onload="changeDynamicText()">
<p id="dynamicline">Starting Text</p>
<script>
function changeDynamicText() {
var descriptions = ['list','of','strings','to','loop','over'];
let i = 0;
let interval = window.setInterval(function () {
document.getElementById("dynamicline").innerHTML = descriptions[i];
i = i + 1;
if (i >= descriptions.length) i = 0;
}, 600);
}
changeDynamicText();
</script>
</body>
</html>
while (true) always blocks the page until it finishes using a break statement, in your code is never finishing, so what you need to do is call the function itself in the timeout (and make i a global variable to keep track of the array position)
let i = 0;
function changeDynamicText() {
var descriptions = ['list','of','strings','to','loop','over'];
setTimeout(function () {
document.getElementById("dynamicline").innerHTML = descriptions[i];
changeDynamicText()
}, 600);
i = i + 1;
if (i >= descriptions.length) i = 0;
}
loops are blockers infinite loops are infinite blockers. What you need is a time based switcher - a built in timeout functionality which you can call in a cyclical manner - or a, on interval ticker. Any of them will do...
function changeDynamicText() {
var descriptions =
['list','of','strings','to','loop','over'];
var i = 0;
setInterval( tick, 800 );
function tick( ) {
dynamicline.innerHTML = descriptions[ i++ ];
if(i >= descriptions.length-1 ) i = 0
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="about.css">
<meta charset="UTF-8">
<title>My Site</title>
</head>
<script>
</script>
<body onload="changeDynamicText()">
<p id="dynamicline">Starting Text</p>
</body>
</html>
I've been working on this code which displays the next traffic light when a button is pressed. Now I am trying to diplay the images in the array every 3 seconds. I have tried using setTimeOut in my code but my code juts stays on the first traffic light.
code:
EDIT(FIXED)
<!DOCTYPE html>
<html>
<body>
<h1>JavaScript Code</h1>
<p>Traffic Light</p>
<img id="traffic" src="only red1.jpg">
<button type="button" onclick="ChangeLight()">Change Light</button>
<script>
var list = ["only red1.jpg","red-yellow 2.jpg", "green3.jpg","yellowonly4.jpg"];
var nextlight = 0;
var timer;
function ChangeLight() {
nextlight = nextlight + 1;
if (nextlight == list.length)
nextlight = 0;
var firstlight = document.getElementById('traffic');
firstlight.src = list[nextlight];
}
timer = setInterval(ChangeLight, 3000);
</script>
</body>
</html>
Solution:
timer = setInterval("ChangeLight", 3000);
Put it out of the function ^^
2 things:
It's supposed to be setInterval(ChangeLight, 3000);
timer is inside the ChangeLight function. You should move it outside.
You may want to change timer = setTimeout("ChangeLight", 3000); into timer = setTimeout(ChangeLight, 3000);.
I could need some help, or maybe just an answer. Is there a way to show changes made by aa js within an executing for loop ? I know there is a way with setInterval, but I have an example with a greater progress where I need it to progress the problem with a for loop. So here is my try:
<!doctype html>
<html>
<head>
<title>life change test</title>
<meta charset="UTF-8">
</head>
<body>
<div id="wrapper">
</div>
<script type="text/javascript">
var el = document.getElementById("wrapper");
/*var i = 0;
var counter = setInterval(function(){
el.innerHTML = i;
i++;
if(i == 18000){
clearInterval(counter);
}
}, 10);*/
for (var i = 400000; i >= 0; i--) {
el.innerHTML = i;
};
</script>
</body>
</html>
My Firefox just freezes until it is completely done, and than displays the result. Is there a chance to actually see the progress ?
I am having some major problems with a javascript app I'm working on. I want my window to open to a closed envelope and then after five seconds to change to an open envelope with a little 1 counter in the corner of it. I want the counter to continue to move up every five seconds unless the envelope is clicked. If clicked I want the count to start over. So far I have only gotten my closed envelope showing up. I'm new and have no idea what I am doing wrong so any help would be awesome!
My html:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="mail.js"></script>
</head>
<body>
<img id"closed" src="closed.png" onclick="resetTimer()">
<span id="counter"></span>
</body>
</html>
And my JavaScript:
window.onload = function(){
var counter = 0;
var timer = setInterval(
function(){
counter++;
document.getElementById("demo").firstChild.nodeValue = counter;
},
5000
);
function openEnvelope(){
var img = document.getElementById("picture");
if (counter > 1){
img.src = "open.png"
}
}
open = setTimeout("open()", 1000);
function resetTimer(){
clearInterval(timer);
}
}
You need to increment your counter and set the counter span to have that value :
var counter = 0;
//Create your timer (setTimeout will only run once, setInterval will start again once run.
//1000 = 1 second
var timer = setInterval(openEnvelope, 1000);
function openEnvelope() {
var img = document.getElementById("picture");
var counterSpan = document.getElementById("counter");
if (counter > 1) {
img.src = "open.png"
counterSpan.innerHTML = counter;
}
//Add 1 to Counter
counter++;
}
function resetTimer() {
clearInterval(timer);
counter = 0;
}
This will run your openEnvelope function every second, and if the counter value is more than 1 it will set the Img Source to be open.png and the counter span to have the counters value. On the click of the Envelope it will clear the timer and reset the counter.
And your HTML will become :
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="mail.js"></script>
</head>
<body>
<img id"picture" src="closed.png" onclick="resetTimer()">
<span id="counter"></span>
</body>
</html>
Here is a working JSFiddle for your problem, try creating a blank page and copying the HTML straight into the <body> tag and the Javascript into <script></script> tags in the <head> of your page.
Really a newbie question but I can't seem to find the answer. I need to have this html file show a bunch of random numbers, separated by 1 second intervals. For some reason (maybe obvious) it is only showing me the last one unless I have 1 alert after each random number generated. How can I correct this?
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
var randomnumber
var message
function placePossibleWinner()
{
randomnumber=Math.floor(Math.random()*11);
message="Teste ";
message=message.concat(randomnumber.toString());
document.getElementById("WINNER").innerHTML=message;
//alert(".")
}
</script>
</head>
<body>
<script type="text/javascript">
function runDraw()
{
var i=1
alert("start")
while (i<20)
{
setTimeout("placePossibleWinner()",1000)
i++
}
}
</script>
<h1>H Draw</h1>
<p id="WINNER">Draw</p>
<p></p>
<button onclick="runDraw()">Get me winner!</button>
</body>
</html>
Thanks in advance for any answers/comments.
The problem is all your setTimeouts are being triggered at the same time. Adding alerts pauses the JavaScript execution, so you see each number. Without that, after 1 second, all 19 setTimeouts run (one after another) and you just see one number (the screen is updated so fast, you just see one).
Try using setInterval instead.
function runDraw() {
var i = 1;
var interval = setInterval(function(){
if(i < 20){
placePossibleWinner();
i++;
}
else{
clearInterval(interval);
}
}, 1000);
}
This will run the function once every second, until i is 20, then it will clear the interval.
I believe you want setInterval instead. using setTimeout in a loop will just queue up 20 calls immediately and they will all fire at once 1 second later. Also, you are setting the innerHTML of the p which will overwrite any previous text.
function placePossibleWinner() {
// add a var here, implicit global
var randomnumber=Math.floor(Math.random()*11);
// add a var here, implicit global
message="Teste " + randomnumber + '\n'; // new line
document.getElementById("WINNER").innerHTML += message; // concat, don't assign
}
function runDraw() {
var counter = 1;
var intervalID = setInterval(function () {
if (counter < 20) {
placePossibleWinner();
counter++;
} else {
clearInterval(intervalID);
}
}, 1000);
}
You are resetting your message in your functions and you are calling placePossibleWinner() the wrong way... you want to use setInterval. Below is a modification of your html/javascript
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
var randomnumber;
var message = "Teste ";
var timesCalled = 0;
var funtionPointer;
function placePossibleWinner()
{
timesCalled++;
randomnumber=Math.floor(Math.random()*11);
message=message.concat(randomnumber.toString());
document.getElementById("WINNER").innerHTML=message;
if (timesCalled > 20)
{
clearInterval(functionPointer);
}
}
</script>
</head>
<body>
<script type="text/javascript">
function runDraw()
{
var i=1
alert("start")
functionPointer = setInterval(placePossibleWinner,1000)
}
</script>
<h1>H Draw</h1>
<p id="WINNER">Draw</p>
<p></p>
<button onclick="runDraw()">Get me winner!</button>
</body>
</html>
To start with,
setTimeout("placePossibleWinner()",1000)
should be
setTimeout(placePossibleWinner,1000)
The parameter to setTimeput should be a reference to a function. See JavaScript,setTimeout