7

I have written the code for a simple function inline, but when i created a separate js.file it doesn't want to work for some reason. I've tried everything it feels like, but maybe my tired eyes can't something!

<!DOCTYPE html>

<html>
  <head>
    <title>Test</title>
    <script type="text/javascript" src="menu.js"></script>
  </head>
 <body>
<div class="container">
  <button name="one">Button 1</button>
  <p>
    Lorem ipsum dolor sit amet
  </p>

</div>
<div class="container">
  <button name="two">Button 2</button>
  <p>
    Lorem ipsum dolor sit amet
  </p>

</div>
<div class="container">
  <button name="three">Button 3</button>
  <p>
    Lorem ipsum dolor sit amet
  </p>
</div>

The idea is to have three buttons that when you click on one of them only one of the divs will be shown, and the other two will be hidden.

Here is the JavaScript (that worked perfectly fine inline):

var first_container = document.querySelectorAll(' div:not(:first-child) p');

for (var i = 0; i < first_container.length; i++) {
  first_container[i].style.visibility = 'hidden';
}
var buttons = document.querySelectorAll('button');

for (var i = 0; i < buttons.length; i++) {
  buttons[i].addEventListener('click', clickHandler);
}

function clickHandler(e) {

  e.preventDefault();

  var text = document.querySelectorAll('p');

  for (var i = 0; i < text.length; i++) {

      if (text[i] === event.target.nextElementSibling) {
          text[i].style.visibility = 'visible';

      } else {
          text[i].style.visibility = 'hidden';
      }
  }
}
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
asso
  • 73
  • 1
  • 1
  • 3
  • 1
    Did you include the javascript – Jochen van Wylick Feb 06 '15 at 08:28
  • I assume the js code is in file `menu.js`. Right? Does it get loaded correctly? – rubikonx9 Feb 06 '15 at 08:29
  • When you had the javascript inline, did it live somewhere at the bottom, just before the `

    ` tag? It seems to rely on the DOM having been loaded.

    – Roy Prins Feb 06 '15 at 08:29
  • If you use the developers console, or firebug, and search the `menu.js` file, in your code, it's the js okay? Or it's missing? Maybe there is a problem with the route to the file. – Kangcor Feb 06 '15 at 08:29

3 Answers3

13

When you put the script in an external file and then load that external script from the <head>, it loads BEFORE the DOM is ready. That means that if your script tries to reference elements in the page like you are with document.querySelectorAll(), those elements will not exist yet.

The simpleset way to fix that is to simply move the script tag:

<script type="text/javascript" src="menu.js"></script>

to right before </body>. Then, all the elements of the page will be parsed and in the DOM before your script runs like this:

<!DOCTYPE html>

<html>
  <head>
    <title>Test</title>
  </head>
 <body>
<div class="container">
  <button name="one">Button 1</button>
  <p>
    Lorem ipsum dolor sit amet
  </p>

</div>
<div class="container">
  <button name="two">Button 2</button>
  <p>
    Lorem ipsum dolor sit amet
  </p>

</div>
<div class="container">
  <button name="three">Button 3</button>
  <p>
    Lorem ipsum dolor sit amet
  </p>
</div>
<script type="text/javascript" src="menu.js"></script>
</body>
</html>

Alternately, you can use a script that will notify you when the DOM is ready and you can then call your code.

See this reference and highly voted answer for a plain Javascript and cross browser way of waiting until the DOM is ready if you'd rather keep your code in the <head> section or make it so you code can be located anywhere.

Community
  • 1
  • 1
jfriend00
  • 683,504
  • 96
  • 985
  • 979
1

Try onload() event of javascript. It happens because when you are adding your script inside the <head>..</head> your script starts working immediately before the web page is even loaded. So to handle this you need to make sure that your script starts working after the page has been completely loaded. And for that write your javascript code or function that you need to make work after complete page load inside window.onload = function(){ //here your code goes };

Update your menu.js file as follows :

javascript : menu.js

window.onload = function(){
    // your javascript code goes here...
};

References : onload()

Md Ashaduzzaman
  • 4,032
  • 2
  • 18
  • 34
0

When you moved the script from being inline to being external you also moved the script tag to the <head>.

Now the script runs before any element that matches div:not(:first-child) p exists so first_container doesn't have any elements in it.

Move the script element back to where it was before.

Alternatively, move the code you have into a function and then run that function after the document has loaded (e.g. with addEventListener('load', your_function)).

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335