简体   繁体   中英

How can I fix this toggle function?

I am working an a project for setting up a basic responsive web page for myself. I have everything the way that I want it for my set up but I am having problems with my function to open and close the hamburger menu on screens with a max-width of less than 480px. If I take the method toggleMenu() off of my div with a menu class and I uncomment out the javascript code that is currently commented out and comment out the code that is currently active, everything works perfect on every click. However if I leave the code as is and run it in the browser the menu only toggles open on every other click, so the first time I click it nothing happens, the second time I click it, the menu opens up, the third time I click it nothing happens and finally when I click the fourth time the menu closes back up again. The other issue that I am having is currently I have to include an external script file or put a script inside of my html file rather than relying on my build.js file to import the code. My question is what am I missing to get my menu to open and close correctly while still calling a function from my menu class and how would I write this as a module that I can bundle and run from my build.js file. Any help is greatly appreciated and thank you in advance. My HTML File:

<!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">
       <!-- Bring in google fonts -->
       <link href="https://fonts.googleapis.com/css?family=Poppins&display=swap" rel="stylesheet">
       <link href="https://fonts.googleapis.com/css?family=Montserrat+Alternates&display=swap" rel="stylesheet">
  <!-- Bring in bootstrap  -->
       <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" crossorigin="anonymous">
       <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/js/bootstrap.bundle.min.js" integrity="sha384-b5kHyXgcpbZJO/tY9Ul7kGkf1S0CWuKcCD38l8YkeH8z8QjE0GmW1gYU5S9FOnJ0" crossorigin="anonymous"></script>
  <!-- Bring in JSPopper -->
       <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.6.0/dist/umd/popper.min.js" integrity="sha384-KsvD1yqQ1/1+IA7gi3P0tyJcT3vR+NdBTt13hSJ2lnve8agRGXTTyNaBYmCR/Nwi" crossorigin="anonymous"></script>

     <script src="src/js/index.js" defer></script>
      
  <!-- Bring in my style sheet  -->
       <link rel="stylesheet" href="src/assets/css/basic-style.css">
     <title>Basic Page Setup</title>
</head>
<body>
   <nav class="navbar">

        <div class="logo-container">
              <a href="#">
                   <img src="src/assets/images/seethrough_1.png" alt="seethrough_1" class="logo-image">
                   <span class="logo-text">LOGOHERE</span>
              </a>
       </div>

        <ul class="nav-list" id="navi-list">
             <li class="list-item">
                  <a href="#">About Us</a>
             </li>
             <li class="list-item">
                  <a href="#">Contact</a>
             </li>
             <li class="list-item">
                  <a href="#">Support</a>
             </li>
        </ul>
        <div class="menu" id="toggle-menu" onclick="toggleMenu()">
             <div class="menu-line"></div>
             <div class="menu-line"></div>
             <div class="menu-line"></div>
        </div>
   </nav>
<div class="main-content">
     <p class="my-story">
          Not many have a story like mine. At 2 years old I was diagnosed with leukemia 
          and went into chemotherapy. This brings a great many problems, not least among 
          them a compromised immune system. I caught a cold that turned into pneumonia 
          and I died. It didn’t stick. In that time I saw things that would influence my life 
          profoundly. I can’t explain what happened but when I woke up, the pneumonia was 
          <a href="#about-me" id="about-me"></a>
          gone along with the leukemia. I have also overcome Pancreatic Cancer, Crohn's Disease, 
          and Diabetes just to name a few of the hurdles I found myself lifted over. I give all glory 
          to God, but I tell you these things not to garner sympathy or convince you that my God is 
          real. I tell you this because I believe all these things made me a purposeful person. I got a 
          certification in Computer programming on purpose. I write clean code on purpose. I believe 
          you are reading this on purpose. Let me show you what I can do for you on purpose.
     </p>
</div>

        <div class="footer-container">
             <div class="logo-copyright">
                  <span class="copyright">&copy;</span>
                  <img src="src/assets/images/seethrough_1.png" alt="seethrough_1" class="footer-logo">
                  <span class="footer-text">WebTek</span>
             </div>
            <div class="webmaster-contact">
                 <span class="footer-info">This page created and designed by</span>
                 <a href="mailto: tkremer@nc.rr.com" class="webmaster" id="contact">Thomas E. Kremer</a>
            </div>
        </div>
        
<!--      <script src="dist/build.js" defer></script>
 -->
 <!-- <script src="src/js/index.js" defer></script> -->
</body>
</html>

My CSS File:

*{
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
/* Style the logo image and text */
/* .company-logo {
     text-decoration: none;
}
.logo-image {
     width: 75px;
     height: 75px;
}
.logo-text {
     font-family: Montserrat Alternates;
     font-weight: 600;
     font-style: none;
     font-size: 35px;
     color: rgba(0, 0, 0, 1);
     line-height: 32px;
     letter-spacing: 0.03em;
}   */
.logo-image {
  width: 55px;
  height: auto;
}
.logo-text {
  font-family: Montserrat Alternates;
  font-weight: 600;
  font-style: none;
  font-size: 36px;
  line-height: 32px;
  letter-spacing: 0.03em;
}
.navbar a{
  text-decoration: none;
  color: rgba(0, 0, 0, 1);
}
.navbar a:hover {
  color: blue;
}
.navbar {
  align-items: center;
  background-color: #FFFFFF;
  color: rgba(0, 0, 0, 1);
  display: flex;
  font-family: Poppins;
  font-size: 25px;
  justify-content: space-around;
}

.nav-list {
  list-style-type: none;
}

.nav-list .list-item {
  display: inline-block;
  padding: 20px 10px;
}
/* Hide menu on larger screens */
.menu {
  display: none;
}
.menu-line {
  background-color: green;
  width: 25px;
  height: 3px;
  margin-bottom: 4px;
}

/* Style the footer and footer elements */
   .footer-logo {
     margin-top: 0px;
     margin-bottom: 10px;
     width: 55px;
     height: 55px;
}
.copyright {
  font-family: Montserrat Alternates;
  font-weight: 600;
  font-size: 25px;
}
.footer-text {
  margin-top: 25px;
  font-family: Montserrat Alternates;
  font-weight: 600;
  font-style: normal;
  font-size: 21px;
}
.webmaster {
  text-decoration: none;
}
.footer-info {
  font-family: Poppins;
  font-weight: 200;
  font-size: 18px;
  font-style: normal;
  line-height: 32px;
  letter-spacing: 0.03em;
}
.webmaster-contact {
  margin-top: 13px;
}
.footer-container {
     display: flex;
     justify-content: space-evenly;
     position: fixed;
     left: 0;
     bottom: 0;
     width: 100%;
     background-color: #FFFFFF;
     text-align: center;
}

.my-story {
  margin-top: 25px;
  padding: 0 25px 0 25px;
  font-family: Poppins;
  font-weight: 200;
  font-style: normal;
  font-size: 16px;
}

/* Media query for smaller devices, hamburger menu */
@media all and (max-width: 480px) {
  .navbar {
    flex-direction: column;
    position: relative;
  }
  .logo-container {
    width: 100%;
    margin-left: 10px;
    margin-top: 10px;
    margin-bottom: 5px;
  }
/* Show menu */
.menu {
  display: block;
  position: absolute;
  right: 10px;
  top: 10px;
}
.nav-list {
  list-style-type: none;
  width: 100%;
  text-align: center;
  padding: 20px;
  display: none;
  /* padding-left: 0; */
}
.nav-list .list-item {
  display: block;
  border-top: 1px solid black;
  padding: 10px;
}
.footer-container {
  display: flex;
  flex-direction: column;
  justify-content:inherit;
  position: fixed;
  left: 0;
  bottom: 0;
  width: 100%;
  background-color: #FFFFFF;
  text-align: center;
}
.copyright {
  font-family: Montserrat Alternates;
  font-weight: 600;
  font-size: 20px;
}
.footer-logo {
  margin-top: 0px;
  margin-bottom: 10px;
  width: 45px;
  height: 45px;
}
.footer-text {
  margin-top: 25px;
  font-family: Montserrat Alternates;
  font-weight: 600;
  font-style: normal;
  font-size: 25px;
}
.logo-copyright {
  display: inline-block;
  margin: 0;
  padding: 0;
}
.webmaster-contact {
  display: inline-block;
  margin: 0;
  padding: 0;
}
.active {
  display: block;
}
.inactive {
  display: none;
}
}

My JavaScript File:

/* Toggle hamburger menu */
/* const toggleButton = document.getElementById('toggle-menu');
const naviList = document.getElementById('navi-list');
toggleButton.addEventListener('click', () => {
           naviList.classList.toggle('active');
}); */


function toggleMenu() {
     const toggleButton = document.getElementById('toggle-menu');
     const naviList = document.getElementById('navi-list');
     toggleButton.addEventListener('click', () => {
          naviList.classList.toggle('active');
     });
}

So recap, I am trying to have the hamburger menu open and close with each click and run the script from my bundled build.js file rather than from within my html file or from another external javascript file, either as a module or as an onclick function. Thank you all again for the help in advance.

Your function toggleMenu() is setting an event listener on the first click, then the second click is triggering that listener!

Your first method works (commented out).

Use standalone JS - with no 'onclick' event:

// JS EVENT LISTENER METHOD (my preferred method)

const toggleButton = document.getElementById('toggle-menu');
const naviList = document.getElementById('navi-list');

toggleButton.addEventListener('click', () => {
  naviList.classList.toggle('active');
});
// HTML EVENT METHOD

// When you call the named function from HTML `onclick="toggleMenu()"` 
// the event listener is not required. You can just toggle 
// the .active class as usual.

// <div class="menu" id="toggle-menu" onclick="toggleMenu()">

function toggleMenu() {
     const naviList = document.getElementById('navi-list');
     naviList.classList.toggle('active');
}

Using both methods together will cancel each other out. It's really toggling .active twice - too fast to see!

tested with codepen

addEventListener VS onclick comparison

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM