如何在ASP.NET Core MVC表格行中显示基于数据库时间的独立倒计时器?
问题分析与解决方案
你的问题核心是全局变量覆盖导致所有倒计时共用同一个时间值,加上脚本逻辑没有为每个购物车独立初始化定时器。下面是具体的修复步骤:
1. 修正Razor视图中的倒计时元素
将原来动态生成类名的<p>标签,改为使用统一类名+data属性存储每个购物车的目标倒计时时间:
<table id="example" class="table table-striped dt-responsive nowrap" width="100%" cellspacing="0"> <thead class="thead-light"> <tr> <th>@Html.DisplayNameFor(model => model.CartNumber)</th> <th>@Html.DisplayNameFor(model => model.CartType)</th> <th>@Html.DisplayNameFor(model => model.Status)</th> <th>@Html.DisplayNameFor(model => model.CustomerID)</th> <th>@Html.DisplayNameFor(model => model.Duration)</th> <th>Remaining Time</th> <th>@Html.DisplayNameFor(model => model.ImageContent)</th> </tr> </thead> <tbody> @foreach (var item in Model) { <tr> <td>@Html.DisplayFor(modelItem => item.CartNumber)</td> <td>@Html.DisplayFor(modelItem => item.CartType)</td> <td>@Html.DisplayFor(modelItem => item.Status)</td> <td>@Html.DisplayFor(modelItem => item.CustomerID)</td> <td>@Html.DisplayFor(modelItem => item.Duration)</td> <!-- 统一类名 + data属性存储目标时间 --> <td><p class="countdown-timer" data-countdown="@item.DurationCountdown"></p></td> <td><img height="50" width="70" src='@Url.Action("BookedCarts", "File", new { id = item.ID })' /></td> </tr> } </tbody> </table>
2. 编写通用的倒计时初始化脚本
移除原来循环内的重复脚本,改用一个全局脚本为每个购物车独立创建定时器,避免全局变量覆盖:
<script> document.addEventListener('DOMContentLoaded', function() { // 批量获取所有倒计时元素 const timerElements = document.querySelectorAll('.countdown-timer'); timerElements.forEach(element => { // 从当前元素的data属性中读取专属目标时间 const targetTime = new Date(element.dataset.countdown).getTime(); // 为每个元素创建独立的定时器 const intervalId = setInterval(() => { const now = new Date().getTime(); const timeLeft = targetTime - now; // 计算剩余时分秒(因为预订时长1-6小时,无需计算天数) const hours = Math.floor((timeLeft % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); const minutes = Math.floor((timeLeft % (1000 * 60 * 60)) / (1000 * 60)); const seconds = Math.floor((timeLeft % (1000 * 60)) / 1000); if (timeLeft > 0) { element.textContent = `${hours}h ${minutes}m ${seconds}s`; } else { // 倒计时结束,清除定时器并更新文本 clearInterval(intervalId); element.textContent = "EXPIRED"; // 可选:这里可以添加购物车过期后的业务逻辑,比如发送请求更新状态 } }, 1000); }); }); </script>
原代码问题总结
- 全局变量覆盖:如果原脚本写在foreach循环内,每次循环都会生成全局的
countDownDate和x变量,后续循环会覆盖前面的值,导致所有定时器共用最后一个购物车的时间。 - 元素选择逻辑错误:原代码中过期时只更新第一个
.demo元素,无法正确处理所有购物车的过期状态。 - 冗余脚本:循环内生成多个重复脚本,既影响性能又容易引发变量冲突。
内容的提问来源于stack exchange,提问作者Haro
相关产品推荐
相关产品推荐

