Создание выпадающего меню

Тренажер по работе с HTML DOM на JavaScript для пользователей с начальным и средним уровнем подготовки.

Тренажер JavaScript: Покоряем HTML DOM

В этом тренажере вы попрактикуетесь в создании интерактивных выпадающих меню с использованием JavaScript и HTML DOM. Задания охватывают различные аспекты работы с выпадающими списками: открытие и закрытие меню по клику, добавление и удаление элементов, изменение стилей и обработка событий. Каждое задание представляет собой фрагмент кода с пропусками, которые вам нужно заполнить, чтобы достичь желаемого результата. Внимательно читайте описание и используйте подсказки, если возникнут трудности.

Список тем

Простое открытие/закрытие меню

id: 37063_dropdown-1

Создайте выпадающее меню, которое открывается при клике на кнопку "Меню" и закрывается при повторном клике. Используйте свойство `display` для управления видимостью списка. Вам нужно добавить обработчик события `click` к кнопке и изменить стиль элемента списка.

CSS
.dropdown-menu { display: none; }
HTML
Восстановить HTML
<button id="menu-btn">Меню</button>
<ul id="menu-list" class="dropdown-menu">
  <li>Пункт 1</li>
  <li>Пункт 2</li>
  <li>Пункт 3</li>
</ul>
JavaScript
const menuBtn = document.getElementById("menu-btn");
const menuList = document.input__1("menu-list");

menuBtn.input__2("click", () => {
  if (menuList.style.display === "block") {
    menuList.style.input__3 = "none";
  } else {
    menuList.style.display = input__4;
  }
});
Используйте `getElementById` для получения элементов кнопки и списка. Добавьте обработчик события `click` к кнопке. Внутри обработчика проверяйте текущее значение свойства `display` у списка и меняйте его на `block` (если было `none` или пустое) или `none` (если было `block`).
Заполнить ответами все поля
Результат
Лог
Выполнить
Показать подсказку

Добавление класса при открытии

id: 37063_dropdown-2

Доработайте предыдущий пример: при открытии меню добавляйте к элементу списка класс `active`, а при закрытии - удаляйте этот класс. Это позволит вам стилизовать открытое меню с помощью CSS.

CSS
.dropdown-menu { display: none; }
.active { background-color: #f0f0f0; }
HTML
Восстановить HTML
<button id="menu-btn">Меню</button>
<ul id="menu-list" class="dropdown-menu">
  <li>Пункт 1</li>
  <li>Пункт 2</li>
  <li>Пункт 3</li>
</ul>
JavaScript
const menuBtn = document.getElementById("menu-btn");
const menuList = document.getElementById("menu-list");

menuBtn.addEventListener("click", () => {
  if (menuList.style.display === "block") {
    menuList.style.display = "none";
    menuList.classList.input__1("active");
  } else {
    menuList.style.display = "block";
    menuList.classList.input__2("active");
  }
});
Используйте свойство `classList` и его методы `add` и `remove` для управления классами элемента.
Заполнить ответами все поля
Результат
Лог
Выполнить
Показать подсказку

Закрытие меню при клике вне его

id: 37063_dropdown-3

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

CSS
.dropdown-menu { display: none; }
HTML
Восстановить HTML
<button id="menu-btn">Меню</button>
<ul id="menu-list" class="dropdown-menu">
  <li>Пункт 1</li>
  <li>Пункт 2</li>
  <li>Пункт 3</li>
</ul>
JavaScript
const menuBtn = document.getElementById("menu-btn");
const menuList = document.getElementById("menu-list");

menuBtn.addEventListener("click", () => {
  if (menuList.style.display === "block") {
    menuList.style.display = "none";
  } else {
    menuList.style.display = "block";
  }
});

document.addEventListener("click", (event) => {
  if (input__1.target !== menuBtn && !menuList.contains(event.target)) {
    menuList.style.display = input__2;
  }
});
Добавьте обработчик события `click` ко всему документу (`document`). Внутри обработчика проверяйте, является ли целевой элемент (`event.target`) кнопкой меню или элементом списка. Если нет, то закрывайте меню.
Заполнить ответами все поля
Результат
Лог
Выполнить
Показать подсказку

Выпадающее меню с подменю

id: 37063_dropdown-4

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

CSS
.dropdown-menu { list-style: none; padding: 0; margin: 0; }
.dropdown-menu li { position: relative; }
.dropdown-menu ul { display: none; position: absolute; top: 100%; left: 0; background-color: #eee; padding: 0; margin: 0; list-style: none; }
.dropdown-menu li:hover > ul { display: block; }
HTML
Восстановить HTML
<ul class="dropdown-menu">
  <li>Пункт 1</li>
  <li>
    Пункт 2
    <ul id="submenu-1">
      <li>Подпункт 2.1</li>
      <li>Подпункт 2.2</li>
    </ul>
  </li>
  <li>Пункт 3</li>
</ul>
JavaScript
const submenu = document.getElementById("submenu-1");
const parentLi = submenu.input__1;

parentLi.addEventListener(input__2, () => {
  submenu.style.display = "block";
});

parentLi.addEventListener("mouseout", () => {
  submenu.input__3.display = "none";
});
Используйте CSS-свойство `position: absolute;` для позиционирования подменю относительно родительского пункта. Добавьте обработчики событий `mouseover` и `mouseout` к пунктам меню, у которых есть подменю. Внутри обработчиков меняйте свойство `display` у подменю.
Заполнить ответами все поля
Результат
Лог
Выполнить
Показать подсказку

Динамическое создание пунктов меню

id: 37063_dropdown-5

Создайте выпадающее меню, пункты которого генерируются динамически из массива JavaScript. Каждый элемент массива должен стать пунктом меню.

CSS
.dropdown-menu { display: none; }
HTML
Восстановить HTML
<button id="menu-btn">Меню</button>
<ul id="menu-list" class="dropdown-menu"></ul>
JavaScript
const menuBtn = document.getElementById("menu-btn");
const menuList = document.getElementById("menu-list");
const menuItems = ["Пункт 1", "Пункт 2", "Пункт 3"];

menuBtn.addEventListener("click", () => {
  if (menuList.style.display === "block") {
    menuList.style.display = "none";
  } else {
    menuList.style.display = "block";
  }
});

for (const item of input__1) {
  const li = document.createElement(input__2);
  li.textContent = item;
  menuList.appendChild(input__3);
}
Используйте цикл `for...of` для итерации по массиву. Внутри цикла создавайте новый элемент `li` с помощью `document.createElement`, устанавливайте его текстовое содержимое (`textContent`) равным элементу массива и добавляйте его в список с помощью `appendChild`.
Заполнить ответами все поля
Результат
Лог
Выполнить
Показать подсказку

Удаление пунктов меню

id: 37063_dropdown-6

Добавьте кнопку "Удалить пункт" к каждому пункту меню. При нажатии на эту кнопку соответствующий пункт меню должен удаляться.

CSS
.dropdown-menu { display: none; }
HTML
Восстановить HTML
<button id="menu-btn">Меню</button>
<ul id="menu-list" class="dropdown-menu"></ul>
JavaScript
const menuBtn = document.getElementById("menu-btn");
const menuList = document.getElementById("menu-list");
const menuItems = ["Пункт 1", "Пункт 2", "Пункт 3"];

menuBtn.addEventListener("click", () => {
  if (menuList.style.display === "block") {
    menuList.style.display = "none";
  } else {
    menuList.style.display = "block";
  }
});

for (const item of menuItems) {
  const li = document.createElement("li");
  li.textContent = item;

  const deleteBtn = document.createElement("button");
  deleteBtn.textContent = "Удалить";
  deleteBtn.addEventListener("click", () => {
    li.input__1();
  });

  li.appendChild(deleteBtn);
  input__2.appendChild(li);
}
Внутри цикла, где создаются пункты меню, добавьте еще один элемент `button` к каждому `li`. Добавьте обработчик события `click` к этой кнопке. Внутри обработчика используйте метод `remove()` для удаления родительского элемента кнопки (то есть, самого пункта `li`).
Заполнить ответами все поля
Результат
Лог
Выполнить
Показать подсказку

Изменение текста пункта меню

id: 37063_dropdown-7

Добавьте текстовое поле и кнопку "Изменить" рядом с каждым пунктом меню. При нажатии на кнопку текст пункта меню должен заменяться на текст из текстового поля.

CSS
.dropdown-menu { display: none; }
HTML
Восстановить HTML
<button id="menu-btn">Меню</button>
<ul id="menu-list" class="dropdown-menu"></ul>
JavaScript
const menuBtn = document.getElementById("menu-btn");
const menuList = document.getElementById("menu-list");
const menuItems = ["Пункт 1", "Пункт 2", "Пункт 3"];

menuBtn.addEventListener("click", () => {
  if (menuList.style.display === "block") {
    menuList.style.display = "none";
  } else {
    menuList.style.display = "block";
  }
});

for (const item of menuItems) {
  const li = document.createElement("li");
  li.textContent = item;

  const input = document.createElement("input");
  input.type = "text";
  const changeBtn = document.createElement("button");
  changeBtn.textContent = "Изменить";

  changeBtn.addEventListener("click", () => {
    li.textContent = input__1.value;
  });

  li.appendChild(input);
  li.appendChild(changeBtn);
  menuList.appendChild(li);
}
Добавьте `input type="text"` и `button` к каждому `li` в цикле. Добавьте обработчик события `click` к кнопке. Внутри обработчика получайте значение из текстового поля (`.value`) и присваивайте его свойству `textContent` пункта меню.
Заполнить ответами все поля
Результат
Лог
Выполнить
Показать подсказку
НайтиКурс.Ру