-1

doesnt stick to the topSticks to the topMy code only works if I include Javascript code in my HTML file using the <script> tags.

When I put my Javascript code outside of the HTML file in a separate javascript.js file it just refuses to work even though I'm sourcing it.

I could not find an answer to this please help.

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

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title></title>
  <link rel="stylesheet" href="stylesheet.css">
  <script src="javascript.js"></script> <!--Doesn't work if i put the code in this file-->
</head>

<body>

  <div class="header">
    <h2>Scroll Down</h2>
    <p>Scroll down to see the sticky effect.</p>
  </div>

  <div id="navbar">
    <a href="index.html">one</a>
    <a href="organisation.html">two</a>
    <a href="ongoing.html">three</a>
    <a href="reference.html">four</a>
    <a href="work.html">five</a>
    <a href="contact.html">six</a>
  </div>

  <div class="content">
    <h1>Fixed Top Menu</h1>
    <h2>The navigation bar will stay at the top of the page while scrolling</h2>
    <p>Some text some text some text some text..</p>
  </div>
  <script>
    //only works if i put it here
    window.onscroll = function() {
      myFunction()
    };

    var navbar = document.getElementById("navbar");
    var sticky = navbar.offsetTop;

    function myFunction() {
      if (window.pageYOffset >= sticky) {
        navbar.classList.add("sticky")
      } else {
        navbar.classList.remove("sticky");
      }
    }
  </script>
</body>

</html>
Ali
  • 29
  • 5
  • Could you please share your browser console? – Rajib karmaker Oct 02 '22 at 09:50
  • 1
    I'm assuming your browser console shows you the error `Cannot read properties of null (reading 'offsetTop')` in the line `var sticky = navbar.offsetTop;`. Your inline code runs _after_ the elements were created as the tag is positioned below, while your external script runs _before_ since you put it in the head area. This matters because you don't wait for the `DOMContentLoaded` event. – CherryDT Oct 02 '22 at 09:51
  • I tried moving it down under but it still doesnt work. I also tried the defer thing but that doesnt work either. – Ali Oct 02 '22 at 09:59
  • Have you both files in the same folder?? Try add full path in `src` or add `/javascript.js` – Dave Oct 02 '22 at 10:03
  • I do have in the same folder. I tried putting a / but still doesnt work. – Ali Oct 02 '22 at 10:05
  • Please show both versions, fully. – yossi Oct 02 '22 at 10:08

3 Answers3

1

I know this problem.

I think in your JS script has reference to html objects which will render only after script.

You should move js after html, and check correct path to your javascript file.

0

Using <script> tag in <head> executes Javascript first, even before implementing html. On your case, you may just move your <script> tag to bottom of <body> or use defer attribute to your script.

Abdulaziz0
  • 128
  • 5
0

It doesn't matter if you put an inline script or a script file reference in HTML, but the problem is from where/which place you put your script.

The HTML is executed from top to bottom, so when it tried to execute document.getElementById("navbar"), it cannot find navbar element because it came after the script. You can check that error by the below demo (click on show code snippet)

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

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title></title>
  <link rel="stylesheet" href="stylesheet.css">
  <script>
    //only works if i put it here
    window.onscroll = function() {
      myFunction()
    };

    var navbar = document.getElementById("navbar");
    var sticky = navbar.offsetTop;

    function myFunction() {
      if (window.pageYOffset >= sticky) {
        navbar.classList.add("sticky")
      } else {
        navbar.classList.remove("sticky");
      }
    }
  </script>
</head>

<body>

  <div class="header">
    <h2>Scroll Down</h2>
    <p>Scroll down to see the sticky effect.</p>
  </div>

  <div id="navbar">
    <a href="index.html">one</a>
    <a href="organisation.html">two</a>
    <a href="ongoing.html">three</a>
    <a href="reference.html">four</a>
    <a href="work.html">five</a>
    <a href="contact.html">six</a>
  </div>

  <div class="content">
    <h1>Fixed Top Menu</h1>
    <h2>The navigation bar will stay at the top of the page while scrolling</h2>
    <p>Some text some text some text some text..</p>
  </div>
</body>

</html>

If you want to make it runnable, you can place your inline script after HTML elements (like what you've done in your question's code), or you can place a script file like below

<body>
  All your other elements
  <script src="javascript.js"></script>
</body>

You also can use window.onload event to make sure all HTML elements are ready before any Javascript logic execution. That would help you to place your script anywhere

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

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title></title>
  <link rel="stylesheet" href="stylesheet.css">
  <script>
    //use window.onload to wrap your Javascript logic
    window.onload = function() {
      window.onscroll = function() {
        myFunction()
      };

      var navbar = document.getElementById("navbar");
      var sticky = navbar.offsetTop;

      function myFunction() {
        if (window.pageYOffset >= sticky) {
          navbar.classList.add("sticky")
        } else {
          navbar.classList.remove("sticky");
        }
      }
    }
  </script>
</head>

<body>

  <div class="header">
    <h2>Scroll Down</h2>
    <p>Scroll down to see the sticky effect.</p>
  </div>

  <div id="navbar">
    <a href="index.html">one</a>
    <a href="organisation.html">two</a>
    <a href="ongoing.html">three</a>
    <a href="reference.html">four</a>
    <a href="work.html">five</a>
    <a href="contact.html">six</a>
  </div>

  <div class="content">
    <h1>Fixed Top Menu</h1>
    <h2>The navigation bar will stay at the top of the page while scrolling</h2>
    <p>Some text some text some text some text..</p>
  </div>
</body>

</html>

Side note, I'd prefer you to place your script at the end of the HTML. Users will see the content first (HTML content) instead of waiting for Javascript loading, which makes them see a blank page for a while because it blocks content renderings from HTML elements.

Nick Vu
  • 14,512
  • 4
  • 21
  • 31