Заполните массив в цикле, а затем считайте массив в JS.

Вопрос или проблема

На моем сайте есть пользовательский тип записи. Каждая пользовательская запись имеет миниатюру человека и дополнительное пользовательское поле с другим изображением. Я написал код, чтобы при наведении курсора на миниатюру человека показывалась альтернативная миниатюра. Это сделано на 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>

Объяснение работы кода

  1. PHP: Мы создаем массив $image_data, где ключами являются ID постов, а значениями — ссылки на альтернативные миниатюры. Эти данные передаются в JavaScript с помощью wp_localize_script.

  2. JavaScript: После загрузки страницы скрипт находит все элементы с классом .animated, добавляет обработчик события mouseover. При наведении на миниатюру извлекается ID поста, и в случае наличия соответствующего изображения в MyScriptParams, оно показывается.

Заключение

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

Оцените материал
Добавить комментарий

Капча загружается...