|
| 1 | +'use strict'; |
| 2 | + |
| 3 | +// Задание 1: |
| 4 | +// Создать простую механику "Показать/Скрыть" для текстового блока. |
| 5 | +/* |
| 6 | +<div class="card"> |
| 7 | + <h3>Заголовок карточки</h3> |
| 8 | + <p>Этот текст виден всем и всегда.</p> |
| 9 | + <div id="details" class="hidden"> |
| 10 | + <p>А это дополнительная информация, которая изначально скрыта от пользователя.</p> |
| 11 | + </div> |
| 12 | + <button id="toggle-btn">Читать далее</button> |
| 13 | +</div> |
| 14 | +*/ |
| 15 | +// Твоя задача: |
| 16 | +// Напиши JavaScript код, который: |
| 17 | +// 1. При клике на кнопку с id="toggle-btn". |
| 18 | +// 2. Находит блок с id="details" и переключает у него класс hidden. |
| 19 | +// 3. Бонус (необязательно): Попробуй сделать так, чтобы текст на кнопке менялся с "Читать далее" на "Скрыть", и обратно, в зависимости от того, виден ли скрытый текст. |
| 20 | + |
| 21 | +const details = document.querySelector('#details'); |
| 22 | +const toggleBtn = document.querySelector('#toggle-btn'); |
| 23 | + |
| 24 | +// function showHideAddInfo() { |
| 25 | +// details.classList.toggle('hidden'); |
| 26 | +// |
| 27 | +// if (details.classList.contains('hidden')) { |
| 28 | +// toggleBtn.textContent = 'Читать далее'; |
| 29 | +// } else { |
| 30 | +// toggleBtn.textContent = 'Скрыть'; |
| 31 | +// } |
| 32 | +// } |
| 33 | +// |
| 34 | +// toggleBtn.addEventListener('click', showHideAddInfo); |
| 35 | + |
| 36 | +// ?? альтернативное решение |
| 37 | +toggleBtn.addEventListener('click', () => { |
| 38 | + // 1. Проверяем, был ли элемент скрыт ДО переключения |
| 39 | + const wasHidden = details.classList.contains('hidden'); |
| 40 | + |
| 41 | + // 2. Меняем текст кнопки в зависимости от того, что было |
| 42 | + toggleBtn.textContent = wasHidden ? 'Скрыть' : 'Читать далее'; |
| 43 | + |
| 44 | + // 3. Переключаем класс |
| 45 | + details.classList.toggle('hidden'); |
| 46 | +}); |
| 47 | + |
| 48 | +// Задание 2: |
| 49 | +// Нужно написать JavaScript-код, который при клике на любую из кнопок-вкладок (.tab-btn) делает следующее: |
| 50 | +// 1. Убирает класс active со всех кнопок. |
| 51 | +// 2. Убирает класс active со всех панелей с контентом (.tab-pane). |
| 52 | +// 3. Добавляет класс active только той кнопке, по которой кликнули. |
| 53 | +// 4. Находит соответствующую панель с контентом и добавляет ей класс active. (Подсказка: кнопки и панели связаны. У кнопки есть data-tab="tab1", а у панели id="tab1"). |
| 54 | +/* |
| 55 | +<div class="tabs-container"> |
| 56 | + <div id="tabs-buttons"> |
| 57 | + <button class="tab-btn active" data-tab="tab1">Котики</button> |
| 58 | + <button class="tab-btn" data-tab="tab2">Собачки</button> |
| 59 | + <button class="tab-btn" data-tab="tab3">Еноты</button> |
| 60 | + </div> |
| 61 | + <div id="tabs-content"> |
| 62 | + <div class="tab-pane active" id="tab1">Содержимое про котиков 😺</div> |
| 63 | + <div class="tab-pane" id="tab2">Содержимое про собачек 🐶</div> |
| 64 | + <div class="tab-pane" id="tab3">Содержимое про енотов 🦝</div> |
| 65 | + </div> |
| 66 | +</div> |
| 67 | +*/ |
| 68 | + |
| 69 | +const tabsContainer = document.querySelector('.tabs-container'); |
| 70 | +const allTabBtn = document.querySelectorAll('.tab-btn'); |
| 71 | +const allTabPanel = document.querySelectorAll('.tab-pane'); |
| 72 | + |
| 73 | +function activeManipulation(event) { |
| 74 | + const target = event.target; |
| 75 | + |
| 76 | + if (target.tagName === 'BUTTON') { |
| 77 | + allTabBtn.forEach((tabBtn) => { |
| 78 | + tabBtn.classList.remove('active'); |
| 79 | + }); |
| 80 | + |
| 81 | + allTabPanel.forEach((panel) => { |
| 82 | + panel.classList.remove('active'); |
| 83 | + }); |
| 84 | + |
| 85 | + target.classList.add('active'); |
| 86 | + const tabValue = target.dataset.tab; |
| 87 | + |
| 88 | + // allTabPanel.forEach((panel) => { |
| 89 | + // if (panel.id === tabValue) { |
| 90 | + // panel.classList.add('active'); |
| 91 | + // } |
| 92 | + // }); |
| 93 | + |
| 94 | + // ?? что бы не перебирать все элементы.. можно сразу по ID отрабатывать |
| 95 | + const targetPanel = document.getElementById(tabValue); |
| 96 | + targetPanel.classList.add('active'); |
| 97 | + } |
| 98 | +} |
| 99 | + |
| 100 | +tabsContainer.addEventListener('click', activeManipulation); |
| 101 | + |
| 102 | +// Задание 3: |
| 103 | +// Создать работающий "аккордеон". |
| 104 | +/* |
| 105 | +<div class="accordion"> |
| 106 | + <div class="accordion-item"> |
| 107 | + <h3 class="accordion-header">Раздел 1</h3> |
| 108 | + <div class="accordion-content"> |
| 109 | + <p>Содержимое первого раздела. Оно изначально скрыто.</p> |
| 110 | + </div> |
| 111 | + </div> |
| 112 | + <div class="accordion-item"> |
| 113 | + <h3 class="accordion-header">Раздел 2</h3> |
| 114 | + <div class="accordion-content"> |
| 115 | + <p>Содержимое второго раздела. Оно также скрыто.</p> |
| 116 | + </div> |
| 117 | + </div> |
| 118 | + <div class="accordion-item"> |
| 119 | + <h3 class="accordion-header">Раздел 3</h3> |
| 120 | + <div class="accordion-content"> |
| 121 | + <p>Содержимое третьего раздела. И оно тоже скрыто.</p> |
| 122 | + </div> |
| 123 | + </div> |
| 124 | +</div> |
| 125 | +*/ |
| 126 | +// Напиши JavaScript, который при клике на любой заголовок (.accordion-header): |
| 127 | +// 1. Переключает класс active у нажатого заголовка. |
| 128 | +// 2. Бонус (сложная часть): Сделай так, чтобы одновременно мог быть открыт только один раздел. То есть, при открытии нового раздела, любой другой, который был открыт до этого, должен закрыться. |
| 129 | +// Намёк: Обрати внимание на CSS. Тебе не нужно напрямую стилизовать или скрывать .accordion-content. Вся магия происходит, когда ты добавляешь/убираешь класс active у заголовка .accordion-header. |
| 130 | + |
| 131 | +const accordion = document.querySelector('.accordion'); |
| 132 | +const allAccHeaders = document.querySelectorAll('.accordion-header'); |
| 133 | + |
| 134 | +function openCloseAccordion(event) { |
| 135 | + const target = event.target; |
| 136 | + |
| 137 | + // определение "именно" заголовка |
| 138 | + if (target.classList.contains('accordion-header')) { |
| 139 | + // проверка состояния (закрыт.. открыт) |
| 140 | + const isAlreadyActive = target.classList.contains('active'); |
| 141 | + |
| 142 | + // закрытие всех элементов |
| 143 | + allAccHeaders.forEach((header) => { |
| 144 | + header.classList.remove('active'); |
| 145 | + }); |
| 146 | + |
| 147 | + // исходя из первичного состояния, далее.. открытие или закрытие |
| 148 | + if (!isAlreadyActive) { |
| 149 | + target.classList.add('active'); |
| 150 | + } |
| 151 | + } |
| 152 | +} |
| 153 | + |
| 154 | +accordion.addEventListener('click', openCloseAccordion); |
0 commit comments