Script标签嵌入JavaScript时钟代码失效问题:排查方法与正确使用方式咨询
解决时钟JS代码嵌入HTML
<script>标签失效的问题 首先,你的代码在CodePen/JSFiddle能正常运行但嵌入HTML后失效,大概率是几个常见的环境差异问题导致的,我帮你拆解并给出修复方案:
核心问题分析
- DOM加载时机不对:如果你的
<script>放在<head>标签里,代码执行时页面上的时钟元素(比如second_time、minute_time)还没被创建,getElementById会返回null,后续操作DOM的代码会直接报错中断。 - 依赖jQuery但未引入:代码里用到了
$(window).on("focusin", ...)这类jQuery语法,但你的HTML里没有引入jQuery库,这会触发$ is not defined的错误,直接阻塞代码运行。 - 变量拼写错误:代码里把
minutes写成了munutes,导致分钟指针的DOM元素获取失败,相关逻辑报错。 - 废弃属性无用:
language="JavaScript"和指定JS版本的做法早已被标准废弃,现代浏览器会忽略这些属性,不是问题根源。
修复步骤与完整代码
步骤1:确保DOM加载完成后执行代码
把脚本放在</body>标签前,或者用DOMContentLoaded事件包裹代码,确保页面元素都已渲染完成。
步骤2:引入jQuery(或替换为原生JS)
如果要保留jQuery的写法,在脚本前引入jQuery库;如果不想依赖jQuery,可以把窗口焦点监听的代码换成原生JS实现。
步骤3:修正拼写错误
把变量munutes改为minutes。
完整可运行示例
<!DOCTYPE html> <html> <head> <title>Clock with Chimes</title> <!-- 引入jQuery(如果保留jQuery代码的话) --> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <style> /* 示例时钟指针样式,根据你的需求调整 */ #second_time, #minute_time, #hour_time { position: absolute; transform-origin: bottom center; width: 2px; background: black; bottom: 50%; left: 50%; } #hour_time { width: 6px; height: 80px; } #minute_time { width: 4px; height: 120px; } #second_time { width: 2px; height: 140px; background: red; } </style> </head> <body> <!-- 确保页面上存在这些DOM元素 --> <div id="hour_time"></div> <div id="minute_time"></div> <div id="second_time"></div> <audio id="tick"></audio> <audio id="chime"></audio> <!-- 脚本放在body末尾,确保DOM已加载 --> <script> (function () { "use strict"; // 修正拼写错误:munutes → minutes let seconds = document.getElementById("second_time"), minutes = document.getElementById("minute_time"), hours = document.getElementById("hour_time"), s, m, h, S, M, H, time; function windup() { time = new Date(); s = time.getSeconds(); m = time.getMinutes(); h = time.getHours(); S = s * 6; M = m * 6 + s / 10; H = h * 30 + 0.5 * m; seconds.style.transform = "rotate(" + S + "deg)"; minutes.style.transform = "rotate(" + M + "deg)"; hours.style.transform = "rotate(" + H + "deg)"; console.log("windup: " + h + ":" + m + ":" + s); tick.volume = chime.volume = 1; } setTimeout(windup, 0); /*[main visibility API function]*/ let vis = (function () { let stateKey, eventKey, keys = { hidden: "visibilitychange", webkitHidden: "webkitvisibilitychange", mozHidden: "mozvisibilitychange", msHidden: "msvisibilitychange" }; for (stateKey in keys) { if (stateKey in document) { eventKey = keys[stateKey]; break; } } return function (c) { if (c) document.addEventListener(eventKey, c); return !document[stateKey]; }; })(); vis(function () { if (vis()) { setTimeout(function () { windup(); console.log("tab is visible - has focus"); }, 300); } else { console.log("tab is invisible - has blur"); tick.volume = chime.volume = 0.1; } }); // 窗口焦点监听:如果不想用jQuery,可以替换为下面的原生代码 // 原生JS版本(替代jQuery的focusin/focusout): // window.addEventListener('focus', function() { // setTimeout(function () { // windup(); // console.log("focus"); // }, 300); // }); // window.addEventListener('blur', function() { // console.log("blur"); // tick.volume = chime.volume = 0.1; // }); // 原jQuery代码(已引入jQuery时可保留) let notIE = document.documentMode === undefined, isChromium = window.chrome; if (notIE && !isChromium) { $(window) .on("focusin", function () { setTimeout(function () { windup(); console.log("focus"); }, 300); }) .on("focusout", function () { console.log("blur"); tick.volume = chime.volume = 0.1; }); } else { if (window.addEventListener) { window.addEventListener( "focus", function (event) { setTimeout(function () { windup(); console.log("focus"); }, 300); }, false ); window.addEventListener( "blur", function (event) { console.log("blur"); tick.volume = chime.volume = 0.1; }, false ); } else { window.attachEvent("focus", function (event) { setTimeout(function () { windup(); console.log("focus"); }, 300); }); window.attachEvent("blur", function (event) { console.log("blur"); tick.volume = chime.volume = 0.1; }); } } /*[hourly and quarterly chimes]*/ const tick = document.getElementById("tick"); const chime = document.getElementById("chime"); const sound_dir = "http://www.gerasimenko.com/sandbox/codepen/sounds/"; let bell, tock = "tock.wav"; tick.src = sound_dir + tock; function hourly_chime(n) { console.log("plays left: " + n); if (n === 0) { return; } else { chime.pause(); chime.currentTime = 0; chime.play(); n--; setTimeout(function () { hourly_chime(n); }, 3000); } } setInterval(function () { time = new Date(); s = time.getSeconds(); m = time.getMinutes(); h = time.getHours(); console.log("watch: " + h + ":" + m + ":" + s); tick.play(); if (s === 0 && (m === 15 || m === 30 || m === 45)) { bell = "ding-tone.wav"; chime.src = sound_dir + bell; hourly_chime(m / 15); } else if (s === 0 && m === 0) { bell = "bell-japanese.wav"; chime.src = sound_dir + bell; h > 12 ? (h = h - 12) : h; hourly_chime(h); } }, 1000); })(); </script> </body> </html>
额外检查项
- 音频跨域问题:如果你的HTML部署在自己的服务器上,第三方音频URL可能存在CORS限制,导致无法播放。可以把音频文件下载到本地服务器,修改
sound_dir为本地路径。 - 浏览器控制台排查:按F12打开浏览器控制台,查看报错信息是定位JS问题最直接的方式,任何代码错误都会在这里显示。
内容的提问来源于stack exchange,提问作者J.G.
相关产品推荐
相关产品推荐

