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>
Related
I want to create a timer that will add or remove divs ( inline divs ) based on time function in Javascript or Jquery.
E.g With each second i want to add a div or remove a div.
Can i get some ideas on this?
<html>
<head>
<title>Testing</title>
<script>
var i = 0;
var myVar=setInterval(function () {myTimer()}, 1000);
function myTimer()
{
document.getElementById('Container').innerHTML += "<div id='"+i+"'>This is the Div with New ID 'i'</div>";
i++;
}
</script>
</head>
<body>
<div id='Container'>
</div>
</body>
</html>
This Should Create a DIV each second inside the Div with id 'Container'
Use setInterval.
var diff = 1000, // how long between adds in milliseconds
totalTime = 0, // how long we have run
maxTime = 1000*60*60*5, // how long we want to run
interval = setInterval(function() {
$(".parentDiv").append($("<div>new div</div>"));
totalTime += diff; // keep track of all of our time
if (totalTime >= maxTime) {
clearInterval(interval);
}
},diff);
Note that the time is in milliseconds.
And to get rid of it
clearInterval(interval);
Beware that it will keep running, and if any of your actions take too long or slow down, you could find yourself with quite the mess stumbling over each other.
You can make use of setTimeout(function, mili seconds)
var testTimer;
function timer()
{
// Do your stuff
testTimer = setTimeout("timer()",1000);
}
This will call your timer function every one second. and you can do your stuff in this function
To stop this timer function you can do
window.clearTimeout(testTimer);
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
I want to change only <p> tag contents using javascript after a defined time delay. For example a
<p>messages</p>
should change depending on the no. of new messages came. As
<p>messages(1)</p>
<p>messages(2)</p>
Write your <p> as:
<p class="messages">messages</p>
Your javascript:
function updateMessages() {
var ps = document.getElementsByClassName("messages");
for(var i = 0, len = ps.length; i < len; i++) {
ps[i].innerHTML = "messages (" + messageCount + ")";
}
}
setTimeout(updateMessages, 1000);
Where 1000 is the number of milliseconds to delay.
Or if you want to do it periodically every 15 seconds, you can use setInterval:
setInterval(updateMessages, 15000);
UPDATE:
I see your comment above:
new messages are retrieved from the database using a JSP function that checks database for new messages
In that case, I gather you want to retrieve that periodically, in effect polling that URL? If you already use a javascript framework, I suggest you look at their AJAX documentation.
$(document).ready({
function updatePara() {
$('p').html('Content to set in para');
}
});
setTimeout(updatePara, no.of milisecond to delay);
jQuery make dom manipulation much easy :)
The above code changes content of all the paragraph, So better to give the desired paragragh <p></p> some call name then filter the para to update with those name i.e $('p.classname').html('your content') OR $('.classname').html('Your content')
jQuery is AWESOME !!! :)
You can use setTimeout function:
var delay = 1000; // 1 second
setTimeout(function() {
var pNodes = document.getElementsByTagName('p');
for (var i=0, length=pNodes.length; i < length; i++) {
pNodes[i].innerHTML = pNodes[i].innerHTML+"("+ (i+1) +")";
}
}, delay);
getElementsByTagName is used just for example. The way of retrieving pNodes depends on structure of your html code.