设置唯一ID后所有商品倒计时仍统一为最后一个商品时间的原因及解决方案
问题根源
- 全局作用域变量/函数覆盖:你在PHP循环中重复声明全局变量
startdate、stopdate和全局函数auctionStart,JS全局作用域下同名声明会被后续值覆盖,所有倒计时逻辑最终都读取到最后一次循环的时间参数,因此全部显示最后一个商品的倒计时。 - 笔误:代码中选择器里将
product_id拼写为prduct_id,会导致部分DOM元素匹配失败。
正确实现方案
不要把JS逻辑写在PHP循环里,通过DOM自定义属性存储每个商品的独立时间参数,页面加载完成后统一初始化所有倒计时:
第一步:改造HTML结构,存储自定义参数
<head> <link rel="stylesheet" href="catalog/view/javascript/countdown/css/jquery.countdown.css"> <script src="catalog/view/javascript/countdown/js/jquery.plugin.min.js"></script> <script src="catalog/view/javascript/countdown/js/jquery.countdown.js"></script> </head> <body> <?php foreach ($products as $product): ?> <!-- 把商品时间存到data属性里 --> <div class="auction-counter" id="auction-counter-<?php echo $product['product_id']; ?>" data-start-time="<?php echo $product['start_time']; ?>" data-stop-time="<?php echo $product['stop_time']; ?>"> </div> <?php endforeach; ?>
第二步:统一写初始化JS,放在body末尾
<script> $(function() { // 遍历所有倒计时元素,各自独立初始化 $('.auction-counter').each(function() { const $counter = $(this); const startDate = new Date($counter.data('start-time')); const stopDate = new Date($counter.data('stop-time')); // 定义当前元素专属的到期回调 function auctionClosed() { $counter.countdown('destroy'); } function auctionStop() { $counter.countdown('destroy').countdown({ until: stopDate, onExpiry: auctionClosed, format: 'DHMS', padZeroes: true, alwaysExpire: true }); } // 初始化倒计时到开始时间 $counter.countdown({ until: startDate, onExpiry: auctionStop, format: 'DHMS', padZeroes: true, alwaysExpire: true }); }); }); </script> </body>
这样每个倒计时元素的参数都从自己的DOM属性读取,回调也绑定到当前元素,不会出现互相覆盖的问题,代码结构也更清晰易维护。
内容的提问来源于stack exchange,提问作者user17225961
相关产品推荐
相关产品推荐

