homepage Welcome to WebmasterWorld Guest from 54.161.155.142
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member

Home / Forums Index / Code, Content, and Presentation / JavaScript and AJAX
Forum Library, Charter, Moderator: open

JavaScript and AJAX Forum

    
getting a global variable to update every setInterval call
cybernoob




msg:4449320
 11:42 am on May 4, 2012 (gmt 0)


i cant get the time to tick down to 0 from 30 seconds, it only ticks down to 29, and im assuming the global variable never changes from 30, so each time the clock "ticks" it goes down to 29 from 30, effectively staying at 29 indefinitely

----------------------------------------

<!DOCTYPE html>
<html lang="en">
<head>

<title>assignment 6</title>

<style type="text/css">

body {
color:#000000;
background-color:#FFFFFF;
}
a { color:#0000FF; }
a:visited { color:#800080; }
a:hover { color:#008000; }
a:active { color:#FF0000; }

#gameContainer{border:solid;width:50%;height:200px; margin-left:25%; margin-right:25%;}
#buttonBox{border:solid; margin-left:20%; margin-top:5px;float:left;}
#emptySpace{float:left; margin-top:5px; width:10%; }
#statsBox{border:solid; margin-top:5px; float:left; margin-right:20%;}
</style>

<script type="text/javascript">

/*
var time=30;
var score=0;
var highScore=0;
var play=false;

function play(time,score,highScore,play){
play=true;
time=30;
score=0;
}
function buttonPress(score){
score+=1;
}
*/
var time=30;
var play=true;

//var t=setInterval(clock(),1000);
function startClock(){
var t=setInterval(clock(time,play),1000)
}

function clock(time,play){
//alert("hi");

if(time>0){
time=time-1;
document.getElementById("time").innerHTML=time;
return time;
}
else{
clearInterval(t);
play=false;
return;
}
//setTimeout(alert("hi"),1000);
}





</script>

</head>
<body>

<div id="gameContainer">

<div id="game">
<div id="buttonBox"><button id="button" onclick="buttonPress();">Click Me!</button></div>
<div id="emptySpace"></div>

<div id="statsBox">
Time:<div id="time">30</div>
Score:<div id="score">0</div>
High Score:<div id="highScore">0</div>
<button id="play" onclick="startClock();">play!</button>
</div>


</div>

</div>

</body>
</html>

 

shingokko




msg:4449363
 12:35 pm on May 4, 2012 (gmt 0)

var t=setInterval(clock(time,play),1000)

What you are doing here is calling the function 'clock(time,play)' and setting the callback function of setInterval to the result, which is 'undefined'. You should change it to:

var t = setInterval(function() { clock(time,play); }, 1000);

Also I want to point out that:

- you should declare the variables of the same name once to avoid confusion at least in your code, for example, you are declaring the variable 'time' twice.

var time = 30;

// your functions

var time = 30; // <= no point doing this

Also the parameters of some of your functions are the same as some of the global variables you've already declared. You should change them so that it's clear wherher you are setting the value of global or local variables.

Good luck!

birdbrain




msg:4449376
 1:04 pm on May 4, 2012 (gmt 0)

Hi there cybernoob,

here is your code, tidied up a little...

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="language" content="english">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">

<title>assignment 6</title>

<style type="text/css">
body {
color:#000;
background-color:#fff;
}
a {
color:#00f;
}
a:visited {
color:#800080;
}
a:hover {
color:#008000;
}
a:active {
color:#f00;
}

#gameContainer {
width:50%;
height:200px;
border:1px solid #000;
margin:auto;
}
#button{
margin:5px 0 0 20%;
margin-top:5px;
float:left;
}
#statsBox {
padding:10px;
border:1px solid #000;
margin:5px 0 0 10%;
float:left;
}
#statsBox div {
margin:6px;
}
</style>

<script type="text/javascript">

function clock(){

if(time>0){
time--;

if(time<10){
time='0'+time;
}
document.getElementById('time').innerHTML=time;
}
else {
clearTimeout(t);
play=false;
return;
}
t=setTimeout(function(){clock()},1000)
}

function buttonPress() {
alert('this is working OK');
}

function init(){

time=30;

document.getElementById('button').onclick=function() {
buttonPress();
}
document.getElementById('play').onclick=function() {
clock();
}
}
window.addEventListener?
window.addEventListener('load',init,false):
window.attachEvent('onload',init);
</script>

</head>
<body>

<div id="gameContainer">

<button id="button">Click Me!</button>

<div id="statsBox">
<div>Time:<span id="time">30</span></div>
<div>Score:<span id="score">0</span></div>
<div>High Score:<span id="highScore">0</span></div>
<div><button id="play">play!</button></div>
</div>

</div>

</body>
</html>

bordbrain

Fotiman




msg:4449392
 1:47 pm on May 4, 2012 (gmt 0)

Welcome to WebmasterWorld, both of you. :)

1. Kudos to cybernoob for using an HTML5 doctype. :)

2. You don't need the type attribute on the script tag, so <script type="text/javascript"> could be shortened to just <script>

3. Instead of time=time-1; you can do either:
time -= 1;
time--; // I prefer this one

4. Scripts are best included at the end of your document just before the closing </body> tag.

5. You've got a minor case of divitis. ;) By that, I just mean your HTML markup is using a lot of non-semantic div elements, and there may be some semantic elements that make more sense.

6. You should avoid using inline event handlers (don't include onclick attributes within your HTML markup, instead attach the event handlers from the script itself).

Now, on to your question...

Lets step through the code.
1. User presses the "play" button, and startClock() is called.
2. startClock creates a local (this is important) variable t to store the result of setInterval, which is a timer id. However, as shingokko pointed out, your code is calling the clock function immediately, and it's the return value of that call to clock which will be called by setInterval. This can be corrected by wrapping the call to clock in an anonymous function definition. Basically, the first parameter to setInterval should be a function reference, and by including parenthesis after the function you are calling that function immediately. So, you could do this:

var t = setInterval(function() { clock(time, play);}, 1000);

When the interval happened, it would call the anonymous function, which in turn would call the clock function, passing in the global time and play variables as parameters. However, we need to look at the clock function...

Your clock function is attempting to modify the global variable time and play. However, you've defined the parameter variables of clock to have the same variable names as the globals, which means that your clock function will not be able to modify the global variables, and will instead only be operating on the local variables. So, why are we passing in those values? The local scope of those variables are preventing you from modifying the global ones, so lets get rid of them and change your function to this:


function clock() {
if (time > 0) {
time--;
document.getElementById("time").innerHTML = time;
return time;
}
else{
clearInterval(t);
play = false;
return;
}
}


Ok, so clock no longer needs to take any parameters. This also means that we can modify our setInterval call from this:

var t = setInterval(function() { clock(time, play);}, 1000);

to this:

var t = setInterval(clock, 1000);

Note, no parenthesis... we're passing the clock function reference to setInterval.

Ok, back in the clock function...

clearInterval(t);

Where was t defined? It was defined in the startClock function, outside of the scope of this clock function. In other words, t here is undefined. In order change that, t would need to be a global variable, which means removing the "var" from "var t = setInterval(clock, 1000);" in startClock, and preferably declaring var t; along with your global time and play variables.

One last note. Your clock function has 2 return lines, one that does return time, the other just returns. This function doesn't need to return anything, since nothing is acting on the return value. I would remove both of those lines to avoid any confusion.

Hope that helps.

Fotiman




msg:4449393
 1:48 pm on May 4, 2012 (gmt 0)

@birdbrain, you replace his nice HTML5 doctype with and HTML 4.01 doctype. Yuck. ;)

birdbrain




msg:4449399
 2:15 pm on May 4, 2012 (gmt 0)

Hi there Fotiman,

I have no objections to the use of HTML5 per se. ;)

I do believe, though, that those with poor coding methodology
will be better served if they first learn strict coding practice.

Of course, I may just be a closet pedant. :)

birdbrain

Fotiman




msg:4449412
 2:37 pm on May 4, 2012 (gmt 0)

Yes, but there is nothing about HTML 4.01 that is more or less strict than HTML5 with regards to coding practice.

I agree, though, strict coding practice is extremely valuable.

birdbrain




msg:4449441
 3:29 pm on May 4, 2012 (gmt 0)

Hi there cybernoob,

as our friend Fotiman has objected to my use of the HTML4 strict DOCTYPE,
I will post the code with the HTML5 DOCTYPE instead, just to be sure. ;)

<!DOCTYPE html>
<html lang="en">
<head>

<meta charset="utf-8">

<title>assignment 6</title>

<style>
body {
color:#000;
background-color:#fff;
}
a {
color:#00f;
}
a:visited {
color:#800080;
}
a:hover {
color:#008000;
}
a:active {
color:#f00;
}
#gameContainer {
width:50%;
height:200px;
border:1px solid #000;
margin:auto;
}
#button{
margin:5px 0 0 20%;
margin-top:5px;
float:left;
}
#statsBox {
padding:10px;
border:1px solid #000;
margin:5px 0 0 10%;
float:left;
}
#statsBox div {
margin:6px;
}
</style>

<script>

function clock(){

if(time>0){
time--;

if(time<10){
time='0'+time;
}
document.getElementById('time').innerHTML=time;
}
else {
clearTimeout(t);
play=false;
return;
}
t=setTimeout(function(){clock()},1000)
}

function buttonPress() {
alert('this is working OK');
}

function init(){

time=30;

document.getElementById('button').onclick=function() {
buttonPress();
}
document.getElementById('play').onclick=function() {
clock();
}
}
window.addEventListener?
window.addEventListener('load',init,false):
window.attachEvent('onload',init);
</script>

</head>
<body>

<div id="gameContainer">

<button id="button">Click Me!</button>

<div id="statsBox">
<div>Time:<span id="time">30</span></div>
<div>Score:<span id="score">0</span></div>
<div>High Score:<span id="highScore">0</span></div>
<div><button id="play">play!</button></div>
</div>

</div>

</body>
</html>

birdbrain

cybernoob




msg:4449521
 5:22 pm on May 4, 2012 (gmt 0)

thanks for all your help! though i have a question on some of the code you guys used...

(1)window.addEventListener?
(2)window.addEventListener('load',init,false):
(3)window.attachEvent('onload',init);


1.what does the question mark mean?

2 and 3. i understand that init is invoked once the document loads ie it would be the same as <body onload="init()"> which i have been taught to use(3) but im not sure what (2) means...

and thanks again, i couldnt believe how many responses ive gotten since this morning, and how detailed and helpful theyve been to help me become better with js!

Fotiman




msg:4449524
 5:34 pm on May 4, 2012 (gmt 0)

JavaScript has something known as the Conditional Operator [developer.mozilla.org] (aka, the Ternary Operator). The format is:
condition ? expr1 : expr2;

In the example above, window.addEventListener? is looking to see if addEventListener exists for the window object. If browsers have a window object that defines addEventListener, then this will evaluate to a truthy condition, whereby expr1 will be called (window.addEventListener('load',init,false)). Otherwise, expr2 will be called (window.attachEvent('onload',init)).

addEventListener is the "standards" way to add event listers, while attachEvent is IE specific (IE9 added support for addEventListener, but earlier versions used only attachEvent). In other words, if the browser support the standard addEventListeners, use it, otherwise (the browser is old IE), use attachEvent.

If you've been taught to use #3 only, you should complain to your teacher.

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / JavaScript and AJAX
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved