Вопрос или проблема
Я немного новичок в этом, так что извините, если мои объяснения немного глупые.
Мы используем пользовательские блоки Гутенберга на нашем сайте. Один из них — это блок FAQ, где вы можете добавлять вопросы и ответы, которые отображаются как кликаемые аккордеоны.
Если я добавляю более 1 такого блока, то нажатие на первый аккордеон в одном блоке также откроет первый аккордеон в последующем блоке.
<?php if( $questions ) : ?>
<div class="offset-xl-1 col-xl-8">
<div class="<?php echo $class.'__questions'; ?> accordion accordion-flush" id="faq-<?php echo $block['id'] ;?>">
<?php foreach( $questions as $index => $question ) :
$collapsed = ' collapsed';
$show = '';
$aria_expanded = 'false';
if( $index == 0 && $open_first_question ) {
$collapsed = '';
$show = ' show';
$aria_expanded = 'true';
}
?>
<div class="accordion-item">
<h3 class="accordion-header" id="faq-heading-<?php echo $index; ?>">
<button class="accordion-button<?php echo $collapsed; ?>" type="button" data-bs-toggle="collapse" data-bs-target="#faq-answer-<?php echo $index; ?>" aria-expanded="<?php echo $aria_expanded; ?>" aria-controls="faq-answer-<?php echo $index; ?>">
<?php echo $question['question']; ?>
</button>
</h3>
<div id="faq-answer-<?php echo $index; ?>" class="accordion-collapse collapse<?php echo $show; ?>" aria-labelledby="faq-answer-<?php echo $index; ?>" data-bs-parent="#faq-<?php echo $block['id'] ;?>">
<div class="accordion-body">
<?php echo $question['answer']; ?>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
Я хотел узнать, есть ли способ сделать так, чтобы переменная $index всегда имела уникальное значение между блоками?
Ответ или решение
Уникальные значения индексной переменной в PHP при использовании многократного цикла foreach в блоках Gutenberg
Использование блоков Gutenberg для создания динамического контента — это мощный инструмент, позволяющий разработчикам настраивать и управлять элементами веб-страниц. Однако, как вы заметили, один из проблем, с которыми можно столкнуться — это идентификация элементов внутри циклов, когда несколько блоков однотипного контента могут вызывать конфликты, например, при использовании аккордеонов для вопросов и ответов.
Проблема: Общие индексы переменной
В вашем коде переменная $index
используется в качестве уникального идентификатора для каждого элемента аккордеона. Однако, если у вас есть несколько блоков FAQ на одной странице, при использовании foreach
, к каждому элементу будет назначен один и тот же индекс (например, 0, 1 и т.д.). Поэтому, клик по кнопке аккордеона в одном блоке может повлиять на аккордеоны в других блоках, так как все аккордеоны будут с одинаковыми идентификаторами.
Решение: Создание уникальных значений индекса
Для того чтобы уникально идентифицировать элементы в каждом блоке, нужно модифицировать код таким образом, чтобы индекс переменной $index
получал уникальное значение на основе идентификатора самого блока. Рассмотрим возможный способ реализации:
- Составление уникального идентификатора для каждого элемента: Вместо использования только
$index
для создания идентификаторов, мы можем комбинировать идентификатор блока с текущим индексом. Это убережет вас от конфликта имен.
Пример изменения кода
Вот переработанный вариант вашего кода с уникальными id
для каждого аккордеона:
<?php if( $questions ) : ?>
<div class="offset-xl-1 col-xl-8">
<div class="<?php echo $class.'__questions'; ?> accordion accordion-flush" id="faq-<?php echo $block['id']; ?>">
<?php foreach( $questions as $index => $question ) :
$collapsed = ' collapsed';
$show = '';
$aria_expanded = 'false';
if( $index == 0 && $open_first_question ) {
$collapsed = '';
$show = ' show';
$aria_expanded = 'true';
}
// Создание уникального индекса
$unique_index = $block['id'] . '-' . $index;
?>
<div class="accordion-item">
<h3 class="accordion-header" id="faq-heading-<?php echo $unique_index; ?>">
<button class="accordion-button<?php echo $collapsed; ?>" type="button" data-bs-toggle="collapse" data-bs-target="#faq-answer-<?php echo $unique_index; ?>" aria-expanded="<?php echo $aria_expanded; ?>" aria-controls="faq-answer-<?php echo $unique_index; ?>">
<?php echo $question['question']; ?>
</button>
</h3>
<div id="faq-answer-<?php echo $unique_index; ?>" class="accordion-collapse collapse<?php echo $show; ?>" aria-labelledby="faq-answer-<?php echo $unique_index; ?>" data-bs-parent="#faq-<?php echo $block['id']; ?>">
<div class="accordion-body">
<?php echo $question['answer']; ?>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
Объяснение изменений
-
Уникальный индекс: Конструкция
$unique_index = $block['id'] . '-' . $index;
создает уникальный идентификатор, комбинируя идентификатор блока и текущий индекс, что позволяет избежать конфликта. -
Обновление идентификаторов: После этого все соответствующие атрибуты
id
,data-bs-target
, иaria-labelledby
были обновлены, чтобы использовать новый уникальный индекс.
Заключение
Оптимизация кода вышеуказанным способом позволяет избежать нежелательного поведения аккордеонов, гарантируя, что каждый элемент будет иметь уникальные идентификаторы на странице. Это улучшает опыт пользователя и делает разработку более управляемой и предсказуемой. Используйте этот подход в своих проектах для создания надежного кода, который не будет конфликтовать при использовании нескольких экземпляров одного блока.