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

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

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

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

Список тем

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

Создайте выпадающее меню, которое открывается при клике на кнопку "Меню" и закрывается при повторном клике. Используйте свойство `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`).
Заполнить ответами все поля
Результат
Лог
Выполнить
Отметить решенным
Показать подсказку

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

Доработайте предыдущий пример: при открытии меню добавляйте к элементу списка класс `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` для управления классами элемента.
Заполнить ответами все поля
Результат
Лог
Выполнить
Отметить решенным
Показать подсказку

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

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

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`) кнопкой меню или элементом списка. Если нет, то закрывайте меню.
Заполнить ответами все поля
Результат
Лог
Выполнить
Отметить решенным
Показать подсказку

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

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

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` у подменю.
Заполнить ответами все поля
Результат
Лог
Выполнить
Отметить решенным
Показать подсказку

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

Создайте выпадающее меню, пункты которого генерируются динамически из массива 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`.
Заполнить ответами все поля
Результат
Лог
Выполнить
Отметить решенным
Показать подсказку

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

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

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`).
Заполнить ответами все поля
Результат
Лог
Выполнить
Отметить решенным
Показать подсказку

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

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

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` пункта меню.
Заполнить ответами все поля
Результат
Лог
Выполнить
Отметить решенным
Показать подсказку
НайтиКурс.Ру
Добавить комментарий