Вопрос или проблема
На моем сайте есть пользовательский тип записи. Каждая пользовательская запись имеет миниатюру человека и дополнительное пользовательское поле с другим изображением. Я написал код, чтобы при наведении курсора на миниатюру человека показывалась альтернативная миниатюра. Это сделано на JS.
Все механически работает хорошо, (я использовал wp_enqueue_script и wp_localize_script, получив помощь отсюда!), но вместо того, чтобы у каждой миниатюры человека отображалась соответствующая альтернативная миниатюра при наведении, они все видели одно и то же изображение. Это было последнее, которое было записано в массив (они все перезаписывались в цикле).
Мой новый подход (который я не знаю, правильно ли это) заключается в том, чтобы записать ID записи в первую половину массива, а затем соответствующую миниатюру во вторую половину.
Все это кажется работающим, когда я делаю echo в PHP, но я не уверн, как это передать в Javascript.
Предположим, ID записи 23, я попробовал просто написать alert(MyScriptParams.23); но это не сработало.
Я не совсем могу понять область видимости, что бы я сделал, если было бы 100 человек? Я предполагаю, что мне нужно написать отдельный цикл в JS, чтобы пройтись по всему? У меня возникают трудности с связью между PHP и JS…
Любая помощь будет очень полезна! Возможно, я делаю что-то глупое!
page-custom.php
<?php
$args = array( 'post_type' => 'drummers', 'orderby' => 'menu_order');
$your_loop = new WP_Query( $args );
//ПОЛУЧАЕТ ЗАПИСИ
if ( $your_loop->have_posts() ) : while ( $your_loop->have_posts() ) :
$your_loop->the_post();
//ПОЛУЧАЕТ ID ЗАПИСИ С ПОМОЩЬЮ WP_QUERY
$gettheid = get_the_ID();
if ( has_post_thumbnail() ) {
the_post_thumbnail('', array( 'class' => "img-fluid animated drummers_face$post_id"));
}
$meta = get_post_meta( $post->ID, 'drummers_fields', true );
$thumbnail_url = get_the_post_thumbnail_url($post->ID);
wp_localize_script('animated', 'MyScriptParams',
$array = array(
$gettheid => $meta['image']
//'bar' => $thumbnail_url
));
//ЭТО ЭХО ДЕЛАЕТСЯ ХОРОШО
echo $array[$gettheid];
?>
<?php the_title(); ?>
<?php the_content(); ?>
</div><!-- КОНЕЦ СТОЛБЦА-->
<?php endwhile; endif; wp_reset_postdata(); ?>
Javascript – У меня есть код, чтобы показать новую миниатюру при наведении, но я держу его простым и пытаюсь сначала просто сделать alert
alert(MyScriptParams.23);
Обновление
Я переместил localize_script за пределы цикла, добавил счетчик, который проходит через массив, но все равно имею ту же проблему.
<?php
$args = array( 'post_type' => 'drummers', 'orderby' => 'menu_order');
$counter = 0;
$bigid = array();
$your_loop = new WP_Query( $args );
if ( $your_loop->have_posts() ) : while ( $your_loop->have_posts() ) :
$your_loop->the_post();
array_push( $bigid, get_the_ID() );
?>
<div class="col-md-4">
<?php
if ( has_post_thumbnail() ) {
the_post_thumbnail('', array( 'class' => "img-fluid animated drummers_face$post_id"));
}
$meta = get_post_meta( $post->ID, 'drummers_fields', true );
$thumbnail_url = get_the_post_thumbnail_url($post->ID);
$array = array(
$bigid[$counter] => $meta['image']
//'bar' => $thumbnail_url
);
echo $bigid[$counter];
$counter++;
?>
<?php the_title(); ?>
<?php the_content(); ?>
</div><!-- КОНЕЦ СТОЛБЦА-->
<?php endwhile; endif; wp_reset_postdata(); ?>
<?php wp_localize_script('animated', 'MyScriptParams', $array); ?>
Это потому, что вы вызываете локализацию скрипта внутри цикла. Вместо этого сохраните массив идентификаторов и т.д., а затем запустите локализацию скрипта снаружи/после того, как вы его настроите.
Все, что делает локализация скрипта, это внедряет параметры, которые вы передаете в него, в глобальную область видимости js/jquery, позволяя вам ссылаться на них. Тем не менее, локализация скрипта не является кумулятивной, вместо этого вы просто перезаписываете ее снова и снова (в результате чего вы видите только последний идентификатор цикла, а все остальные идентификаторы остаются неопределенными).
Посмотрев еще раз, я вижу еще одну проблему:
$array = array(
$bigid[$counter] => $meta['image']
//'bar' => $thumbnail_url
);
Должно быть
$array[] = array(
$bigid[$counter] => $meta['image']
//'bar' => $thumbnail_url
);
Суть в том, что в первом случае вы сбрасываете $array снова и снова, тогда как во втором случае вы фактически добавляете данные в массив.
Также вам стоит убедиться, что перед циклом, перед итерацией, вы определяете $array = array(). Это все равно будет работать, но если вы не определите это заранее, то получите предупреждения PHP.
В качестве третьего варианта вы также можете сделать:
$array[$bigid[$counter]] = $meta['image'];
Поскольку вы, похоже, новички, я бы действительно попробовал оба варианта и сделал сброс/консольный лог, чтобы увидеть разницу в структуре данных, которую они создают.
Ответ или решение
Для решения проблемы, связанной с корректным отображением альтернативных миниатюр по наведению курсора на основную миниатюру в вашей пользовательской теме WordPress, необходимо правильно организовать передачу данных из PHP в JavaScript. Мы рассмотрим, как избежать переопределения значений при итерации в цикле и как эффективно передавать результат в JavaScript.
Введение
Ваша задача — добиться корректного сопоставления постов и их дополнительных изображений, чтобы при наведении на миниатюру отображалось соответствующее изображение. Для этого мы воспользуемся функцией wp_localize_script
, которая позволяет передавать массивы данных из PHP в JavaScript, делая их доступными в глобальной области видимости.
Шаг 1: Формирование массива в PHP
Начнем с создания массива, в который будут собраны идентификаторы постов и соответствующие им альтернативные миниатюры. Важно правильно инициализировать массив и заполнять его вне цикла, чтобы избежать перезаписи данных.
<?php
$args = array('post_type' => 'drummers', 'orderby' => 'menu_order');
$your_loop = new WP_Query($args);
$image_data = array(); // Инициализация массива
if ($your_loop->have_posts()) :
while ($your_loop->have_posts()) :
$your_loop->the_post();
$post_id = get_the_ID(); // Получаем ID поста
$meta = get_post_meta($post_id, 'drummers_fields', true); // Получаем мета-данные
// Проверяем наличие миниатюры
if (has_post_thumbnail()) {
the_post_thumbnail('', array('class' => "img-fluid animated drummers_face$post_id"));
}
// Заполняем массив ID поста и соответствующее изображение
$image_data[$post_id] = $meta['image'];
// Печатаем заголовок и контент поста
the_title();
the_content();
endwhile;
wp_reset_postdata();
endif;
// Передаем данные в JavaScript
wp_localize_script('animated', 'MyScriptParams', $image_data);
?>
Шаг 2: Доступ к данным в JavaScript
Теперь, когда мы передали данные в JavaScript, мы можем получить к ним доступ. Допустим, вы хотите отобразить альтернативное изображение при наведении на миниатюру. Вам нужно будет создать обработчик события в JavaScript.
<script>
document.addEventListener("DOMContentLoaded", function() {
// Перебираем все миниатюры
document.querySelectorAll('.animated').forEach(function(element) {
element.addEventListener('mouseover', function() {
const postId = this.classList[2].split('drummers_face')[1]; // Извлекаем ID поста
if (MyScriptParams[postId]) {
alert(MyScriptParams[postId]); // Отображаем соответствующее изображение
}
});
});
});
</script>
Объяснение работы кода
-
PHP: Мы создаем массив
$image_data
, где ключами являются ID постов, а значениями — ссылки на альтернативные миниатюры. Эти данные передаются в JavaScript с помощьюwp_localize_script
. -
JavaScript: После загрузки страницы скрипт находит все элементы с классом
.animated
, добавляет обработчик событияmouseover
. При наведении на миниатюру извлекается ID поста, и в случае наличия соответствующего изображения вMyScriptParams
, оно показывается.
Заключение
Этот подход позволяет корректно сопоставить миниатюры и их альтернативные изображения без перезаписи данных. Убедитесь, что вы правильно настроили классы для элементов, чтобы обработчик событий мог их распознавать. С таким решением вы создадите динамичное и интуитивно понятное взаимодействие для пользователей вашего сайта.