Как вывести изображение выбранной вариации Woocommerce в слайдер Swiper JS?
Не меняется изображения, если выбираю вариацию
Для ссылки fancybox атрибут src меняется, а для img нет. Есть ли какие варианты?
<?php /** * Single Product Image * * This template can be overridden by copying it to yourtheme/woocommerce/single-product/product-image.php. * * HOWEVER, on occasion WooCommerce will need to update template files and you * (the theme developer) will need to copy the new files to your theme to * maintain compatibility. We try to do this as little as possible, but it does * happen. When this occurs the version of the template file will be bumped and * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ * @package WooCommerceTemplates * @version 7.8.0 */ defined( 'ABSPATH' ) || exit; // Note: `wc_get_gallery_image_html` was added in WC 3.3.2 and did not exist prior. This check protects against theme overrides being used on older versions of WC. if ( ! function_exists( 'wc_get_gallery_image_html' ) ) { return; } global $product; $columns = apply_filters( 'woocommerce_product_thumbnails_columns', 4 ); $post_thumbnail_id = $product->get_image_id(); $wrapper_classes = apply_filters( 'woocommerce_single_product_image_gallery_classes', array( 'woocommerce-product-gallery', 'woocommerce-product-gallery--' . ( $post_thumbnail_id ? 'with-images' : 'without-images' ), 'woocommerce-product-gallery--columns-' . absint( $columns ), 'images', ) ); ?> <div class="<?php echo esc_attr( implode( ' ', array_map( 'sanitize_html_class', $wrapper_classes ) ) ); ?>" data-columns="<?php echo esc_attr( $columns ); ?>" style="opacity: 0; transition: opacity .25s ease-in-out;"> <div class="slider__images <?php echo esc_attr( implode( ' ', array_map( 'sanitize_html_class', $wrapper_classes ) ) ); ?>"> <div class="swiper-container"> <!-- Слайдер с изображениями --> <div class="swiper-wrapper"> <?php if ( has_post_thumbnail() ) : ?> <div class="slider__images_slide swiper-slide woocommerce-product-gallery__image"> <a href="<?php the_post_thumbnail_url(); ?>" data-fancybox="gallery"> <img src="<?php the_post_thumbnail_url(); ?>" width="499" height="374"> </a> </div> <?php echo apply_filters( 'woocommerce_single_product_image_thumbnail_html', $html, $post_thumbnail_id ); // phpcs:disable WordPress.XSS.EscapeOutput.OutputNotEscaped do_action( 'woocommerce_product_thumbnails' ); ?> <?php endif; ?> <?php global $product; $attachment_ids = $product->get_gallery_attachment_ids(); foreach( $attachment_ids as $attachment_id ) { ?> <div class="slider__images_slide swiper-slide woocommerce-product-gallery__image"> <a href="<?php echo $image_link = wp_get_attachment_url( $attachment_id ); ?>" data-fancybox="gallery"> <img src="<?php echo $image_link = wp_get_attachment_url( $attachment_id ); ?>" class="wp-post-image" width="499" height="374"> </a> </div> <?php echo apply_filters( 'woocommerce_single_product_image_thumbnail_html', $html, $post_thumbnail_id ); // phpcs:disable WordPress.XSS.EscapeOutput.OutputNotEscaped do_action( 'woocommerce_product_thumbnails' ); ?> <?php } ?> </div> </div> <?php if ($product->get_gallery_attachment_ids()) { ?> <div class="slider__nav"> <div class="pagination"></div> <div class="slider__nav__buttons"> <div class="btn-product-prev"></div> <div class="btn-product-next"></div> </div> </div> <?php } ?> </div> </div> |
<?php /** * Single Product Image * * This template can be overridden by copying it to yourtheme/woocommerce/single-product/product-image.php. * * HOWEVER, on occasion WooCommerce will need to update template files and you * (the theme developer) will need to copy the new files to your theme to * maintain compatibility. We try to do this as little as possible, but it does * happen. When this occurs the version of the template file will be bumped and * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ * @package WooCommerceTemplates * @version 7.8.0 */ defined( 'ABSPATH' ) || exit; // Note: `wc_get_gallery_image_html` was added in WC 3.3.2 and did not exist prior. This check protects against theme overrides being used on older versions of WC. if ( ! function_exists( 'wc_get_gallery_image_html' ) ) { return; } global $product; $columns = apply_filters( 'woocommerce_product_thumbnails_columns', 4 ); $post_thumbnail_id = $product->get_image_id(); $wrapper_classes = apply_filters( 'woocommerce_single_product_image_gallery_classes', array( 'woocommerce-product-gallery', 'woocommerce-product-gallery--' . ( $post_thumbnail_id ? 'with-images' : 'without-images' ), 'woocommerce-product-gallery--columns-' . absint( $columns ), 'images', ) ); ?> <div class="<?php echo esc_attr( implode( ' ', array_map( 'sanitize_html_class', $wrapper_classes ) ) ); ?>" data-columns="<?php echo esc_attr( $columns ); ?>" style="opacity: 0; transition: opacity .25s ease-in-out;"> <div class="slider__images <?php echo esc_attr( implode( ' ', array_map( 'sanitize_html_class', $wrapper_classes ) ) ); ?>"> <div class="swiper-container"> <!-- Слайдер с изображениями --> <div class="swiper-wrapper"> <?php if ( has_post_thumbnail() ) : ?> <div class="slider__images_slide swiper-slide woocommerce-product-gallery__image"> <a href="<?php the_post_thumbnail_url(); ?>" data-fancybox="gallery"> <img src="<?php the_post_thumbnail_url(); ?>" width="499" height="374"> </a> </div> <?php echo apply_filters( 'woocommerce_single_product_image_thumbnail_html', $html, $post_thumbnail_id ); // phpcs:disable WordPress.XSS.EscapeOutput.OutputNotEscaped do_action( 'woocommerce_product_thumbnails' ); ?> <?php endif; ?> <?php global $product; $attachment_ids = $product->get_gallery_attachment_ids(); foreach( $attachment_ids as $attachment_id ) { ?> <div class="slider__images_slide swiper-slide woocommerce-product-gallery__image"> <a href="<?php echo $image_link = wp_get_attachment_url( $attachment_id ); ?>" data-fancybox="gallery"> <img src="<?php echo $image_link = wp_get_attachment_url( $attachment_id ); ?>" class="wp-post-image" width="499" height="374"> </a> </div> <?php echo apply_filters( 'woocommerce_single_product_image_thumbnail_html', $html, $post_thumbnail_id ); // phpcs:disable WordPress.XSS.EscapeOutput.OutputNotEscaped do_action( 'woocommerce_product_thumbnails' ); ?> <?php } ?> </div> </div> <?php if ($product->get_gallery_attachment_ids()) { ?> <div class="slider__nav"> <div class="pagination"></div> <div class="slider__nav__buttons"> <div class="btn-product-prev"></div> <div class="btn-product-next"></div> </div> </div> <?php } ?> </div> </div>
Дополнительно:
проблема в JS а не в PHP
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
В вариативном товаре WooCommerce изображение выбранной вариации приходит во фронтенд в событии
found_variation. Если у вас меняется толькоhrefдля Fancybox, но не меняетсяimg src, значит ваш JS обновляет ссылку, но не обновляет сам тег изображения или Swiper не пересчитывается после замены слайда.Базовая схема для Swiper такая:
jQuery(function ($) { const $form = $('.variations_form'); const swiperEl = document.querySelector('.product-gallery-swiper'); if (!$form.length || !swiperEl || !swiperEl.swiper) { return; } const swiper = swiperEl.swiper; $form.on('found_variation', function (event, variation) { if (!variation || !variation.image || !variation.image.src) { return; } const imageUrl = variation.image.full_src || variation.image.src; const thumbUrl = variation.image.src; const slide = swiper.slides[0]; const link = slide.querySelector('a'); const img = slide.querySelector('img'); if (link) { link.setAttribute('href', imageUrl); link.setAttribute('data-src', imageUrl); } if (img) { img.setAttribute('src', thumbUrl); img.setAttribute('srcset', variation.image.srcset || ''); img.setAttribute('alt', variation.image.alt || ''); } swiper.slideTo(0); swiper.update(); }); });jQuery(function ($) { const $form = $('.variations_form'); const swiperEl = document.querySelector('.product-gallery-swiper'); if (!$form.length || !swiperEl || !swiperEl.swiper) { return; } const swiper = swiperEl.swiper; $form.on('found_variation', function (event, variation) { if (!variation || !variation.image || !variation.image.src) { return; } const imageUrl = variation.image.full_src || variation.image.src; const thumbUrl = variation.image.src; const slide = swiper.slides[0]; const link = slide.querySelector('a'); const img = slide.querySelector('img'); if (link) { link.setAttribute('href', imageUrl); link.setAttribute('data-src', imageUrl); } if (img) { img.setAttribute('src', thumbUrl); img.setAttribute('srcset', variation.image.srcset || ''); img.setAttribute('alt', variation.image.alt || ''); } swiper.slideTo(0); swiper.update(); }); });
Если Fancybox уже инициализирован, после замены ссылок может потребоваться обновить/переинициализировать Fancybox по документации вашей версии. Но чаще достаточно менять
hrefиdata-src.В шаблоне
product-image.phpне удаляйте стандартные классы и data-атрибуты WooCommerce без необходимости. Вариации завязаны на.variations_formи данные, которые WooCommerce печатает в JSON. Если шаблон сильно переписан, проверьте, что на странице естьdata-product_variationsи событиеfound_variationреально срабатывает.Для отладки добавьте временно:
$('.variations_form').on('found_variation', function (event, variation) { console.log(variation.image); });$('.variations_form').on('found_variation', function (event, variation) { console.log(variation.image); });
Если в консоли нет изображения, проблема не в Swiper, а в данных вариации: у выбранной вариации не задана картинка или шаблон/плагин не отдаёт её во фронтенд.