基于Django模型日期实现同页面多Javascript倒计时器问题求助
问题根因
你当前的写法有两个核心问题:
- 你将完整JS脚本放在Django的模型遍历循环中,会重复渲染多段完全相同的JS代码,全局定义的
targetdate变量会被循环中后续的模型日期覆盖,最终只会保留最后/第一个模型的日期值。 - JS内部遍历所有倒计时容器时,所有容器都统一使用了全局的
targetdate计算,没有和每个模型对应的日期做绑定。
实现思路
不用把JS放在Django循环里,只需要把每个模型的目标日期存到对应倒计时容器的自定义数据属性中,JS全局只加载一次,遍历容器时直接读取每个容器自带的日期值即可。
完整实现代码
1. 修改Django模板的倒计时容器渲染逻辑
给每个容器加data-target-date属性存储对应模型的Unix时间戳:
{% for datemodel in your_queryset %} <!-- 这里替换成你实际的Django循环变量名 --> <div class="clockdiv" data-target-date="{{ datemodel.dateinmodel|date:"U" }}"> <div> 倒计时至目标日期- <span class="days"></span>天 <span class="hours"></span>时 <span class="minutes"></span>分 <span class="seconds"></span>秒 </div> </div> {% endfor %}
2. 替换原来的JS代码
JS代码只需要在页面放一次,不需要放到Django循环内:
document.addEventListener('readystatechange', event => { if (event.target.readyState === "complete") { const clockdivs = document.getElementsByClassName("clockdiv"); const countDownList = []; // 遍历每个倒计时容器,读取自带的目标日期 for (let i = 0; i < clockdivs.length; i++) { const el = clockdivs[i]; // 从自定义属性读取时间戳,转成JS要求的毫秒级时间戳 const targetTimestamp = parseInt(el.dataset.targetDate) * 1000; countDownList.push({ el: el, time: new Date(targetTimestamp).getTime() }); } // 每秒更新所有倒计时 setInterval(() => { const now = new Date().getTime(); countDownList.forEach(item => { const distance = item.time - now; let days = 0, hours = 0, minutes = 0, seconds = 0; if (distance > 0) { days = Math.floor(distance / (1000 * 60 * 60 * 24)); hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)); seconds = Math.floor((distance % (1000 * 60)) / 1000); } // 写入对应DOM节点 item.el.querySelector('.days').textContent = days; item.el.querySelector('.hours').textContent = hours; item.el.querySelector('.minutes').textContent = minutes; item.el.querySelector('.seconds').textContent = seconds; }); }, 1000); } });
内容的提问来源于stack exchange,提问作者Marcy
相关产品推荐
相关产品推荐

