0

I am trying to implement this bit of code to enable a sticky nav bar on my website: https://www.w3schools.com/howto/howto_js_navbar_sticky.asp

I keep getting the following error: "index.html:44 Uncaught TypeError: Cannot read property 'remove' of undefined"

Here is the snippet:


<body class="is-preload">
        <div class="topnav">
            <a class="active" href="#header">Home</a>
            <a href="#first">Book an Appointment</a>
            <a href="#second">Contact</a>
            <a href="#third">About</a>
            
          </div>
          <script>// When the user scrolls the page, execute myFunction
            
            
            
            
            window.onscroll = function() {myFunction()};
            // Get the navbar
            var navbar = document.getElementsByClassName("topnav");
            
            
            
            
            // Get the offset position of the navbar
            var sticky = navbar.offsetTop;
            
            
            // Add the sticky class to the navbar when you reach its scroll position. Remove "sticky" when you leave the scroll position
            function myFunction() {
              if (window.pageYOffset >= sticky) {
                navbar.classList.add("sticky")
              } else {
                navbar.classList.remove("sticky");
               
              }
            }</script>

I cant figure out for the life of me whats wrong. Its the exact bit of code from the W3C site and it wrks fine there.

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
aloescript
  • 11
  • 1
  • w3schools.com and w3c have nothing to do with another. – Heretic Monkey Jan 21 '21 at 03:15
  • Does this answer your question? [What do querySelectorAll and getElementsBy\* methods return?](https://stackoverflow.com/questions/10693845/what-do-queryselectorall-and-getelementsby-methods-return) – Heretic Monkey Jan 21 '21 at 03:16
  • `navbar` is a collection of elements. Loop through them or get the first one. – Heretic Monkey Jan 21 '21 at 03:17
  • `getElementsByClassName()` returns an array (collection). It's the source of the "undefined" and thus `.remove()` and `.classList()` are not methods of it. – GetSet Jan 21 '21 at 03:18

3 Answers3

1

From glancing at it, it would appear to be because the following part returns an array and you are treating it as an element:

var navbar = document.getElementsByClassName("topnav");

What you are getting is actually an array with the navbar as its first element. Change it to the following and hopefully it should work:

var navbar = document.getElementsByClassName("topnav")[0];
dev
  • 818
  • 8
  • 14
  • I see. So by indexing the elements in the array I can then get the remove() method to work. Its stopped pulling up an error but now the nav bar has disappeared entirely. – aloescript Jan 22 '21 at 04:20
1

Your getElementsByClassName will return an array of elements and not a single element, so you want to use

document.getElementsByClassName("topnav")[0];

If you only have one element in that class, or you can just switch to an ID as well

Da Mahdi03
  • 1,468
  • 1
  • 9
  • 18
1

You need the sticky navbar. Just use querySelector instead of getElementsByClassName like as below:

var navbar = document.querySelector(".topnav");