-2

I want to have one navigation bar/menu for all my web pages.

I found one solution for that problem (one menu/navbar for alla web pages). Someone had the same problem her, and I used one member’s answer that worked just fine. The solution was to make a javascript imbedded code. The problem is that I don't know how to make a submenu in javascript. I have tried but not succeeded. Can someone tell me how to modify the javascript code? I would be very happy if someone could help me. I used the following code:

script.js

 document.getElementById("navMenu").innerHTML =
 '<ul>'+
  '<li><a href="index.html">Home</a></li>'+
  '<li><a href="services.html">Services</a></li>'+
  '<li><a href="about.html">About</a></li>'+
 '</ul>';

index.html

 <body>
  <nav id="navMenu"></nav>
  <div> rest of web page body here </div>
  <script src="script.js"></script>
 </body>

about.html

 <body>
  <nav id="navMenu"></nav>
  <div> rest of web page body here </div>
  <script src="script.js"></script>
 </body>
Buzinas
  • 11,597
  • 2
  • 36
  • 58
question
  • 19
  • 5
  • 2
    You should not build your menu in JS. You should try to keep your site accessible and symantic. Build your menu using HTML – Jackson Sep 26 '15 at 20:53
  • But I don’t want to change “hundreds” of pages when changing the navbar/menu! I want to have one menu for all my pages on the site. And that one modification on the navbar should change all my pages. Do you have a better solution? – question Sep 26 '15 at 21:06
  • I found the solution I used on this page: http://stackoverflow.com/questions/15445430/how-can-i-make-my-navi-bar-the-same-across-my-html That’s the reason I used the js code. – question Sep 27 '15 at 00:56

2 Answers2

0

I don't really approve the way you're doing it, since you should be doing that on the server.

But you can simply add other ul tags inside the li tags that you want to be a submenu. E.g:

var nav = document.getElementById("navMenu");
nav.innerHTML =
  '<ul>' +
    '<li><a href="index.html">Home</a></li>' +
    '<li>' +
      '<a href="#">Services</a>' +
      '<ul>' +
        '<li><a href="simple-service.html">Simple Service</a></li>' +
        '<li><a href="regular-service.html">Regular Service</a></li>' +
        '<li><a href="hard-service.html">Hard Service</a></li>' +
      '</ul>' +
    '</li>' +
    '<li><a href="about.html">About</a></li>' +
  '</ul>';

var anchors = nav.querySelectorAll('a');

for (var i = 0; i < anchors.length; i++) {
  if (anchors[i].getAttribute('href') === '#') {
    anchors[i].nextElementSibling.style.display = 'none';
    anchors[i].addEventListener('click', function(e) {
      e.preventDefault();
      this.nextElementSibling.style.display = this.nextElementSibling.style.display.toLowerCase() === 'none' ? 'block' : 'none';
    });
  }
}
      
<nav id="navMenu"></nav>
Buzinas
  • 11,597
  • 2
  • 36
  • 58
  • Thanks Buzinas, I will try and see if it works. But why is it att bad solution to executing the code for the menu in the browser (using js) instead of doing it on the server as you prefer? How woudl you do it instead if you want one navbar for all pages? – question Sep 26 '15 at 21:29
  • @question The best way is by using some server technology, for example [Node.js](https://nodejs.org/), or PHP, ASP.NET, Ruby on Rails, Python etc. But if you don't want to / can't do that for some reason, you can at least use regular HTML, and load the views the way you are, but via [XHR](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest). Take a look at [this plunker I've created for you](http://plnkr.co/edit/T8HzbLfq1OTTUjnr1Guy?p=preview). – Buzinas Sep 26 '15 at 21:51
  • If I understand it right, is the difference that a "server technology" then the code (in this case, the menu) is executed on the server instead of in the browser as the current solution I am using? And why is it a bad solution? It's not that I don’t want to do it, it’s that I don't know how to do it. I also want to have an easy and non complicated solution. And another question regarding plunker that you so kindly created for me. What’s the difference with that solution and the one that I am now using now (the first js code in my question)? Sorry for my lack of knowledge. Thanks! – question Sep 26 '15 at 22:28
  • The difference is that the server can handle parts separetely, using `include` or `master page` etc. Other benefits is that you can cache those parts, and render much faster. The main benefit is SEO, since the search crawlers won't understand rightly when you render stuff client-side. Other benefit is that you can make friendly URLs to your visitor, e.g `/about` instead of `/about.html` etc. Now, talking about the plunker version instead of yours, the only reason is maintainability, since it's too hard to maintain string interpolation code. The more complex gets your HTML, harder to maintain. – Buzinas Sep 26 '15 at 23:49
  • @question And please, if my answer was useful for you, mark it as the accepted one by clicking on the `V`, and upvote it by clicking on the arrow. Thank you! :) – Buzinas Sep 26 '15 at 23:50
  • Oki. Thanks! The code above where you added the ul tags inside the li tag. (I still have som problem, must be doing something wrong ... don't know what) Because now I get three rows in the menu under each other. How should I do if I want that submenu to function as a dropdown menu? How and where do I configure that? – question Sep 27 '15 at 00:02
  • @question I've edited my answer with the code that will add this behavior. Now, I'm done. If you need anything else, take a look at [Bootstrap](http://getbootstrap.com/), they have a great menu. – Buzinas Sep 27 '15 at 05:07
0

The code you have will create the HTML elements dynamically as you suspect. Your problem, though you haven't actually described a problem, is likely that your js file is attempting to access the DOM elements before the DOM is finished loading. And easy check to see if this is what's happening is to store the results of getElementById and examine them, before you set the innerHTML, so:

var theNav = document.getElementById("navMenu");
//this will mostly likely console log as theNav being undefined
console.log("the nav element", theNav);

The solution is to run your js code only after the DOM is finished loading, by running your code inside of a function assigned to window.onload:

window.onload = function(){
  //do code in here that requires interaction with the DOM
  //because you can guarantee that the DOM elements, like nav, are loaded
}
Cooper Buckingham
  • 2,503
  • 2
  • 15
  • 23
  • Tanks for trying to explain, unfortunately this is above my head. I’m way to new to this to understand. I really don’t know what the "DOM" is. And I don’t know what you mean with “window.onload” Sorry..., can you try to explain it for a newbie? My problem is that I don't know how to create a submenu in js. I'm on a learing curve. :) – question Sep 26 '15 at 21:51