0

I've used Google's material icons in a navbar and used the following javascript to switch between div's when the icons are clicked. But, for some reason, when I first go into the webpage, all the div's are showing, instead of only the one that is currently being viewed. The javascript switching is working, but I don't know why at first everything shows. Is it because I need to change their display to none? To view it all go to https://tafc.glitch.me/content.html

var page = document.getElementsByClassName("page");
function switchTo(index) {
  for (var i = 0; i < page.length; i++) {
    page[i].style.display = "none";
  }

  page[index - 1].style.display = "block";
  window.scroll(0, 0);
}
switchTo(1);
* {
  margin: 0;
  padding: 0;
  text-decoration: none;
}

@keyframes slidein {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(0%);
  }
}

@keyframes fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

body {
  background-color: darkcyan;
}

nav header {
  background: linear-gradient(45deg, rgb(255, 17, 0), rgb(255, 200, 5));
  padding: 11px;
  height: 44px;
}

nav header a {
  text-decoration: none;
  color: midnightblue;
  font-size: 33px;
  margin: 5.5%;
}

.title {
  color: firebrick;
  font-family: serif;
  font-style: normal;
  font-weight: bold;
  font-size: 75px;
  font-variant: small-caps;
  line-height: 105%;
  padding-left: 12.5px;
  animation: slidein 2s;
}

h2 {
  color: gold;
  font-family: serif;
  font-style: normal;
  font-size: 30px;
  font-variant: small-caps;
  padding-left: 12.5px;
  animation: slidein 2s;
}

img {
  display: block;
  float: right;
  width: 30%;
  height: 30%;
  padding-right: 12.5px;
}

.page {
  animation: fade 2s;
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link
      rel="icon"
      href="https://cdn.glitch.com/8a4e3a34-26d3-443f-8e6c-ea2607c91f8c%2FAvatar%20on%20ice-32.png?v=1628529343716"
    />

    <title>The TAFC Website</title>

    <script src="/script.js"></script>

    <link rel="stylesheet" href="/style.css" />

    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link
      rel="stylesheet"
      href="https://fonts.googleapis.com/icon?family=Material+Icons"
    />
    <link
      rel="stylesheet"
      href="https://fonts.googleapis.com/css2?family=Raleway:ital,wght@0,800;1,500&display=swap"
    />
    <link
      rel="stylesheet"
      href="https://fonts.googleapis.com/css2?family=Lato&display=swap"
    />
  </head>

  <body>
    <nav>
      <header>
        <a href="javascript:switchTo(1);"><i class="material-icons">home</i></a>
        <a href="javascript:switchTo(2);"
          ><i class="material-icons">local_fire_department</i></a
        >
        <a href="javascript:switchTo(3);"><i class="material-icons">air</i></a>
        <a href="javascript:switchTo(4);"
          ><i class="material-icons">water</i></a
        >
        <a href="javascript:switchTo(5);"
          ><i class="material-icons">terrain</i></a
        >
        <a href="javascript:switchTo(6);"
          ><i class="material-icons">shopping_cart</i></a
        >
        <a href="javascript:switchTo(7);"><i class="material-icons">info</i></a>
        <a href="javascript:switchTo(8);"
          ><i class="material-icons">copyright</i></a
        >
      </header>
    </nav>
    <div class="page">
      <h1 class="title">
        The TAFC Website
      </h1>
      <h2>
        Welcome to the Homepage of the Team Avatar Fan Club!
      </h2>
      <img
        src="https://cdn.glitch.com/8a4e3a34-26d3-443f-8e6c-ea2607c91f8c%2FIMG_1854.PNG?v=1628338275471"
        alt="Avatar the Last Airbender and The Legend of Korra element symbols."
      />
    </div>
    <div class="page">
      <h1 class="title">
        The Element of Fire
      </h1>
    </div>
    <div class="page">
      <h1 class="title">
        The Element of Air
      </h1>
    </div>
    <div class="page">
      <h1 class="title">
        The Element of Water
      </h1>
    </div>
    <div class="page">
      <h1 class="title">
        The Element of Earth
      </h1>
    </div>
    <div class="page">
      <h1 class="title">
        Merchandise Shop
      </h1>
    </div>
    <div class="page">
      <h1 class="title">
        About TAFC
      </h1>
    </div>
    <div class="page">
      <h1 class="title">
        Copyright Information
      </h1>
    </div>
  </body>
</html>
Godzilla
  • 1
  • 3
  • `var page = document.getElementsByClassName("page");` you don't have any elements with `class="page"`, so `page[(index - 1)]` is undefined – WOUNDEDStevenJones Aug 10 '21 at 21:57
  • I do, I just didn't show it - I have seven div tags under the class page. It works, but at first everything shows. – Godzilla Aug 11 '21 at 15:26
  • 1
    Then please edit your question to include a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) (i.e. make the code snippet on SO behave as similarly as possible to the actual problem you're experiencing). Otherwise, trying to debug via SO won't be very efficient or beneficial. – WOUNDEDStevenJones Aug 11 '21 at 15:39
  • I just wanted to show you the syntax error that comes up on the console: "TypeError: Cannot read property 'style' of undefined at swtichTo (/script.js:7:19) at /script.js:10:1" – Godzilla Aug 12 '21 at 13:12

1 Answers1

0

In order to trigger javascript on click, you want to use the onclick attribute, not href:

<a href="#" onclick="javascript:switchTo(1);">Home</a>

See Which "href" value should I use for JavaScript links, "#" or "javascript:void(0)"? for more discussion about this.

var page = document.getElementsByClassName("page");
function switchTo(index) {
  for (var i = 0; i < page.length; i++) {
    page[i].style.display = "none";
  }

  page[index - 1].style.display = "block";
  window.scroll(0, 0);
}
switchTo(1);
* {
  margin: 0;
  padding: 0;
  text-decoration: none;
}

@keyframes slidein {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(0%);
  }
}

@keyframes fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

body {
  background-color: darkcyan;
}

nav header {
  background: linear-gradient(45deg, rgb(255, 17, 0), rgb(255, 200, 5));
  padding: 11px;
  height: 44px;
}

nav header a {
  text-decoration: none;
  color: midnightblue;
  font-size: 33px;
  margin: 5.5%;
}

.title {
  color: firebrick;
  font-family: serif;
  font-style: normal;
  font-weight: bold;
  font-size: 75px;
  font-variant: small-caps;
  line-height: 105%;
  padding-left: 12.5px;
  animation: slidein 2s;
}

h2 {
  color: gold;
  font-family: serif;
  font-style: normal;
  font-size: 30px;
  font-variant: small-caps;
  padding-left: 12.5px;
  animation: slidein 2s;
}

img {
  display: block;
  float: right;
  width: 30%;
  height: 30%;
  padding-right: 12.5px;
}

.page {
  animation: fade 2s;
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link
      rel="icon"
      href="https://cdn.glitch.com/8a4e3a34-26d3-443f-8e6c-ea2607c91f8c%2FAvatar%20on%20ice-32.png?v=1628529343716"
    />

    <title>The TAFC Website</title>

    <script src="/script.js"></script>

    <link rel="stylesheet" href="/style.css" />

    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link
      rel="stylesheet"
      href="https://fonts.googleapis.com/icon?family=Material+Icons"
    />
    <link
      rel="stylesheet"
      href="https://fonts.googleapis.com/css2?family=Raleway:ital,wght@0,800;1,500&display=swap"
    />
    <link
      rel="stylesheet"
      href="https://fonts.googleapis.com/css2?family=Lato&display=swap"
    />
  </head>

  <body>
    <nav>
      <header>
        <a href="#" onclick="javascript:switchTo(1);"><i class="material-icons">home</i></a>
        <a href="#" onclick="javascript:switchTo(2);"
          ><i class="material-icons">local_fire_department</i></a
        >
        <a href="#" onclick="javascript:switchTo(3);"><i class="material-icons">air</i></a>
        <a href="#" onclick="javascript:switchTo(4);"
          ><i class="material-icons">water</i></a
        >
        <a href="#" onclick="javascript:switchTo(5);"
          ><i class="material-icons">terrain</i></a
        >
        <a href="#" onclick="javascript:switchTo(6);"
          ><i class="material-icons">shopping_cart</i></a
        >
        <a href="#" onclick="javascript:switchTo(7);"><i class="material-icons">info</i></a>
        <a href="#" onclick="javascript:switchTo(8);"
          ><i class="material-icons">copyright</i></a
        >
      </header>
    </nav>
    <div class="page">
      <h1 class="title">
        The TAFC Website
      </h1>
      <h2>
        Welcome to the Homepage of the Team Avatar Fan Club!
      </h2>
      <img
        src="https://cdn.glitch.com/8a4e3a34-26d3-443f-8e6c-ea2607c91f8c%2FIMG_1854.PNG?v=1628338275471"
        alt="Avatar the Last Airbender and The Legend of Korra element symbols."
      />
    </div>
    <div class="page">
      <h1 class="title">
        The Element of Fire
      </h1>
    </div>
    <div class="page">
      <h1 class="title">
        The Element of Air
      </h1>
    </div>
    <div class="page">
      <h1 class="title">
        The Element of Water
      </h1>
    </div>
    <div class="page">
      <h1 class="title">
        The Element of Earth
      </h1>
    </div>
    <div class="page">
      <h1 class="title">
        Merchandise Shop
      </h1>
    </div>
    <div class="page">
      <h1 class="title">
        About TAFC
      </h1>
    </div>
    <div class="page">
      <h1 class="title">
        Copyright Information
      </h1>
    </div>
  </body>
</html>

Edit: update after some discussion and discovering the real issue, <script src="/script.js"></script> should be removed from the <head> and moved to the bottom of your HTML like:

    <div class="page">
      <h1 class="title">
        Copyright Information
      </h1>
    </div>

    <script src="/script.js"></script>
  </body>
</html>

See Why put JavaScript in the footer of a page? for more info.

WOUNDEDStevenJones
  • 5,150
  • 6
  • 41
  • 53
  • Sorry, but this didn’t work. It’s not a problem with the menu switching, but at first all of the dives show—I think it is a display problem. – Godzilla Aug 13 '21 at 23:01
  • If you click the blue "Run code snippet" button on my answer it works as expected, right? Even in your question it seems to work on page load (but not on subsequent nav links, which is what this answer fixes). Can you confirm that the code in your question matches the code you're using? – WOUNDEDStevenJones Aug 14 '21 at 03:39
  • It has to, because I pasted it into the question from my actual code. – Godzilla Aug 15 '21 at 15:39
  • My point is that the code that you posted on your question seems to work on page load in the Stack Snippet, so something isn't lining up with between your environment and your SO question. I believe it's because you're loading `script.js` in the head, and it's not wrapped in a `document ready` event. The easy fix is to move `` just before `

    `. Currently, when your script tries to execute, the target HTML nodes aren't in the DOM yet, so your script can't find any `pages` classes. By putting the script at the bottom, those nodes should be selectable.

    – WOUNDEDStevenJones Aug 16 '21 at 03:11
  • The JavaScript is it’s own file though. – Godzilla Aug 17 '21 at 18:49
  • I see that, but by default a script is executed in the order that it's loaded in the DOM. So when it's included it in the head, it tries executing before the rest of your HTML is loaded. So by moving it to the end of your HTML, the DOM nodes will exist and will be selectable by your JS script. See https://stackoverflow.com/questions/16391348/why-put-javascript-in-the-footer-of-a-page for more info. – WOUNDEDStevenJones Aug 17 '21 at 20:37