0

I know it's possible to do this with php/jquery, but I haven't found a working vanilla javascript solution. I'm doing this in vanilla javascript mainly as a learning experience so please no php/jquery.

This is what I have, based off of this answer.

//load_essentials.js
document.getElementById("myNav").innerHTML =
 "<ul id='navLinks'>"
 + "<li><a href='index.html'>Home</a></li>"
 + "<li><a href='about.html'>About</a>"
 + "<li><a href='donate.html'>Donate</a></li>"
 + "</ul>";
<!--index.html-->
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title> NavBar </title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>

<body>
    <nav id="myNav"></nav>
    This is the content in the home page.
    <script src="load_essentials.js"></script>
</body>

</html>

and this is about.html:

<!--about.html-->
    <nav id="myNav"></nav>   
    <script src="load_essentials.js"></script>
    Hello World, this is my about me page!

The issue is when someone clicks the About link in the navbar in index.html, the navbar in about.html has no bootstrap styling (blue text), it's just a plain black unordered list. I could just copy and paste the <head></head> from index.html onto every page, but there has to be a better way to do this in vanilla javascript?

nodel
  • 471
  • 6
  • 22
  • It's generally best practice to not use javascript to dynamically load external stylesheets you need on every page. You should just include the `link` in the `head` on each page. Templating engines like [Pug](https://pugjs.org/api/getting-started.html) make this easy to manage across multiple pages. – Sean May 23 '19 at 18:40
  • Your javascript (load_essentials) seems to work - it is successfully adding the nav to the document. What's not working seems to be the stylesheet. Could you be specific about what styles you are expecting to see? @sean I am not seeing where they are using javascript to load external stylesheets. – AlexMA May 23 '19 at 18:42
  • @AlexMA Maybe I'm misreading the question. Also, you need the bootstrap classes on your `nav` element and its children in order for the bootstrap styling to apply. – Sean May 23 '19 at 18:52
  • The issue is when someone clicks the About link in the navbar in index.html, the navbar in about.html has no bootstrap styling (blue text), it's just a plain black unordered list. – nodel May 23 '19 at 19:20

3 Answers3

0

Don't use javascript to link a stylesheet. It is best if you link your stylesheet in your html file like so...

<link rel="stylesheet" type="text/css" href="yourname.css">

DerpyCoder
  • 127
  • 1
  • 6
0

In essentials.js do the following:

document.getElementById("myNav").innerHTML =
    `<ul id='navLinks'>
         <li><a href='index.html'>Home</a></li>
         <li><a href='about.html'>About</a>
         <li><a href='donate.html'>Donate</a></li>
    </ul>`;

document.querySelector("head").innerHTML += 
`
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<!-- you might want to add some other libraries to load here -->
`;

and load this into every page.

Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
0

Metadata Tags
Hopefully you are aware that each page is required to download certain files to use Bootstrap. Pay special attention of what and where each <link> and <style> and <script> tag is in the demo. It is essential that you are totally familiar with external files as well as the inline tags that are not part of the flow (invisible and doesn't affect layout).

HTML/CSS
90% of Bootstrap's layout and behavior is class oriented. You can safely assume that any tag in layout needs a BS class in order to style it. The htmlString provided in OP is void of any class so of course it's not going to appear as expected.

JavaScript
Although commonly used to render htmlString, .innerHTML has some drawbacks that are commonly overlooked. One major issue is that it rewrites everything within the targeted tag which takes unneeded processing and removal of any attached events. Use .insertAdjacentHTML() instead -- it doesn't destroy content plus the position in which the htmlString can be determined by the first parameter:

document.querySelector('.navbar').insertAdjacentHTML(position, htmlString)

/**@ Param: [position] "beforebegin" - in front of .navbar as next sibling
                       "afterbegin" - within .navbar as first child
                       "beforeend" - within .navbar as last child
                       "afterend" - behind .navbar as previous sibling
*/

Don't limit yourself with #id, there are other methods that can access a tag by .class, [attribute], and tag as well. Use .querySelector() to select a single tag by any CSS/jQuery selector.

   `<nav id='nav1' class='navbar' name='navigation'></nav>
  // by #id
  document.querySelector('#nav1')
  // by .class
  document.querySelector('.navbar')
  // by [attribute]
  document.querySelector('[name=navigator]')
  // by tag
  document.querySelector('nav')

In cases of multiple selectors (with the exception of #id in valid HTML), qS() will get the first one on the page. If you need to target a tag other than the first one you need to do one of the following with qS() (ex. to access the second nav tag):

  • add a different attribute (.class is recommended) manually or dynamically

  • change the selector

    document.querySelector("nav:nth-of-type(2)")

  • use a DOM property

    document.querySelector('ul').parentElement

  • use .querySelectorAll() to collect all nav tags into a NodeList

    var navs = document.querySelector('nav') then navs[1]

Demo

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

<head>
  <meta charset="UTF-8">
  <title> NavBar </title>
  <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
  <style>
    /* extra styles may be added here */
  </style>
</head>

<body>

  <nav class="navbar navbar-expand-sm bg-dark"></nav>

  <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.0/jquery.min.js'></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>

  <script>
    document.querySelector(".navbar").insertAdjacentHTML('beforeend', `<ul class='navbar-nav'>
<li class="nav-item">
  <a class='nav-link' href='index.html'>Home</a>
</li>
<li class="nav-item">
  <a class='nav-link' href='about.html'>About</a>
</li>
<li class="nav-item">
  <a class='nav-link' href='donate.html'>Donate</a>
</li>
</ul>`);
  </script>

</body>

</html>
zer00ne
  • 41,936
  • 6
  • 41
  • 68
  • how is about.html supposed to look? – nodel May 23 '19 at 22:10
  • when I click the link to about.html, the about.html page doesn't have the navbar. I'm just confused how to keep the navbar on multiple pages – nodel May 23 '19 at 22:16
  • `about.html` is an entirely different page use the same code on each page. This can be automated server-side but that is beyond the scope of this vague misleading question. – zer00ne May 23 '19 at 22:19
  • I don't see how it's vague/misleading. The title says "navbar on every page". And I discuss the issue when clicking about.html. – nodel May 23 '19 at 22:34
  • The code provided in OP has nothing to do with going to another page. The JavaScript merey creates the children of a nav with no styles. If you were to run that code on any page there would be no styling whatsoever. You need to load everything that was mentioned in this answer onto each page so that you'll have a fully functional and fully styled Bootstrap page. The real point here is along with these needed files you need to add the BS classes to every tag in the `` (except ` – zer00ne May 23 '19 at 22:44
  • If you are asking how to generate the same navbar in each page without hardcoding it into each page manually then you have a [xy problem](http://xyproblem.info) – zer00ne May 23 '19 at 22:52