Как превратить ссылки панели навигации в раскрывающееся меню с помощью HTML CSS и JavaScript?

Я пытаюсь превратить первые две ссылки моей панели навигации в выпадающие меню. Я хочу сделать так, чтобы при нажатии на них отображалось раскрывающееся меню, а значок стрелки превращался из стрелки, указывающей вниз, в стрелку, указывающую вверх.

Я пытался использовать JavaScript для выполнения событий OnClick, но безуспешно.

По какой-то причине мои два раскрывающихся меню перекрывают друг друга и не расположены под правильными ссылками на панели навигации. Один должен отображаться под ссылкой на функции, а другой — под ссылкой на компанию на панели навигации. Я также хотел бы попросить помощи в том, как это исправить.

/* When the user clicks on the button,
    toggle between hiding and showing the dropdown content */
function myFunction() {
  document.getElementById("dropdown").classList.toggle("show");
}

// Close the dropdown menu if the user clicks outside of it
window.onclick = function(event) {
  if (!event.target.matches('.dropdown-arrow')) {
    var dropdowns = document.getElementsByClassName("dropdown-content");
    var i;
    for (i = 0; i < dropdowns.length; i++) {
      var openDropdown = dropdowns[i];
      if (openDropdown.classList.contains('show')) {
        openDropdown.classList.remove('show');
      }
    }
  }
}
@import url('https://fonts.googleapis.com/css2?family=Epilogue:wght@500;700&display=swap');
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
  font-family: 'Epilogue', 'sans-serif';
}

.body-container {
  background-color: hsl(0, 0%, 98%);
  height: 100vh;
  width: 100vw;
  max-width: 100%;
}

.navbar {
  display: flex;
  align-items: center;
}

.navbar-flex li {
  margin-right: auto;
  display: inline-block;
  padding: 1em;
}

.navbar-flex a {
  color: hsl(0, 0%, 41%);
  text-decoration: none;
}

.navbar-flex a:hover {
  color: hsl(0, 0%, 8%);
}

.navbar li {
  list-style-type: none;
}

.navbar img {
  padding: 1.5em 1em 1em 2em;
}

.navbar-btn {
  margin-left: auto;
  padding: 1.5em;
}

.dropdown {
  position: relative;
  display: inline-block;
}

.dropdown-content {
  /*display: none;*/
  position: absolute;
  min-height: 100px;
  box-shadow: 0px 8px 16px 0px hsla(0, 0%, 0%, 0.2);
  z-index: 1;
}

.dropdown-content a {
  color: hsl(0, 0%, 8%);
  padding: 12px 16px;
  text-decoration: none;
  display: block;
}


/* Change color of dropdown links on hover */

.dropdown-content a:hover {
  background-color: hsl(0, 0%, 41%);
}

.dropdown-arrow {
  color: hsl(0, 0%, 41%);
  outline: none;
  background: none;
  border: none;
  cursor: pointer;
}

.dropdown-arrow:hover {
  color: hsl(0, 0%, 8%);
}

.dropdown-links {
  text-decoration: none;
  display: block;
  padding: 1em;
  color: hsl(0, 0%, 8%);
}

.dropdown-links:hover {
  background-color: hsl(0, 0%, 98%);
}

.show {
  display: block;
}


/* Styles for both buttons in the navbar */

.btn-primary {
  color: hsl(0, 0%, 41%);
  outline: none;
  padding: 0.5em;
  margin-left: 1em;
  cursor: pointer;
}

.btn-primary:hover {
  color: hsl(0, 0%, 8%);
}


/* Styles for login button in the navbar */

#login-btn {
  border: none;
  background: none;
}


/* Styles for register button in the navbar */

#register-btn {
  padding: 0.8em;
  border-radius: 10px;
  background: none;
  border-color: hsl(0, 0%, 41%);
  border-width: 1px;
}

.register-btn:hover {
  border-color: hsl(0, 0%, 8%);
}
<div class = "body-container">
  <nav class = "navbar">
    <a href = "#"><img src = "images/logo.svg" alt = "company logo"></a>
    <ul class = "navbar-flex">

      <li><a href = "#">Features </a>
        <!-- Features dropdown menu-->
        <div class = "dropdown">
          <button onclick = "myFunction()" class = "dropdown-arrow">
            <svg class = "drop-image" svg width = "10" height = "6" xmlns = "http://www.w3.org/2000/svg"><path stroke = "#686868" stroke-width = "1.5" fill = "none" d = "m1 1 4 4 4-4"/></svg>
          </button>
          <ul class = "dropdown-content">
            <li><a class = "dropdown-links" href = "#">Todo List</a></li>
            <li><a class = "dropdown-links" href = "#">Calendars</a></li>
            <li><a class = "dropdown-links" href = "#">Reminders</a></li>
            <li><a class = "dropdown-links" href = "#">Planning</a></li>
          </ul>
        </div>
      </li>

      <li><a href = "#">Company </a>
        <!-- Company dropdown menu-->
        <div class = "dropdown">
          <button onclick = "myFunction()" class = "dropdown-arrow">
            <svg class = "drop-image" width = "10" height = "6" xmlns = "http://www.w3.org/2000/svg"><path stroke = "#686868" stroke-width = "1.5" fill = "none" d = "m1 1 4 4 4-4"/></svg>
          </button>
          <ul id = "my-dropdown" class = "dropdown-content">
            <li><a class = "dropdown-links" href = "#">History</a></li>
            <li><a class = "dropdown-links" href = "#">Our Team</a></li>
            <li><a class = "dropdown-links" href = "#">Blog</a></li>
          </ul>
        </div>
      </li>

      <li><a href = "#">Careers</a></li>
      <li><a href = "#">About</a></li>
    </ul>

    <div class = "navbar-btn">
      <button class = "btn-primary" id = "login-btn">Login</button>
      <button class = "btn-primary" id = "register-btn">Register</button>
    </div>
  </nav>

</div>

</div>
</div>
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
36
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я написал вам возможный подход Vanilla JS для обработки поведения, которое вы ищете:

  1. Сначала выберите все элементы li в вашем списке;
  2. Добавьте прослушиватель событий click;
  3. При каждом щелчке он добавляет или удаляет классы, которые показывают модальное окно и поворачивают стрелку, на основе свойства, которое я прикрепляю к узлу DOM, isOpen, поэтому вы всегда можете знать, открыт или закрыт определенный элемент визуально. Это полезно, если вы планируете закрыть другие открытые раскрывающиеся списки при открытии нового, чтобы предотвратить перекрытие.

const links = document.querySelectorAll(".navbar-flex>li")
links.forEach((el, i) => {
  el.isOpen = false;
  el.onclick = e => {
    const dropdown = el.querySelector(".dropdown")
    const arrow = el.querySelector(".dropdown-arrow")
    el.isOpen ? close(dropdown,
      arrow) : open(dropdown,
      arrow)
    el.isOpen = !el.isOpen
    //Close other open dropdowns
    links.forEach((el, j) => {
      const dropdown = el.querySelector(".dropdown")
      const arrow = el.querySelector(".dropdown-arrow")
      if (i !== j) {
        if (el.isOpen) {
          close(dropdown, arrow)
          el.isOpen = false
        }
      }
    })
  }

})


function open(el, arrow) {
  el.classList.add("show")
  arrow.classList.add("rotate")
}

function close(el, arrow) {
  el.classList.remove("show")
  arrow.classList.remove("rotate")
}
@import url('https://fonts.googleapis.com/css2?family=Epilogue:wght@500;700&display=swap');
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
  font-family: 'Epilogue', 'sans-serif';
}

.body-container {
  background-color: hsl(0, 0%, 98%);
  height: 100vh;
  width: 100vw;
  max-width: 100%;
}

.navbar {
  display: flex;
  align-items: center;
}

.navbar-flex li {
  margin-right: auto;
  display: inline-block;
  padding: 1em;
}

.navbar-flex a {
  color: hsl(0, 0%, 41%);
  text-decoration: none;
}

.navbar-flex a:hover {
  color: hsl(0, 0%, 8%);
}

.navbar li {
  list-style-type: none;
}

.navbar img {
  padding: 1.5em 1em 1em 2em;
}

.navbar-btn {
  margin-left: auto;
  padding: 1.5em;
}

.dropdown {
  position: absolute;
  display: none;
  background: #FFF;
}

.dropdown-content {
  min-height: 100px;
  box-shadow: 0px 8px 16px 0px hsla(0, 0%, 0%, 0.2);
  z-index: 1;
  display: flex;
  flex-direction: column;
}

.dropdown-content a {
  color: hsl(0, 0%, 8%);
  padding: 12px 16px;
  text-decoration: none;
  display: block;
}


/* Change color of dropdown links on hover */

.dropdown-content a:hover {
  background-color: hsl(0, 0%, 41%);
}

.dropdown-arrow {
  color: hsl(0, 0%, 41%);
  outline: none;
  background: none;
  border: none;
  cursor: pointer;
  transition: all 0.2s ease-out;
}

.dropdown-arrow:hover {
  color: hsl(0, 0%, 8%);
}

.dropdown-links {
  text-decoration: none;
  display: block;
  padding: 1em;
  color: hsl(0, 0%, 8%);
}

.dropdown-links:hover {
  background-color: hsl(0, 0%, 98%);
}

.show {
  display: block !important;
}

.rotate {
  transform: rotate(180deg);
}


/* Styles for both buttons in the navbar */

.btn-primary {
  color: hsl(0, 0%, 41%);
  outline: none;
  padding: 0.5em;
  margin-left: 1em;
  cursor: pointer;
}

.btn-primary:hover {
  color: hsl(0, 0%, 8%);
}


/* Styles for login button in the navbar */

#login-btn {
  border: none;
  background: none;
}


/* Styles for register button in the navbar */

#register-btn {
  padding: 0.8em;
  border-radius: 10px;
  background: none;
  border-color: hsl(0, 0%, 41%);
  border-width: 1px;
}

.register-btn:hover {
  border-color: hsl(0, 0%, 8%);
}
<div class = "body-container">
  <nav class = "navbar">
    <a href = "#"><img src = "images/logo.svg" alt = "company logo"></a>
    <ul class = "navbar-flex">

      <li>
        <a href = "#">Features </a>
        <button class = "dropdown-arrow">
            <svg class = "drop-image" svg width = "10" height = "6" xmlns = "http://www.w3.org/2000/svg"><path stroke = "#686868" stroke-width = "1.5" fill = "none" d = "m1 1 4 4 4-4"/></svg>
          </button>
        <!-- Features dropdown menu-->
        <div class = "dropdown">

          <ul class = "dropdown-content">
            <li><a class = "dropdown-links" href = "#">Todo List</a></li>
            <li><a class = "dropdown-links" href = "#">Calendars</a></li>
            <li><a class = "dropdown-links" href = "#">Reminders</a></li>
            <li><a class = "dropdown-links" href = "#">Planning</a></li>
          </ul>
        </div>
      </li>

      <li>
        <a href = "#">Company </a>
        <button class = "dropdown-arrow">
            <svg class = "drop-image" width = "10" height = "6" xmlns = "http://www.w3.org/2000/svg"><path stroke = "#686868" stroke-width = "1.5" fill = "none" d = "m1 1 4 4 4-4"/></svg>
          </button>
        <!-- Company dropdown menu-->
        <div class = "dropdown">
          <ul id = "my-dropdown" class = "dropdown-content">
            <li><a class = "dropdown-links" href = "#">History</a></li>
            <li><a class = "dropdown-links" href = "#">Our Team</a></li>
            <li><a class = "dropdown-links" href = "#">Blog</a></li>
          </ul>
        </div>
      </li>

      <li><a href = "#">Careers</a></li>
      <li><a href = "#">About</a></li>
    </ul>

    <div class = "navbar-btn">
      <button class = "btn-primary" id = "login-btn">Login</button>
      <button class = "btn-primary" id = "register-btn">Register</button>
    </div>
  </nav>

</div>

</div>
</div>

Спасибо, вы спасатель @Cesare Polonara

shemjay 15.05.2022 14:14

Другие вопросы по теме