HTML/PHP页面onload事件如何同时执行两个JS初始化函数
问题根因
两个函数无法同时执行根本不是onload绑定方式的问题,是代码里存在3个硬错误,会触发JS运行时中断:
Lightbox.activate()方法中,插入的DOM结构没有class为no_action的元素,执行const nobtn = lightBox.querySelector(".no_action")会返回null,后续给null绑定click事件会直接抛出类型错误,阻断后续所有代码执行,这是set_message()偶发失效的核心原因。set_message()的时段判断逻辑完全错误:所有条件分支误用了||(或)运算符,比如hr >= 1 || hr <=5对任意小时数都成立——哪怕是正午12点也满足hr >=1,会直接命中第一个分支,永远显示"Good night"。Lightbox.show()方法里的选择器字符串被意外拆成两行,会直接触发JS语法错误。
修复步骤
- 修正Lightbox类代码:要么删除不存在的
no_action按钮相关绑定逻辑,要么在插入的DOM结构中补上对应按钮,同时修复换行的选择器:
class Lightbox { static activate() { document.body.insertAdjacentHTML("beforeend", ` <div class="lightbox" id="lightbox" style="display: none;"> <div class="lightbox__inner"> <button type="button" class="lightbox__close"> × </button> <div class="lightbox__content"></div> </div> </div> `); const lightBox = document.querySelector("#lightbox"); const btnClose = lightBox.querySelector(".lightbox__close"); const content = lightBox.querySelector(".lightbox__content"); const closeLightbox = () => { lightBox.style.display = "none"; content.innerHTML = ""; }; lightBox.addEventListener("mousedown", e => { if (e.target.matches("#lightbox")) { closeLightbox(); } }); btnClose.addEventListener("click", closeLightbox); } static show(htmlOrElement) { const content = document.querySelector("#lightbox .lightbox__content"); document.querySelector("#lightbox").style.display = null; content.innerHTML = typeof htmlOrElement === "string" ? htmlOrElement : ""; if (typeof htmlOrElement !== "string") content.appendChild(htmlOrElement); } }
如果确实需要no_action按钮,在lightbox__inner结构里补上对应按钮,再恢复对应的事件绑定代码即可。
- 修正
set_message()的时段判断逻辑,将||替换为&&调整区间判断:
function set_message(){ const hr = new Date().getHours(); const mesg = document.getElementById('hello'); if (!mesg) return; // 提前判断元素是否存在,避免null报错 const name = mesg.textContent; let greeting = ""; if(hr >= 0 && hr <= 5) greeting = "Good night"; else if(hr >= 6 && hr <= 11) greeting = "Good morning"; else if(hr >= 12 && hr <=16) greeting = "Good afternoon"; else greeting = "Good evening"; mesg.innerHTML = greeting + name; }
- 替换inline onload绑定为更稳妥的
DOMContentLoaded事件,把下面代码放到JS文件末尾,或页面</body>标签前即可,不需要在body标签上加任何onload属性:
document.addEventListener('DOMContentLoaded', () => { Lightbox.activate(); set_message(); });
内容的提问来源于stack exchange,提问作者Aviv Moyal
相关产品推荐
相关产品推荐

