基于时间的值轮转脚本问题:Eldoren的60分钟间隔仅首次生效
问题描述
我编写了一个循环遍历常量const rotation中值的脚本,需持续运行且从指定值与起始日期const known开始。正常情况下,列表中的下一个值每30分钟出现一次,但存在例外:当值的id为"193234"(Eldoren)时,下一个值需间隔60分钟而非30分钟。
目前问题在于,该例外规则仅对id"193234"的首次出现生效,后续出现时无法正常触发。
当前输出示例:
01:00 Skag
01:30 Pfliep
02:00 Magmaton
02:30 Eldoren // 1 hour until the next value, which is correct
03:30 Skag
04:00 Pfliep
04:30 Magmaton
05:00 Eldoren // should be 1 hour until the next value, too
05:30 Skag // so start should be at 06:00
原脚本代码:
$(function () { if ($("[id^=test]").length) { function addHours(date, hours) { var copy = new Date(date); copy.setTime(copy.getTime() + hours * 60 * 60 * 1000); return copy; } function addMinutes(date, minutes) { return new Date(date.getTime() + minutes * 60000); } function next(value) { return { index: (value.index + 1) % rotation.length, date: addHours(value.date, 0.5), }; } const known = { id: 193210, ts: "2023-06-20T17:30:00" }; const rotation = [ { id: 193210, name: "Pfliep " }, { id: 186827, name: "Magmaton" }, { id: 193234, name: "Eldoren" }, { id: 193149, name: "Skag" }, ]; const now33 = new Date(); const now2 = addHours(now33, 10); const now3 = addHours(now33, -0); const end = addHours(now33, rotation.length * 2); var cur = { index: rotation.findIndex((li) => li.id == known.id), date: Date.parse(known.ts), }; while (cur.date < now3) { cur = next(cur); } const out = document.getElementById("test"); let increaseMinutes = 0; while (cur.date < end && cur.date < now2 && cur.date > now3) { const li = document.createElement("li"); li.className = "test"; var link = document.createElement("a"); link.textContent = `${rotation[cur.index].name}`; link.href = "dadada"; link.class = "dadada"; li.innerText = `${rotation[cur.index].name} (${cur.date.toLocaleString()})`; var id = `${rotation[cur.index].id}`; var title2 = `${rotation[cur.index].name}`; var link = "https://de.wowhead.com/npc="; var ClassName = "weeklytext"; var ClassName2 = "weeklytext2"; var ClassName3 = "peinigertime"; var options = { hour: "numeric", minute: "numeric" }; var date33 = `${addMinutes(cur.date, increaseMinutes).toLocaleString("en-GB", options)}`; if (id == 193234) { increaseMinutes = 30; } else if (increaseMinutes > 0) { increaseMinutes += 0; } $( '<li class="' + ClassName2 + '"><div class="' + ClassName3 + '"> ' + date33 + '</div> <a class="' + ClassName + '" href="' + link + +id + '">' + title2 + "</a></li>" ).appendTo(out); cur = next(cur); } } });
问题根源
next函数固定每次增加30分钟,完全没考虑Eldoren之后需要额外延长30分钟的规则,导致后续项的时间计算始终错误。increaseMinutes变量的逻辑仅在首次遇到Eldoren时设置为30,但后续没有将这个增量正确同步到cur.date的更新中,而且没有在非Eldoren项时重置,导致时间显示和实际循环的cur.date脱节。
修复方案
修改核心的时间间隔计算逻辑,让next函数根据当前项的id动态调整下一个时间的间隔,同时移除冗余的increaseMinutes变量:
$(function () { if ($("[id^=test]").length) { function addHours(date, hours) { var copy = new Date(date); copy.setTime(copy.getTime() + hours * 60 * 60 * 1000); return copy; } // 重构next函数,根据当前项id决定时间间隔 function next(value, rotation) { const currentItem = rotation[value.index]; // Eldoren(id:193234)之后间隔1小时,其他项间隔30分钟 const interval = currentItem.id === 193234 ? 1 : 0.5; return { index: (value.index + 1) % rotation.length, date: addHours(value.date, interval), }; } const known = { id: 193210, ts: "2023-06-20T17:30:00" }; const rotation = [ { id: 193210, name: "Pfliep " }, { id: 186827, name: "Magmaton" }, { id: 193234, name: "Eldoren" }, { id: 193149, name: "Skag" }, ]; const now33 = new Date(); const now2 = addHours(now33, 10); const now3 = addHours(now33, 0); const end = addHours(now33, rotation.length * 2); var cur = { index: rotation.findIndex((li) => li.id === known.id), date: Date.parse(known.ts), }; // 同步更新循环中的next调用,传入rotation参数 while (cur.date < now3) { cur = next(cur, rotation); } const out = document.getElementById("test"); while (cur.date < end && cur.date < now2 && cur.date > now3) { const currentItem = rotation[cur.index]; const id = currentItem.id; const title2 = currentItem.name; const link = "https://de.wowhead.com/npc="; const ClassName = "weeklytext"; const ClassName2 = "weeklytext2"; const ClassName3 = "peinigertime"; const options = { hour: "numeric", minute: "numeric" }; // 直接使用cur.date显示,无需额外增量 const date33 = cur.date.toLocaleString("en-GB", options); $( `<li class="${ClassName2}"><div class="${ClassName3}"> ${date33}</div> <a class="${ClassName}" href="${link}${id}">${title2}</a></li>` ).appendTo(out); // 调用next时传入rotation参数 cur = next(cur, rotation); } } });
修复说明
- 动态调整时间间隔:
next函数现在会根据当前项的id判断,如果是Eldoren则设置1小时间隔,其他项保持30分钟,确保每次循环都能正确应用规则,无论Eldoren是首次还是后续出现。 - 移除冗余变量:删除了
increaseMinutes,直接使用cur.date显示时间,避免了显示时间和实际循环时间脱节的问题。 - 优化代码可读性:简化了DOM元素的拼接逻辑,使用模板字符串替代字符串拼接,同时清理了无用的DOM创建代码。
内容的提问来源于stack exchange,提问作者Zerers
相关产品推荐
相关产品推荐

