如何用原生JavaScript实现15天无限循环展示不同内容
实现15天无限循环的内容轮换(原生JavaScript)
问题背景
需要实现每天展示一个特定内容的div,15天后自动重启循环,原实现仅支持前15天,后续需手动添加循环起始日期,无法动态实现无限循环。
原实现代码
Rotator核心逻辑
const Rotator = { init(startDate) { const todayMonth = new Date(SERVER_DATETIME).getMonth() + 1; const todayDate = new Date(SERVER_DATETIME).getDate(); const sectionArray = [];//array of ids const daysArray = [];//array of days to rotate document.querySelectorAll('.ws-slide').forEach((item,index) => { let id = item.id; sectionArray.push(id); }); sectionArray.forEach((item, index) => { daysArray.push(startDate + (index * 24 * 60 * 60 * 1000)); }); daysArray.forEach((item, index) => { let newMonth = new Date(item).getMonth() + 1; let newDate = new Date(item).getDate(); if (newMonth === todayMonth && newDate === todayDate) { console.log(sectionArray[index]) document.querySelector(`#${sectionArray[0]}`).style.display = "none"; document.querySelector(`#${sectionArray[index]}`).style.display = 'block'; } }); } }
手动设置循环起始日期的代码
const spectrumStartDate = '6/29/2023'; let date; let d = new Date(SERVER_DATETIME); let slidesLength = document.querySelectorAll('.ws-slide').length; let cycle = 24 * 60 * 60 * 1000 * slidesLength; let mydate = new Date(spectrumStartDate).getTime(); //'6/29' console.log("start date 6/29 " + new Date(mydate)); let mydate15 = mydate + cycle; console.log("start date 7/14 " + new Date(mydate15)); let mydate30 = mydate15 + cycle; console.log("start date 7/29 " + new Date(mydate30)); let mydate45 = mydate30 + cycle; console.log("start date 8/13 " + new Date(mydate45)); let mydate60 = mydate45 + cycle; console.log("start date 8/28 " + new Date(mydate60)); let mydate75 = mydate60 + cycle; console.log("start date 9/12 " + new Date(mydate75)); let mydate90 = mydate75 + cycle; console.log("start date 9/27 " + new Date(mydate90)); if (d >= mydate90) { date = mydate90 //start date is 9/27 } else if (d >= mydate75) { date = mydate75 //start date is 9/12 } else if (d >= mydate60) { date = mydate60 //start date is 8/28 } else if (d >= mydate45) { date = mydate45 //start date is 8/13 } else if (d >= mydate30) { date = mydate30 //start date is 7/29 } else if (d >= mydate15) { date = mydate15; //start date is 7/14 } else if (d >= mydate) { date = mydate;//start date is 6/29 } console.log("start date is " + new Date(date)); Rotator.init(date);
动态无限循环解决方案
核心思路是计算当前日期与起始日期的天数差,再对15取模,直接得到当前应展示的内容索引,无需手动维护循环起始日期。
重构后的完整代码
const Rotator = { init(startDateStr) { // 先隐藏所有幻灯片 document.querySelectorAll('.ws-slide').forEach(slide => { slide.style.display = 'none'; }); // 获取所有幻灯片的ID数组 const sectionArray = Array.from(document.querySelectorAll('.ws-slide')).map(item => item.id); const totalCycleDays = sectionArray.length; // 固定为15天 const oneDayMs = 24 * 60 * 60 * 1000; // 转换起始日期为当天0点时间戳,避免时分秒干扰 const startDate = new Date(startDateStr); startDate.setHours(0, 0, 0, 0); const startTimestamp = startDate.getTime(); // 转换服务器当前日期为当天0点时间戳 const today = new Date(SERVER_DATETIME); today.setHours(0, 0, 0, 0); const todayTimestamp = today.getTime(); // 计算天数差并取模,得到当前展示的索引 const daysDiff = Math.floor((todayTimestamp - startTimestamp) / oneDayMs); const currentIndex = daysDiff >= 0 ? daysDiff % totalCycleDays : 0; // 显示当前幻灯片 document.getElementById(sectionArray[currentIndex]).style.display = 'block'; console.log(`当前展示内容:${sectionArray[currentIndex]}`); } }; // 初始化调用 const spectrumStartDate = '6/29/2023'; Rotator.init(spectrumStartDate);
优化说明
- 去掉手动维护循环起始日期的冗余代码,通过数学计算实现无限循环
- 统一初始化隐藏所有幻灯片,避免原代码仅隐藏第一个的逻辑漏洞
- 将日期统一转为当天0点时间戳,确保跨天切换的准确性
- 增加容错处理:若当前日期早于起始日期,默认展示第一个幻灯片
内容的提问来源于stack exchange,提问作者mgreen
相关产品推荐
相关产品推荐

