1

I wrote code on JavaScript, it suppose to give class "active" to the sidebar when clicking on the hamburger menu, but it isn't. It says that "hamburger is not defined or it's not a function". I checked everything I could but could not find the answer.

Here is the HTML code:

const hamburger = document.getElementsByClassName(".hamburger");
const sidebar = document.getElementsByClassName(".sidebar");

hamburger.addEventListener('click', () => {
  sidebar.classList.add("active");
})
.main-page {
  width: 100%;
  height: 100vh;
  background-color: #000;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.main-page__inner {
  width: 100%;
  max-width: 1350px;
  margin: 0 auto;
}

.main-page__title {
  font-family: 'Syncopate';
  font-style: normal;
  font-weight: 700;
  font-size: 100px;
  line-height: 104px;
  color: #FFFFFF;
}

.hamburger {
  position: absolute;
  width: 40px;
  top: 69px;
  left: 41px;
  z-index: 9999;
  padding: 15px 0;
  cursor: pointer;
}

.hamburger__item {
  width: 100%;
  display: block;
  height: 4px;
  background-color: #fff;
  position: absolute;
  inset: 0;
  margin: 0 auto;
}

.hamburger__item:before,
.hamburger__item:after {
  width: 100%;
  height: 4px;
  position: absolute;
  content: "";
  background-color: #fff;
  left: 0;
  z-index: 9999;
}

.hamburger__item:before {
  top: -7px;
}

.hamburger__item:after {
  bottom: -8px;
}

.sidebar {
  position: fixed;
  top: 0;
  left: -100%;
  bottom: 0;
  z-index: 600;
  background: #591753;
  width: 100%;
  max-width: 400px;
  height: 100vh;
  visibility: hidden;
}

.sidebar.open {
  visibility: visible;
  left: 0;
}

.sidebar__inner {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: auto 0;
}

.sidebar__title {
  font-family: 'Montserrat';
  font-weight: 400;
  font-size: 20px;
  color: #fff;
}
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&family=Montserrat:wght@400;600&family=Open+Sans:wght@300;400;500;600;700;800&family=Raleway:wght@100;200;300;400;500;600;700;800;900&family=Source+Sans+Pro:wght@600&family=Syncopate:wght@400;700&display=swap"
  rel="stylesheet">
<header class="header">
  <div class="container">
    <div class="header__inner">
      <div class="nav-bar">
        <img class="logo" src="/assets/Header/LOGO.png" alt="logo">
        <a class="click-to-action" href="#">Оставить заявку</a>
      </div>
    </div>
  </div>
</header>

<div class="hamburger" id="hamburger">
  <span class="hamburger__item" id="hamburger__item"></span>
</div>

<div class="sidebar" id="sidebar">
  <div class="sidebar__inner">
    <h1 class="sidebar__title">BLA BLA BLA</h1>
  </div>
</div>

<div class="main-page">
  <div class="container">
    <div class="main-page__inner">
      <h1 class="main-page__title">CHAMPION ASTANA</h1>
    </div>
  </div>
</div>
blurfus
  • 13,485
  • 8
  • 55
  • 61
Ayatsu
  • 39
  • 4
  • 1
    Does this answer your question? [Why does jQuery or a DOM method such as getElementById not find the element?](https://stackoverflow.com/questions/14028959/why-does-jquery-or-a-dom-method-such-as-getelementbyid-not-find-the-element) –  Aug 25 '22 at 16:12
  • Also [What do querySelectorAll and getElementsBy* methods return?](https://stackoverflow.com/questions/10693845/what-do-queryselectorall-and-getelementsby-methods-return) –  Aug 25 '22 at 16:13
  • 1
    3rd issue: you're supposed to pass the actual class to getElementsByClassName, without the period at the start. –  Aug 25 '22 at 16:14
  • 1
    4th issue: you're adding the class "active" but in your CSS it's called "open" –  Aug 25 '22 at 16:15

2 Answers2

0

Will be easier for you if you use

document.getElementById("hamburger"); and

document.getElementById("sidebar");

instead of getElementsByClassName

Also you need to change in the css this class

.sidebar.open {
  visibility: visible;
  left: 0;
}

into this one:

.sidebar.active {
  visibility: visible;
  left: 0;
}

Because you are adding the class "active" in sidebar.classList.add("active");, not the class "open".

Here is a working code of your example:

const hamburger = document.getElementById("hamburger");
const sidebar = document.getElementById("sidebar");

hamburger.addEventListener('click', () => {
sidebar.classList.add("active");
})
.main-page {
  width: 100%;
  height: 100vh;
  background-color: #000;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.main-page__inner {
  width: 100%;
  max-width: 1350px;
  margin: 0 auto;
}

.main-page__title {
  font-family: 'Syncopate';
  font-style: normal;
  font-weight: 700;
  font-size: 100px;
  line-height: 104px;
  color: #FFFFFF;
}

.hamburger {
  position: absolute;
  width: 40px;
  top: 69px;
  left: 41px;
  z-index: 9999;
  padding: 15px 0;
  cursor: pointer;
}

.hamburger__item {
  width: 100%;
  display: block;
  height: 4px;
  background-color: #fff;
  position: absolute;
  inset: 0;
  margin: 0 auto;
}

.hamburger__item:before,
.hamburger__item:after {
  width: 100%;
  height: 4px;
  position: absolute;
  content: "";
  background-color: #fff;
  left: 0;
  z-index: 9999;
}

.hamburger__item:before {
  top: -7px;
}

.hamburger__item:after {
  bottom: -8px;
}

.sidebar {
  position: fixed;
  top: 0;
  left: -100%;
  bottom: 0;
  z-index: 600;
  background: #591753;
  width: 100%;
  max-width: 400px;
  height: 100vh;
  visibility: hidden;
}

.sidebar.active {
  visibility: visible;
  left: 0;
}

.sidebar__inner {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: auto 0;
}

.sidebar__title {
  font-family: 'Montserrat';
  font-wei
<!DOCTYPE html>
<html lang="en">
<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">
    <link rel="stylesheet" href="ChampionA.css">
    <script src="ChampionA.js"></script>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&family=Montserrat:wght@400;600&family=Open+Sans:wght@300;400;500;600;700;800&family=Raleway:wght@100;200;300;400;500;600;700;800;900&family=Source+Sans+Pro:wght@600&family=Syncopate:wght@400;700&display=swap" rel="stylesheet">
    <title>CHAMPION Astana</title>
</head>
<body>
    <header class="header">
        <div class="container">
            <div class="header__inner">
                <div class="nav-bar">
                    <img class="logo" src="/assets/Header/LOGO.png" alt="logo">
                    <a class="click-to-action" href="#">Оставить заявку</a>
                </div>
            </div>
        </div>
    </header>

    <div class="hamburger" id="hamburger">
        <span class="hamburger__item" id="hamburger__item"></span>
    </div>

    <div class="sidebar" id="sidebar">
        <div class="sidebar__inner">
            <h1 class="sidebar__title">BLA BLA BLA</h1>
        </div>
    </div>

    <div class="main-page">
        <div class="container">
            <div class="main-page__inner">
                <h1 class="main-page__title">CHAMPION ASTANA</h1>
            </div>
        </div>
    </div>
</body>
</html>
blurfus
  • 13,485
  • 8
  • 55
  • 61
  • If, instead of using `sidebar.classList.add("active");` you change it to `.toggle(...)` as in `sidebar.classList.toggle("active");` you get the sidebar to close as well :) – blurfus Aug 25 '22 at 16:48
  • Yes, but the question only asked why the "active" class was not added, it does not ask how to remove it or any futher functionalities. – Hussein Lababidi Aug 25 '22 at 16:54
  • I was just trying to suggest an improvement to your answer :) - up to you if you want to actually improve it. You would know that a sidebar needs to be shown and eventually hidden as well (so users can see the content of the page) - – blurfus Aug 25 '22 at 16:56
  • I understand, I don't really know how to reply, since I'm just starting here. Is it better to give a more advanced answer, even if the original question did not ask for it? If so, i can edit my aswer – Hussein Lababidi Aug 25 '22 at 17:03
  • You can always make the answer better for the OP (original poster) - which is why I suggested my improvement. You are not obligated to do it (as it is _your_ answer) but better answers get more upvotes. My suggestion would be to include a comment indicating the improvement (like my original comment) - It would be up to the OP to use your improved code or not – blurfus Aug 25 '22 at 17:26
-2

Firstly you are using getElementsByClassName with wrong string. It should be only the class name: document.getElementsByClassName('hamburger').

Secondly getElementsByClassName returns the array of elements, therefore it should be used like document.getElementsByClassName('hamburger')[0]

I would recommend using document.getElementById("hamburger") as you do have id available.

const hamburger = document.getElementsByClassName("hamburger")[0];
const sidebar = document.getElementsByClassName("sidebar")[0];

hamburger.addEventListener('click', () =>{
    sidebar.classList.add("active");
})
AhmerMH
  • 638
  • 7
  • 18
  • this would require the `.hamburger` to be in the exact position in the collection as you expect it. The moment you add another hamburger class before the existing one (for whatever reason) - the desired outcome stops working. So, I suggest this is a 'weak' solution as it is very tightly coupled to the structure of the DOM. – blurfus Aug 25 '22 at 16:50
  • I also mentioned using `getElementById` as this is what should be used. The mentioned code is a working snippet of currently available code, as usually while studying it is mentioned in problem statement to use getElementsByClassnames etc. – AhmerMH Aug 26 '22 at 17:33