求助:JavaScript计时器无法显示及运行的问题排查
问题排查与修复
最明显的问题:没地方放计时器内容
你的JS代码里用document.getElementById("countdown")找元素来显示倒计时,但你的HTML里根本没有这个id的元素,代码就算跑起来了,内容也没地方渲染。
隐藏的逻辑漏洞:当天直播时间过了会算错
原来的getNextStreamDate函数只看星期几,比如今天是周一,现在已经20点了,直播是周一19点,它还是会返回今天19点的时间(已经过去了),导致遍历的时候找不到未来的直播时间,最后nextStream是undefined,直接报错。
还有个边界情况没处理
比如周日的时候,本周所有直播都结束了,遍历完所有streamTimes也找不到未来的直播,这时候代码会因为nextStream不存在而报错。
一步步修复
1. 先给计时器加个容器
在HTML的<main>里最后加个带id="countdown"的区块,比如:
<div class="divider"></div> <section> <h2>Nächster Stream</h2> <div id="countdown"></div> </section>
2. 修复直播时间的计算逻辑
修改getNextStreamDate函数,判断如果当天就是直播日,但已经过了直播时间,就返回下周的时间:
function getNextStreamDate(day, hour, minute) { var date = new Date(); var targetDay = day; // 1=周一,6=周六 var currentDay = date.getDay(); // 0=周日,1=周一...6=周六 var daysToAdd = (targetDay - currentDay + 7) % 7; // 如果今天就是直播日,但当前时间已经过了直播时间,加7天等下周 if (daysToAdd === 0) { var currentTotalMinutes = date.getHours() * 60 + date.getMinutes(); var streamTotalMinutes = hour * 60 + minute; if (currentTotalMinutes > streamTotalMinutes) { daysToAdd = 7; } } date.setDate(date.getDate() + daysToAdd); date.setHours(hour); date.setMinutes(minute); date.setSeconds(0); date.setMilliseconds(0); return date; }
3. 处理周日无直播的情况
在updateCountdown里加个判断,如果找不到未来的直播,就默认取第一个直播的下周时间:
function updateCountdown() { var now = new Date(); var nextStream; // 找下一个直播时间 for (var i = 0; i < streamTimes.length; i++) { var streamDate = getNextStreamDate(streamTimes[i].day, streamTimes[i].hour, streamTimes[i].minute); if (streamDate > now) { nextStream = streamDate; break; } } // 找不到未来直播的话,取第一个直播的下周时间 if (!nextStream) { nextStream = getNextStreamDate(streamTimes[0].day, streamTimes[0].hour, streamTimes[0].minute); } var distance = nextStream - now; // 直播中显示的逻辑,这里要加个setTimeout,不然直播结束后不会自动更新 if (distance <= 0 && distance >= -7200000) { countdownElement.innerHTML = '<a href="https://twitch.tv/chyyyp">Stream momentan Live</a>'; setTimeout(updateCountdown, 1000); return; } // 计算倒计时 var days = Math.floor(distance / (1000 * 60 * 60 * 24)); var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)); var seconds = Math.floor((distance % (1000 * 60)) / 1000); // 显示倒计时 countdownElement.innerHTML = "Nächster Stream in: " + days + " Tage " + hours + " Stunden " + minutes + " Minuten " + seconds + " Sekunden"; setTimeout(updateCountdown, 1000); }
修复后的完整代码
HTML
<link href="https://fonts.googleapis.com/css2?family=Varela+Round&display=swap" rel="stylesheet"> <header> <h1>Der Streamplan</h1> </header> <main> <div class="divider"></div> <section> <h2>Montag</h2> <p>19:00 - 21:00 Uhr</p> </section> <div class="divider"></div> <section> <h2>Dienstag</h2> <p>19:00 - 21:00 Uhr</p> </section> <div class="divider"></div> <section> <h2>Mittwoch</h2> <p>19:00 - 21:00 Uhr</p> </section> <div class="divider"></div> <section> <h2>Donnerstag</h2> <p>19:00 - 21:00 Uhr</p> </section> <div class="divider"></div> <section> <h2>Freitag</h2> <p>20:00 - 24:00 Uhr</p> </section> <div class="divider"></div> <section> <h2>Samstag</h2> <p>15:00 - 18:00 Uhr</p> </section> <div class="divider"></div> <section> <h2>Sonntag</h2> <p>Kein Stream</p> </section> <div class="divider"></div> <!-- 新增的计时器容器 --> <section> <h2>Nächster Stream</h2> <div id="countdown"></div> </section> </main>
JavaScript
window.onload = function() { var streamTimes = [{ day: 1, hour: 19, minute: 0 }, // Montag 19:00 { day: 2, hour: 19, minute: 0 }, // Dienstag 19:00 { day: 3, hour: 19, minute: 0 }, // Mittwoch 19:00 { day: 4, hour: 19, minute: 0 }, // Donnerstag 19:00 { day: 5, hour: 20, minute: 0 }, // Freitag 20:00 { day: 6, hour: 15, minute: 0 } // Samstag 15:00 ]; var countdownElement = document.getElementById("countdown"); function updateCountdown() { var now = new Date(); var nextStream; // 遍历找下一个未来的直播时间 for (var i = 0; i < streamTimes.length; i++) { var streamDate = getNextStreamDate(streamTimes[i].day, streamTimes[i].hour, streamTimes[i].minute); if (streamDate > now) { nextStream = streamDate; break; } } // 找不到未来直播时,取第一个直播的下周时间 if (!nextStream) { nextStream = getNextStreamDate(streamTimes[0].day, streamTimes[0].hour, streamTimes[0].minute); } var distance = nextStream - now; // 直播中状态(持续2小时) if (distance <= 0 && distance >= -7200000) { countdownElement.innerHTML = '<a href="https://twitch.tv/chyyyp">Stream momentan Live</a>'; setTimeout(updateCountdown, 1000); return; } // 计算倒计时各单位 var days = Math.floor(distance / (1000 * 60 * 60 * 24)); var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)); var seconds = Math.floor((distance % (1000 * 60)) / 1000); // 渲染倒计时 countdownElement.innerHTML = "Nächster Stream in: " + days + " Tage " + hours + " Stunden " + minutes + " Minuten " + seconds + " Sekunden"; // 每秒更新一次 setTimeout(updateCountdown, 1000); } function getNextStreamDate(day, hour, minute) { var date = new Date(); var targetDay = day; var currentDay = date.getDay(); var daysToAdd = (targetDay - currentDay + 7) % 7; // 判断当天是否已过直播时间,是的话延后一周 if (daysToAdd === 0) { var currentTotalMinutes = date.getHours() * 60 + date.getMinutes(); var streamTotalMinutes = hour * 60 + minute; if (currentTotalMinutes > streamTotalMinutes) { daysToAdd = 7; } } date.setDate(date.getDate() + daysToAdd); date.setHours(hour); date.setMinutes(minute); date.setSeconds(0); date.setMilliseconds(0); return date; } updateCountdown(); };
CSS
保持你原来的CSS代码不变即可。
内容的提问来源于stack exchange,提问作者chyyyp
相关产品推荐
相关产品推荐

