0

I have had this issue before on another project. When I include my variables in a function with local scope, the function is able to run. When I put the variable outside of function with global scope, the function does not interpret the variables and does not run. I've tried passing the global variables into my functions and it does not run.

This example is a snippet of a countdown timer I was working on:

LOCAL SCOPE (FUNCTION RUNS) http://jsbin.com/leyicubegu/2/edit

function addTime() {

     var userTime = timeInput.value;
     var timeString = userTime.toString();
     var timeArray = timeString.split("");
     var hundrethsValue = timeArray[6].concat(timeArray[7]);
     var secondsValue = timeArray[3].concat(timeArray[4]);
     var minutesValue = timeArray[0].concat(timeArray[1]);

     var hundreths = hundrethsValue;
     var seconds = secondsValue;
     var minutes = minutesValue;    

document.getElementById("time").innerHTML = minutes + ":" + seconds + ":" + hundreths;

}

GLOBAL SCOPE (FUNCTION DOES NOT RUN) http://jsbin.com/fuxexajozu/2/edit

var userTime = timeInput.value;
var timeString = userTime.toString();
var timeArray = timeString.split("");
var hundrethsValue = timeArray[6].concat( timeArray[7]);
var secondsValue = timeArray[3].concat(timeArray[4]);
var minutesValue = timeArray[0].concat(timeArray[1]);

var hundreths = hundrethsValue;
var seconds = secondsValue;
var minutes = minutesValue;  


function addTime() {

document.getElementById("time").innerHTML = minutes + ":" + seconds + ":" + hundreths;

}

PASSING VARIABLES TO FUNCTION (GLOBAL SCOPE) - (FUNCTION DOES NOT RUN)

var userTime = timeInput.value;
var timeString = userTime.toString();
var timeArray = timeString.split("");
var hundrethsValue = timeArray[6].concat( timeArray[7]);
var secondsValue = timeArray[3].concat(timeArray[4]);
var minutesValue = timeArray[0].concat(timeArray[1]);

var hundreths = hundrethsValue;
var seconds = secondsValue;
var minutes = minutesValue;  


function addTime(minutes, seconds, hundreths) {


document.getElementById("time").innerHTML = minutes + ":" + seconds + ":" + hundreths;

}

*note: the running function only runs in jsbin, not jsfiddle

I can't identify why the the variables only run with a local scope. I would like them to run with global scope so that I can use them in multiple functions. Please provide any input. I am new to this so my knowledge of scopes is limited.

HTML (if needed)

<input id="timeInput" name="timeInput" type="text " length="20">

<h1><div id="time">00:00:00</div></h1>

<div id="result"></div>

<button onclick=addTime(); >Submit</button>

<button id="start" onclick = startClock();>Start</button>

<button id="stop" onclick="stopTimer();">Stop</button>

<button id="clear" onclick="resetTimer();">Reset</button>
  • 1
    seriously, make them work as they were in local functions, and use proper DOM3 `addEventListener` calls to register them instead of inline DOM0 event handlers. Those are how we wrote JS code in the '90s. – Alnitak Mar 28 '15 at 22:15
  • Thanks for your input @Alnitak. As I mentioned I am new to this and have not gotten that far. –  Mar 28 '15 at 22:18
  • jsbin/jsfiddle links would be helpful. – Shomz Mar 28 '15 at 22:20

2 Answers2

0

I suppose that

LOCAL SCOPE (FUNCTION RUNS)

All values are being got on click so every local variable has actual values.

GLOBAL SCOPE

All variables are defined on page load and have empty values. These variables stay the same the whole page life. And each click on Submit reads the same (old) values every timeю

Anyway avoid using global variables. They will make your life worse in future.

In your case I cannot see the reason to use these global variables at all because they should have actual values on button click.

So as @Alnitak suggested it's much better to move event handler definitions from HTML page to JS files and use local variables:

document.getElementById("mySubmitButton").onclick = function addTime() {
     var userTime = timeInput.value;
     var timeString = userTime.toString();
     ...
     document.getElementById("time").innerHTML = minutes + ":" + seconds + ":" + hundreths;
}
phts
  • 3,889
  • 1
  • 19
  • 31
  • thank you. i've switch it so that all the onclick functions are called inside of the JS. –  Mar 28 '15 at 22:46
0

Two issues:


Variable value: is userTime really what you expect it to be?

The first issue is that you read off the input value as soon as the page loads and the input field is empty, of course. You always need to have most up-to-date value there, so you should definitely read the input when the addTime function is called.

If you wish, you can still keep variables global, but you have to read the input when needed.


Accessing element values - risky business!

The second issue will explain why your code works in some online environments and not in others and is something you should generally avoid. It's this line:

var userTime = timeInput.value;

This part: timeInput.value depends on the browser and the scope context. By the browser I mean each browser's JS implementation - most of them will work as expected and pack names elements as scope context properties (unless they're taken, of course). Usually, that's the window object, but it doesn't have to be. Always do something like this instead:

var userTime = document.getElementById('timeInput').value;

There are some nice answers about this specific issue here: Do DOM tree elements with ids become global variables?.


Another thing to watch out for is quoting HTML element attribute values. Here, for example:

<button onclick=addTime(); >

Always quote the values, because you might encounter weird issues if you don't (if there are spaces, etc.), and it might be hard to debug. So, the right way would be:

<button onclick="addTime();" >

Or even better, you'd assign the click listener from the JS, and not in the HTML markup, using addEventListener, like this:

<button id="timeButton">

var timeButton = document.getElementById('timeButton');
timeButton.addEventListener('click', addTime);
Community
  • 1
  • 1
Shomz
  • 37,421
  • 4
  • 57
  • 85
  • 1
    wow...looks like there was a lot i missed. thanks for pointing out the errors –  Mar 29 '15 at 05:05