Создание аккордеона

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

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

В этом тренажере вы попрактикуетесь в создании интерактивного элемента интерфейса - аккордеона. Аккордеон позволяет компактно отображать большое количество контента, раскрывая только нужные разделы по клику. Задания охватывают различные аспекты создания аккордеона: от простой смены видимости содержимого до добавления классов для стилизации и обработки событий. Вы будете работать с HTML-структурой, CSS-классами (в некоторых заданиях) и, конечно же, JavaScript-кодом, который и оживляет аккордеон.

Список тем

Простой аккордеон: скрытие/отображение

id: 37069_accordion-1

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

CSS
.accordion-content { display: none; }
HTML
Восстановить HTML
<div class="accordion">
  <div class="accordion-header">Заголовок 1</div>
  <div class="accordion-content">Содержимое 1</div>
</div>
JavaScript
const header = document.querySelector('.accordion-header');
header.addEventListener(input__1, () => {
  const content = header.input__2;
  if (content.style.display === input__3) {
    content.style.display = 'block';
  } else {
    content.style.display = input__4;
  }
});
Используйте обработчик события `click` для заголовка. Внутри обработчика получите элемент содержимого (например, с помощью `nextElementSibling`) и измените его свойство `style.display`. Если содержимое скрыто (`display: none`), установите `display: block`; иначе - `display: none`.
Заполнить ответами все поля
Результат
Лог
Выполнить
Показать подсказку

Множественный аккордеон

id: 37069_accordion-2

Доработайте код так, чтобы аккордеон работал с несколькими секциями. При клике на заголовок каждой секции должно открываться/закрываться только её содержимое.

CSS
.accordion-content { display: none; }
HTML
Восстановить HTML
<div class="accordion">
  <div class="accordion-header">Заголовок 1</div>
  <div class="accordion-content">Содержимое 1</div>
</div>
<div class="accordion">
  <div class="accordion-header">Заголовок 2</div>
  <div class="accordion-content">Содержимое 2</div>
</div>
JavaScript
const headers = document.querySelectorAll('.accordion-header');

headers.forEach(header => {
  header.addEventListener('click', () => {
    const content = header.input__1;
    if (content.style.display === 'none') {
      content.style.display = input__2;
    } else {
      content.style.display = 'none';
    }
  });
});
Используйте `querySelectorAll` для получения всех заголовков. Затем переберите их в цикле и добавьте обработчик события `click` к каждому заголовку. Внутри обработчика используйте `this` для ссылки на текущий заголовок и `nextElementSibling` для получения соответствующего содержимого.
Заполнить ответами все поля
Результат
Лог
Выполнить
Показать подсказку

Добавление класса active

id: 37069_accordion-3

Добавьте класс `active` к заголовку аккордеона при его открытии и удаляйте этот класс при закрытии. Это позволит стилизовать активный заголовок.

CSS
.accordion-content { display: none; }
.active { background-color: #f0f0f0; }
HTML
Восстановить HTML
<div class="accordion">
  <div class="accordion-header">Заголовок 1</div>
  <div class="accordion-content">Содержимое 1</div>
</div>
<div class="accordion">
  <div class="accordion-header">Заголовок 2</div>
  <div class="accordion-content">Содержимое 2</div>
</div>
JavaScript
const headers = document.querySelectorAll('.accordion-header');

headers.forEach(header => {
  header.addEventListener('click', () => {
    const content = header.nextElementSibling;
    if (content.style.display === 'none') {
      content.style.display = 'block';
      header.classList.input__1('active');
    } else {
      content.style.display = 'none';
      header.classList.input__2('active');
    }
  });
});
В обработчике события `click` используйте `classList.add('active')` для добавления класса и `classList.remove('active')` для удаления. Используйте `this` для ссылки на текущий заголовок.
Заполнить ответами все поля
Результат
Лог
Выполнить
Показать подсказку

Закрытие других секций

id: 37069_accordion-4

Сделайте так, чтобы при открытии одной секции аккордеона, все остальные секции закрывались.

CSS
.accordion-content { display: none; }
.active { background-color: #f0f0f0; }
HTML
Восстановить HTML
<div class="accordion">
  <div class="accordion-header">Заголовок 1</div>
  <div class="accordion-content">Содержимое 1</div>
</div>
<div class="accordion">
  <div class="accordion-header">Заголовок 2</div>
  <div class="accordion-content">Содержимое 2</div>
</div>
<div class="accordion">
  <div class="accordion-header">Заголовок 3</div>
  <div class="accordion-content">Содержимое 3</div>
</div>
JavaScript
const headers = document.querySelectorAll('.accordion-header');

headers.forEach(header => {
  header.addEventListener('click', function() {
    headers.forEach(otherHeader => {
      if (otherHeader !== input__1) {
        otherHeader.classList.remove('active');
        otherHeader.nextElementSibling.style.display = input__2;
      }
    });

    const content = this.nextElementSibling;
    if (content.style.display === 'none') {
      content.style.display = 'block';
      this.classList.add('active');
    } else {
      content.style.display = 'none';
      this.classList.remove('active');
    }
  });
});
В обработчике `click` перед открытием текущей секции, пройдитесь по всем заголовкам и закройте их содержимое, а также удалите класс `active` у заголовков. Используйте `forEach` и проверку, не является ли текущий заголовок тем, на который кликнули (с помощью `this`).
Заполнить ответами все поля
Результат
Лог
Выполнить
Показать подсказку

Аккордеон с иконками

id: 37069_accordion-5

Добавьте иконки (например, стрелочки) к заголовкам аккордеона, которые меняют свое направление при открытии/закрытии секции.

CSS
.accordion-content { display: none; }
.accordion-header { cursor: pointer; }
.accordion-icon { display: inline-block; margin-left: 5px; transition: transform 0.3s; }
.accordion-icon.open { transform: rotate(90deg); }
HTML
Восстановить HTML
<div class="accordion">
 <div class="accordion-header">Заголовок 1<span class="accordion-icon">►</span></div>
 <div class="accordion-content">Содержимое 1</div>
</div>
<div class="accordion">
 <div class="accordion-header">Заголовок 2<span class="accordion-icon">►</span></div>
 <div class="accordion-content">Содержимое 2</div>
</div>
JavaScript
const headers = document.querySelectorAll('.accordion-header');

headers.forEach(header => {
 header.addEventListener('click', function() {
 const content = this.nextElementSibling;
 const icon = this.querySelector(input__1);
 if (content.style.display === 'none') {
 content.style.display = 'block';
 icon.classList.add(input__2);
 } else {
 content.style.display = 'none';
 icon.classList.remove(input__3);
 }
 });
});
Добавьте HTML-элемент для иконки внутрь каждого заголовка (например, `<span>`). Используйте CSS для стилизации иконки и её поворота (например, с помощью `transform: rotate(90deg)`). В JavaScript, при клике на заголовок, добавляйте/удаляйте класс у иконки, который и будет отвечать за её поворот.
Заполнить ответами все поля
Результат
Лог
Выполнить
Показать подсказку

Аккордеон: начальное состояние

id: 37069_accordion-6

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

CSS
.accordion-content { display: none; }
.active { background-color: #f0f0f0; }
HTML
Восстановить HTML
<div class="accordion">
  <div class="accordion-header">Заголовок 1</div>
  <div class="accordion-content">Содержимое 1</div>
</div>
<div class="accordion">
  <div class="accordion-header">Заголовок 2</div>
  <div class="accordion-content">Содержимое 2</div>
</div>
JavaScript
const headers = document.querySelectorAll('.accordion-header');

headers.forEach(header => {
  header.addEventListener('click', function() {
    const content = this.nextElementSibling;
    if (content.style.display === 'none') {
      content.style.display = 'block';
      this.classList.add('active');
    } else {
      content.style.display = 'none';
      this.classList.remove('active');
    }  
  });
});

const firstHeader = headers[input__1];
firstHeader.classList.add('active');
firstHeader.nextElementSibling.style.display = input__2;
После получения всех заголовков, получите первый заголовок (например, с помощью `headers[0]`) и примените к нему логику открытия: установите `style.display = 'block'` для содержимого и добавьте класс `active` заголовку.
Заполнить ответами все поля
Результат
Лог
Выполнить
Показать подсказку

Плавное открытие/закрытие

id: 37069_accordion-7

Добавьте плавную анимацию открытия и закрытия содержимого аккордеона, используя CSS transitions.

CSS
.accordion-content { max-height: 0; overflow: hidden; transition: max-height 0.3s ease-out; }
.accordion-header { cursor: pointer; }
.accordion-header.active { background-color: #f0f0f0; }
HTML
Восстановить HTML
<div class="accordion">
  <div class="accordion-header">Заголовок 1</div>
  <div class="accordion-content">Содержимое 1<br>Строка 2<br>Строка 3</div>
</div>
<div class="accordion">
  <div class="accordion-header">Заголовок 2</div>
  <div class="accordion-content">Содержимое 2</div>
</div>
JavaScript
const headers = document.querySelectorAll('.accordion-header');

headers.forEach(header => {
  header.addEventListener('click', function() {
    const content = this.nextElementSibling;
    if (content.style.maxHeight) {
      content.style.maxHeight = input__1;
      this.classList.remove('active');
    } else {
      content.style.maxHeight = content.input__2 + 'px';
      this.classList.add('active');

    }
  });
});
Используйте CSS-свойство `max-height` и `transition` для содержимого аккордеона. В JavaScript, при открытии, устанавливайте `max-height` равным scrollHeight содержимого, а при закрытии - 0. Также добавьте `overflow: hidden` для `accordion-content` в CSS.
Заполнить ответами все поля
Результат
Лог
Выполнить
Показать подсказку
НайтиКурс.Ру