我有一个短代码在轮播中显示最近的 WooCommerce 产品,但是我希望最终用户能够在同一页面上多次使用该短代码,目前发生这种情况时 jQuery 轮播有冲突。
这是我用于简码的代码,
function recent_products_slider_func($atts) {
global $woocommerce_loop;
static $count = 0;
if (empty($atts)) return;
extract(shortcode_atts(array(
'title' => 'Recent Products',
'order' => 'DESC',
'orderby' => 'date',
'mousewheel' => 'false',
'autoscroll' => '1',
'swipe' => 'false',
'scroll' => '1',
'items' => 6
), $atts));
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => $items,
'ignore_sticky_posts' => 1,
'orderby' => $orderby,
'order' => $order,
'meta_query' => array(
array(
'key' => '_visibility',
'value' => array('catalog', 'visible'),
'compare' => 'IN'
)
)
);
wp_enqueue_script('owlcarouselcustom', get_template_directory_uri() . '/includes/pixelstores/shortcodes/js/' . 'owlcarousel.js');
wp_localize_script('owlcarouselcustom', 'carouselvars', array(
'autoscroll' => $autoscroll
)
);
ob_start();
$products = new WP_Query( $args );
if ( $products->have_posts() ) : ?>
<div class="row ps-carousel">
<div class="col-xs-10">
<h3><?php echo $title; ?></h3>
</div>
<div class="col-xs-2">
<div class="ps-carousel-btns">
<a class="btn prev"><i class="fa fa-angle-left" /></a>
<a class="btn next"><i class="fa fa-angle-right" /></a>
</div>
</div>
</div>
<div class="row">
<div id="owl-example" class="owl-carousel">
<?php while ( $products->have_posts() ) : $products->the_post(); ?>
<?php if ( class_exists('woocommerce') ) { woocommerce_get_template_part( 'content', 'product' ); } ?>
<?php endwhile; ?>
</div>
</div>
<?php endif;
wp_reset_query();
$count++;
return ob_get_clean();
}
add_shortcode('recent_products_slider', 'recent_products_slider_func');
对于 jQuery,我使用以下内容,
jQuery(document).ready(function($) {
var settingObj = carouselvars;
var owlcontainer = $("#owl-example");
if(settingObj.autoscroll == 1) {settingObj.autoscroll = true;} else {settingObj.autoscroll = false;}
$(owlcontainer).owlCarousel({
autoPlay: settingObj.autoscroll,
});
});
我知道为什么这不起作用但不确定什么是最佳解决方案,wp_localize_script 中的“carouselvars”句柄在没有唯一名称的情况下被调用,因此该变量被调用了两次。
非常感谢任何解决方案。
亲切的问候
我不是 jQuery 专家,但我遇到了同样的问题,我相信我有一个可行的解决方案。 问题是每次运行 wp_localize_script 时,它都会使用 $name 设置创建一个 javascript 变量。 在你的情况下是’carouselvars’。 由于这是在运行 jQuery 之前设置的,jQuery 只会“看到”传递给变量的最后一个值,因此在您的情况下,settingObj.autoscroll 将始终是短代码最后一个实例中设置的值.
我的解决方案是为 wp_localize_script 调用设置一个动态变量名称,类似于:
wp_localize_script('owlcarouselcustom', 'carouselvars' . $instance, array(
'autoscroll' => $autoscroll
)
);
$instance 可以是用户想要设置的任何值。 所以用法是:
[recent_products_slider instance=1 autoscroll=0]
[recent_products_slider instance=2 autoscroll=1]
并且您提取设置的代码需要是:
extract(shortcode_atts(array(
'title' => 'Recent Products',
'order' => 'DESC',
'orderby' => 'date',
'mousewheel' => 'false',
'autoscroll' => '1',
'swipe' => 'false',
'scroll' => '1',
'items' => 6,
'instance' => 1
), $atts));
我确信有更聪明的方法可以做到这一点,因此不需要设置任何实例,但是,就像我说的,我不是 jQuery 专家。
然后诀窍是获取正确的数据以拉入正确的短代码实例。 我是用 html5 数据类型做的。 因此,在您代码的 php 部分,我认为最好这样做:
<div id="owl-' . $instance . '" class="owl-carousel" data-instance="' . $instance . '">
然后你的 jQuery 看起来像这样:
jQuery(document).ready(function($) {
$('.owl-carousel').each(function( index ) {
var instance = $( this ).data('instance');
SetOwlCarousel(instance);
});
});
function SetOwlCarousel(instance) {
var settingObj = window["carouselvars"+instance];
var owlcontainer = $("#owl-" + instance);
if(settingObj.autoscroll == 1) {settingObj.autoscroll = true;} else {settingObj.autoscroll = false;}
jQuery(owlcontainer).owlCarousel({
autoPlay: settingObj.autoscroll,
});
});
}
所以这个 jQuery 脚本将遍历“.owl-carousel”的每个实例并在其上运行 SetOwlCarousel 函数。 在设置 settingObj 时调用窗口对象允许您评估“carouselvars”+实例到您使用 wp_localize_script 设置的变量,因此在我的示例中为 carouselvars1 和 carouselvars2。
如果有人有更简洁的方法来做到这一点,我很乐意使用它,但这应该可以满足您的需求。 我没有测试过这段代码,但它与我自己使用的代码基本相同。
提供其他一切正常 – 为了使用 ID 来定位滑块,它必须是唯一的。 因此,所有滑块容器的 ID 都不能为 #owl-example
– 它需要 #owl-example-1
, #owl-example-2
ETC。
为了完全避免这种情况,您可能想尝试使用 .owl-carousel
类代替。
