I'm very new to javascript and I'm trying to do something I thought would be very basic.
I've created a countdown timer and used "i" as my variable to hold a number from 0-5. And I have an array of "d" from d[0] to d[5] containing strings.
I'm trying to make the timer countdown pass the "i" value into an innerHTML method array value so I want it to display d[5]... d[4]...d[3]... etc.
What am I doing wrong!? Please Help!
<html><head><script language="javascript" type="text/javascript">
var d=new Array():
d[1]="One";
d[2]="Two";
d[3]="Three";
d[4]="Four";
d[5]="Five";
var i=5;
var i=setInterval("timer()",2000); //1000 will run it every 1 second
function timer() {
i--;
if (i <= 0)
clearInterval(countD);
return;
}
}
document.getElementById(timer).innerHTML = d[i];
</script>
</head>
<body>
<h1>
<p id="timer"></p>
</h1>
</body>
</html>
Also, document.getElementById(timer).innerHTML = d[i];
should be document.getElementById("timer").innerHTML = d[i];
id names need to have quotes around them because they are not names of variables. The variable 'timer' is undefined.
Also, you are missing a curly brace on the line if (i <= 0). I am assuming that you meant to exit the function if this if statement is true.
Also, you have a colon instead of a semicolon on the line var d=new Array():
Also, you can't have a paragraph tag inside of an h1
Also, you should encapsulate all of this javascript into a function called something like init. I believe that the javascript code in the head runs before the html is loaded. The javascript can't therefore find the tag. Then, use <body onload="init()"> as your body tag.
EDIT: As the commenters have stated, you are using the variable i for multiple unrelated things.
I'm sorry to say but your code is quite a mess; here's one way to get your code to work, along with a working example:
<html>
<head>
<script language="javascript" type="text/javascript">
var d=new Array();
d[0]="One";
d[1]="Two";
d[2]="Three";
d[3]="Four";
d[4]="Five";
var i=4;
var myTimer =setInterval(timer,2000); //1000 will run it every 1 second
function timer() {
document.getElementById("timer").innerHTML = d[i];
i--;
if (i < 0){
clearInterval(myTimer);
}
}
</script>
</head>
<body>
<h1>
<p id="timer"></p>
</h1>
</body>
</html>
The problems with your JavaScript
You've got two declarations for i, one after the other - one is set to 5 and the other to the setInterval timer
What is countD in clearInterval(countD);?
document.getElementById(timer).innerHTML = d[i]; is attempting to use the function timer as the argument to getElementById. It should be in quotes: document.getElementById("timer").innerHTML = d[i];
It is also being invoked only once since it's not inside the function that is being called by the timer.
var d=new Array(): should be terminated by a ;(semi-colon) and not a : (colon)
You have unmatched braces - your if statement doesn't have an opening brace ({) but it does have a closing one.
Note that while setInterval("timer()", 1000) is valid JavaScript, it depends on eval which should be avoided if possible. The alternate, preferred way to use this is setInterval(timer, 1000) i.e. passing the function and not a string.
Related
Non-working code:
<html>
<body>
<p id="timeCountBar">-></p>
<script>
var timeCountBarText = document.getElementById("timeCountBar").innerHTML;
function subCount(){
timeCountBarText="-"+timeCountBarText;
document.getElementById('timeCountBar.innerHTML').innerHTML=timeCountBarText;
}
function countTime(){
for (int i; i < 100; i++){
setTimeout("subCount",10);
}
//something to do after counting has ended
}
countTime();
</script>
</body>
</html>
Only showed -> and nothing else happened.
What should I do?
SOLVED:
HTML:
<p id="timeCountBar">-></p>
JavaScript:
var timeCountBarText = document.getElementById("timeCountBar").innerHTML;
var sc = setInterval(function(){subCount()}, 10);
var i=0;
var subCount = function() {
timeCountBarText = "-" + timeCountBarText;
document.getElementById('timeCountBar').innerHTML = timeCountBarText;
i=i+1;
if(i==100){
clearInterval(sc);
}
}
You can see it working here:
http://jsfiddle.net/aniruddha153/Ezres/
You had 3 problems:
Logic was not entirely correct.
you should not use setTimeout. Instead you should use setInterval. And the right way to declare setInterval is
setInterval(function(){subCount()}, 10);
You need to use clearInterval
Reference: JavaScript Timing Events
You have two major problems.
The first is easily discovered by looking at the JavaScript console in your browser.
JavaScript is not JavaScript, int should be var.
The second is that setTimeout is not sleep. You need to call subCount either recursively with setTimeout or by using setInterval instead of using a for loop.
How I update the DOM in html meanwhile I'm executing a "while sentece".
Look the example below
<html>
<body>
<input type="text" id="element" >
<input type="submit" id ="run" value="run">
<script>
function contar(){
var contador=0;
while( contador<10){
setTimeout(function(){
$('#element').val( contador );
},1000);
//I use sleep or setTimeout to try to see the values
//if put its in the input.
console.log("contando");
contador++;
}
}
function sleep(seconds){
var e = new Date().getTime() + (seconds * 1000);
while (new Date().getTime() <= e) {
}
}
$('#run').bind('click',contar);
</script>
</body>
</html>
Context:
I have a process logic inside a while loop, this process, generates data that I use to show in a view through of jquery or other way. When I try to update the content in real time, it's mean that when I try to change some value inside a while loop, it does not work .All I see is the last value that generates the process logic. So I wanna see all changing data.
For example in the code above, I would like see 1 ,2,3,.., value to value.
The Problem with your code is, that your while loop
while(contador<10){
setTimeout(function(){
$('#element').val( contador );
},1000);
contador++;
}
will start the inner function $('#element').val( contador ); 10 times with the same delay of 1000ms instead of executing each code after next 1000ms.
The reason for this is, that your program won't wait for 1000ms when calling setTimeout(); - it just starts an other "thread-like" thing, which will be executed after 1000ms. But the program itself will continue straight.
so I think you're looking for something like:
// note these extra function
function updateValue(val){
setTimeout(function(){
$('#element').val( val );
},1000 * val);
}
. . .
var contador = 0;
while(contador<10){
updateValue(contador);
contador++;
}
Here is a working example: jsfiddle
The extra function is needed to be sure that the right number is printed. If you do it in place inside the while loop, the number will always be your maximum.
I've a jsp page which sets 'timestamp' attribute to certain HTML elements. I use the value of these 'timestamp' to display time elapsed in the format - "updated 10 seconds ago" (as tooltips)
I've created a static HTML page for the demonstration of my issue.
This is my code:
<html>
<head>
<script type = "text/javascript">
function setTime() {
var currentDate = new Date();
var elem = document.getElementsByClassName('supermaxvision_timestamp');
if(elem) {
for (var i = 0; i < elem.length; i++) {
var timestamp = elem[i].getAttribute('timestamp');
if(timestamp) {
var startTimestamp = new Date();
startTimestamp.setTime(timestamp)
var difference = currentDate.getTime() -startTimestamp.getTime();
elem[i].innerHTML = difference + " milliseconds";
}
}
}
setInterval(setTime, 1000);
}
</script>
</head>
<body>
<div class='supermaxvision_timestamp' timestamp='1353389123456' ></div>
<div class='supermaxvision_timestamp' timestamp='1353389234567' ></div>
<div class='supermaxvision_timestamp' timestamp='1353389345678' ></div>
<div class='supermaxvision_timestamp' timestamp='1353389456789' ></div>
<div class='supermaxvision_timestamp' timestamp='1353389567890' ></div>
<button onclick="setTime()">start</button>
</body>
</html>
you can just copy paste this code into a text file and open it in a browser (click 'start' button only once).
The problem is that initially the values of my div will update once every second ( as the code - setInterval(setTime, 1000)). But slowly the update interval decreases and values gets updated instantaneously. And within a minute the browser stops responding.
I'm not calling setInterval from within the loop. What is possibly wrong here?
Also, this code doesn't work in IE.
setInterval(fn, ms) says run fn every ms milliseconds, from now until I clear this interval. But on each call, you set a new interval, identical to the last.
So simply change setInterval to setTimeout which does not repeat, and only calls the function provided once. setTimeout can emulate setInterval by calling a function that sets a new timeout recursively. If you do that with intervals, you schedule more and more intervals that never stop. And each time it calls itself, the number of scheduled intervals double. It gets out of hand quickly...
Alternatively, you can move the setInterval out of the setTime function and only call it once, which will keep it being called every second. Like say:
// button calls this.
function startTime() {
setInterval(setTime);
}
function setTime() {
// all that code, but minus the setInterval at the end
}
You're calling setInterval recursively. Every time a new interval is created, that interval creates a new interval. Eventually the browser cannot handle it.
Maybe you would rather something like this?
<button onclick="setInterval(setTime, 1000)">start</button>
setInterval begins a repeating function - as it is right now setTime does it's loop and logic then calls setTimeout every second, each setTimeout call then starts another repeated call to itself every second. if you use setTimeout instead, it will be called once only, but my suggestion would be that instead you simply run setInterval outside your function declaration, like:
<html>
<head>
<script type = "text/javascript">
function GEBCN(cn){
if(document.getElementsByClassName) // Returns NodeList here
return document.getElementsByClassName(cn);
cn = cn.replace(/ *$/, '');
if(document.querySelectorAll) // Returns NodeList here
return document.querySelectorAll((' ' + cn).replace(/ +/g, '.'));
cn = cn.replace(/^ */, '');
var classes = cn.split(/ +/), clength = classes.length;
var els = document.getElementsByTagName('*'), elength = els.length;
var results = [];
var i, j, match;
for(i = 0; i < elength; i++){
match = true;
for(j = clength; j--;)
if(!RegExp(' ' + classes[j] + ' ').test(' ' + els[i].className + ' '))
match = false;
if(match)
results.push(els[i]);
}
// Returns Array here
return results;
}
function setTime() {
var currentDate = new Date();
var elem = GEBCN('supermaxvision_timestamp');
if(elem) {
for (var i = 0; i < elem.length; i++) {
var timestamp = elem[i].getAttribute('timestamp');
if(timestamp) {
var startTimestamp = new Date();
startTimestamp.setTime(timestamp)
var difference = currentDate.getTime() -startTimestamp.getTime();
elem[i].innerHTML = difference + " milliseconds";
}
}
}
}
</script>
</head>
<body>
<div class='supermaxvision_timestamp' timestamp='1353389123456' ></div>
<div class='supermaxvision_timestamp' timestamp='1353389234567' ></div>
<div class='supermaxvision_timestamp' timestamp='1353389345678' ></div>
<div class='supermaxvision_timestamp' timestamp='1353389456789' ></div>
<div class='supermaxvision_timestamp' timestamp='1353389567890' ></div>
<button onclick="setInterval(setTime, 1000)">start</button>
</body>
</html>
Also, the reason this is not working in IE is that it does not properly support the getElementsByClassName method of document. I found that out here: IE 8: Object doesn't support property or method 'getElementsByClassName' and Rob W also gives a good explanation there, but for a quick answer I have modified my code above to work in IE, using querySelectorAll
Derp, thats a jQuery method Chris, why would you just assume people use jQuery. getElementsByClassName & IE8: Object doesn't support this property or method includes an answer from ascii-lime which implements it's own version of getElementsByClassName. There no benefit to me copying all the code to here, but go have a look if you don't want to use jQuery.
OK, I just said there was no point, but I've copied all the code here anyway, above is a working, tested (on ie and ff) example of what you want
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
I have multiple paragraphs in an html-file that should show a dynamic countdown.
So I made a Countdown function in javascript, that returns the remaining time every time it is called. Unfortunately, I don't know how to call this function every second in the html file. Can you please help me out?
This is how my html file looks like:
EDIT, I have many countdown-paragraphs in my html file!:
<p class="countdown"><script>document.write(CountdownAnzeigen('2012-07-16 12:20:00'));</script></p>
<p class="countdown"><script>document.write(CountdownAnzeigen('2012-08-10 10:10:00'));</script></p>
...
The javascript function looks like:
function CountdownAnzeigen(end_datetime){
var Now = new Date();
var Countdown = Date.parse(end_datetime);
var CountdownText = Countdown.getTime()-Now.getTime();
return CountdownText;
}
setInterval(function() {
CountdownAnzeigen('2012-07-16 12:20:00');
}, 1000);
The setInterval(foobar, x) function is used to run a function foobar every x milliseconds.
Note that foobar can either be a function to be run or a string which will be interpreted as a Javascript, but I believe its accepted that using the string methodology is bad practice.
See the MDN setInterval docs.
(See also setInterval's sister method setTimeout's documentation.)
Use data- attributes to associate a target time with each element:
<p class="countdown" data-target-time="2012-07-06 12:20:00"></p>
<p class="countdown" data-target-time="2012-08-10 10:10:00"></p>
Then use a single setInterval function to fill each countdown-classed element with the result of the countdown function for its related time data:
setTimeout(function() {
var countdowns = document.getElementsByClassName("countdown");
for(var i=0; i < countdowns.length; ++i) {
var cd = countdowns[i];
cd.innerHTML = CountdownAnzeigen(cd.getAttribute("data-target-time"));
}
}, 1000);
This creates completely valid HTML5 and still functions correctly in older browsers.
Besides all answers how to use setInterval(), nobody explained, how to get the result into the paragraph. :)
So again, call you function like this:
setInterval(function() { CountdownAnzeigen('2012-07-16 12:20:00'); }, 1000);
And update the function:
// remove return value
return CountdownText;
// and replace it with this
document.getElementById('countdown').innerHTML = CountdownText;
Finally change your HTML to this:
<p class="countdown" id="countdown"></p>
If you don't use any "onload"-handler, place all your JavaScript below the paragraph and call the function once manually, to have the start time immediately and not the first time after one second.
EDIT
If you have multiple paragraphs you could do it like this:
<p class="countdown" id="countdown_1"></p>
<p class="countdown" id="countdown_2"></p>
<script>
setInterval(function() { CountdownAnzeigen('countdown_1', '2012-07-16 12:20:00'); }, 1000)
setInterval(function() { CountdownAnzeigen('countdown_2', '2012-07-16 12:20:00'); }, 500)
</script>
And update the function to:
document.getElementById(id).innerHTML = a;
Where ìd is a new parameter from the function call.
You can call function periodically also via the setTimeout().
Example:
javascript
function CountdownAnzeigen(countdown){
document.getElementById('countdown').innerHTML = countdown--;
if (countdown>0) {
window.setTimeout(function(){CountdownAnzeigen(countdown);}, 1000);
} else { alert('The End');}
}
html
<input type="button" value="count down" onclick="CountdownAnzeigen(10)"/>
<div id="countdown"></div>