倒计时计时器未独立运行,所有元素同步问题排查
问题原因
- 硬编码统一日期:脚本里所有计时器都用了同一个固定日期
July 15, 2023 00:00:00,自然显示相同时间。 - 重复ID导致元素选择错误:HTML里每个计时器的天/时/分/秒都用了相同的ID(
day/hour/minute/second),但ID在页面中必须唯一。querySelector("#day")会始终选中页面中最后一个带该ID的元素,所以所有计时器最终都更新最后一个item的显示内容。 - 脚本重复执行:把完整脚本放在每个
collection-item里,导致页面加载时多次遍历所有item,逻辑混乱。
解决方法
1. 修正HTML结构(替换重复ID为类)
把每个计时器的ID改成类名,同时给每个collection-item添加存储专属目标日期的data属性(日期值从Webflow集合的对应字段绑定):
<div role="listitem" class="collection-item w-dyn-item" data-countdown-date="2023-07-15T00:00:00"> <a id="000001" href="/books/000001" target="_blank" class="wrapper w-inline-block"> <h1 class="something"> <span class="countdown-day">00</span> <span class="countdown-hour">00</span> <span class="countdown-minute">00</span> <span class="countdown-second">00</span> </h1> </a> </div>
注:data-countdown-date的值要替换成Webflow集合中每个item对应的目标日期,比如绑定集合里的“截止日期”字段
2. 重构脚本(仅执行一次,放在页面底部)
移除每个item里的脚本,在页面底部(比如</body>前)添加以下脚本:
<script> // 选择所有带计时器的集合项 var countdownItems = document.querySelectorAll(".collection-item"); countdownItems.forEach(function(item) { // 从当前item的data属性获取专属目标日期 var targetDateStr = item.getAttribute("data-countdown-date"); if (!targetDateStr) return; // 无日期则跳过 var countDownDate = new Date(targetDateStr).getTime(); var timer = setInterval(function() { var now = new Date().getTime(); var distance = countDownDate - now; // 计算天/时/分/秒,补零确保两位数显示 var days = String(Math.floor(distance / (1000 * 60 * 60 * 24))).padStart(2, "0"); var hours = String(Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))).padStart(2, "0"); var minutes = String(Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60))).padStart(2, "0"); var seconds = String(Math.floor((distance % (1000 * 60)) / 1000)).padStart(2, "0"); // 更新当前item内的计时器元素(用类选择器) item.querySelector(".countdown-day").textContent = days; item.querySelector(".countdown-hour").textContent = hours; item.querySelector(".countdown-minute").textContent = minutes; item.querySelector(".countdown-second").textContent = seconds; // 倒计时结束处理 if (distance < 0) { clearInterval(timer); // 找到当前item内的announcement元素更新内容(如果有的话) var announcement = item.querySelector(".announcement"); if (announcement) announcement.textContent = "Yay!"; } }, 1000); }); </script>
额外优化点
- 用
textContent替代innerHTML,更安全且性能更好 - 用
padStart(2, "0")确保时间显示为两位数(比如05天而不是5天) - 增加了空日期判断,避免无日期的item报错
内容的提问来源于stack exchange,提问作者trell
相关产品推荐
相关产品推荐

