1

In the code below I assign the gobal variable "myDiv" a jQuery element. But then inside the "test()" function it seems the myDiv variable is declared but not defined. I have to reassign it $('myDiv') again before I can do anything with it.

The Bogus variable xyz seems to be reachable just fine though...

<!DOCTYPE html>
<htm>
<head>
<title>Javascript Test Code</title>
<script src="js/jquery-1.9.0.min.js"></script>
<script>

var App = App || (function () {

  var myDiv = $('#myDiv'), // define a global jQuery element variable.  
        xyz = 'xyz';       // and a bogus variable as a test.  

  function test()
  {
    console.log('running test...','myDiv is', myDiv); // length is 0
    console.log('xyz is ', xyz); // says xyz

    myDiv = $('#myDiv'); // after selecting with jQuery...

    console.log('running test...','myDiv is', myDiv); //length is 1
    console.log('xyz is ', xyz); // still says xyz
  }

  return {test:test} 

}());

$(function(){

  App.test();

});

</script>
</head>
<body>
<div id="myDiv"></div>
</body>
</html>
  • This has nothing to do with scoping, the variable exists and its value is correctly logged. For the issue, see the duplicate [Why does jQuery or a DOM method such as \`getElementById\` not find the element?](http://stackoverflow.com/questions/14028959/why-does-jquery-or-a-dom-method-such-as-getelementbyid-not-find-the-element) – Bergi Feb 21 '13 at 00:51

2 Answers2

2

There is no access to elements from the head of the document because nothing is rendered. This line

var App = App || (function () {

will execute the self executing function because App at that point is undefined.

Once the self executing function is ran, it will look for $('#myDiv') but since the element does not exist, it will not be found (this is always why you get a length of 0 for the elements array which matches the selector).

Later, when you attempt to access the App it will have already been built.

$(function(){
 App.test();
});

Which means that the call to App returns the already built App from the self executing function, with the values already stored from when it executed in the head of the document.

When you call the function test the state that was loaded is reflected. However, lower in the function you issue

myDiv = $('#myDiv'); // after selecting with jQuery...

once the page has already been loaded (since we are inside of the jquery ready callback already). This will find the element on the page since the DOM has already been rendered and update the value.

Travis J
  • 77,009
  • 39
  • 185
  • 250
  • Thanks for your answer. I added an init() function after my var statement to do global variable assignments. I have to explicitly call init() first before test() but I will avoid such problems in the future. – Thomas Orion Feb 21 '13 at 01:52
0

In your specific example code above, the initial myDiv is empty because when App is declared, the DOM has not fully loaded and so the length of #myDiv is correctly zero.

You should move the module to be run after the DOM has loaded, ie. move to the bottom of the script.

See example jsFiddle - your assignment is fine. http://jsfiddle.net/yWhbL/

Alex Osborn
  • 9,674
  • 3
  • 30
  • 44