PageSpeed рекомендує позбавлятись від бібліотек типу jQuery то ж рекомендуємо використовувати чистий JavaScript 

В даному прикладі використовуємо стандартний модуль Joomla 6 для виводу матеріалів. Але можна цей приклад застосовувати для інших CMS чи самописних кодів. Для пришвидшення роботи сайту PageSpeed рекомендує позбавлятись від бібліотек типу jQuery тому бажано використовувати чистий JavaScript.

Щоб перетворити масив даних на FAQ-акордеон, нам потрібно:

  1. Спростити структуру: Прибрати зайві дати, авторів та посилання на окремі сторінки (у FAQ вони зазвичай заважають).
  2. Додати CSS для анімації: Зробити так, щоб відповідь була прихована і плавно з'являлася при кліку на питання.
  3. Додати JS: Для обробки кліку.

Ось як орієнтовно має виглядати код сторінки чи файл шаблону модуля default_faq.php:

<?php

$doc = Factory::getApplication()->getDocument();

// Додаємо стилі для акордеона
$style = "
.faq-container { list-style: none; padding: 0; margin: 0; }
.faq-item { border-bottom: 1px solid #eee; margin-bottom: 5px; background: #fff; }
.faq-question {
width: 100%; padding: 15px 20px; text-align: left;
background: #f9f9f9; border: none; outline: none;
cursor: pointer; display: flex; justify-content: space-between; align-items: center;
font-weight: bold; transition: 0.3s; margin: 0;
}
.faq-question:hover { background: #f0f0f0; }
.faq-question::after { content: '+'; font-size: 20px; color: #ff6600; } /* Колір евакуатора */
.faq-item.active .faq-question::after { content: '−'; }
.faq-item.active .faq-question { background: #fff; color: #ff6600; }.faq-answer {
max-height: 0; overflow: hidden; transition: max-height 0.3s ease-out;
background: #fff;
}
.faq-answer-content { padding: 15px 20px; border-top: 1px solid #eee; line-height: 1.6; }
";
$doc->addStyleDeclaration($style);
?>

<ul class="faq-container">
<?php foreach ($items as $index => $item) : ?>
<li class="faq-item">
<button class="faq-question" type="button">
<?php echo htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8'); ?>
</button>
<div class="faq-answer">
<div class="faq-answer-content">
<?php echo $item->displayIntrotext; ?>
</div>
</div>
</li>
<?php endforeach; ?>
</ul>

<script>
document.querySelectorAll('.faq-question').forEach(button => {
button.addEventListener('click', () => {
const faqItem = button.parentElement;
const isActive = faqItem.classList.contains('active');

// Закриваємо всі інші відкриті питання (опціонально)
document.querySelectorAll('.faq-item').forEach(item => {
item.classList.remove('active');
item.querySelector('.faq-answer').style.maxHeight = null;
});

// Відкриваємо поточне
if (!isActive) {
faqItem.classList.add('active');
const answer = faqItem.querySelector('.faq-answer');
answer.style.maxHeight = answer.scrollHeight + "px";
}
});
});
</script>

2. Чому ми зробили саме так?

  1. Семантика: Використати кнопки <button>. Це правильно для доступності (accessibility) — екранні читці розуміють, що це інтерактивний елемент.
  2. scrollHeight: В JavaScript ми не просто міняємо display: block/none, а вираховуємо реальну висоту контенту. Це дозволяє зробити анімацію розгортання дуже плавною.
  3. Чистота: Залишили тільки питання - в якості кнопок, та відповіді.

3. На що звернути увагу?

  • Символи: Використовуються прості + та −. Їх можна замінити на іконки (наприклад, FontAwesome або SVG), які ти вже використовував у модулі.
  • Текст: Відповідь береться з displayIntrotext. Тобто все, що ти напишеш у статті до тегу "Читати далі" (або вся стаття, якщо тегу немає), стане відповіддю.