IIFE模块未自动执行,需手动调用Board.renderBoard()才能渲染问题排查
这个问题其实很常见——你的IIFE确实封装了Board模块,但你只是定义了渲染方法,却从来没主动触发它!而且代码里还有两个小bug,我一步步给你拆解:
首先说核心问题:
你的IIFE执行后,只是把renderBoard方法挂载到了Board对象上,但没有任何代码去调用这个方法。就像你买了个打印机,插好电但没按打印键,自然不会出东西。
然后看代码里的两个小问题:
createTiles里的tile变量没有用const/let声明,会变成全局变量,这是个潜在的坑,必须补上。- 循环里你调用了两次
createTiles():一次是单独调用(返回的tile没用到),一次是传给appendChild——这意味着每次循环会创建两个tile,最后页面上会有18个而不是9个tile,这明显不是你想要的。
接下来是修复后的代码,分两种场景:
场景1:模块加载后自动渲染(适合不需要控制渲染时机的情况)
直接在IIFE内部最后调用renderBoard(),但要确保DOM已经加载完成,所以最好把整个IIFE放在DOMContentLoaded事件里,避免document.querySelector('.board')找不到元素:
document.addEventListener('DOMContentLoaded', () => { const Board = (() => { const board = document.querySelector('.board'); const createTiles = () => { const tile = document.createElement('div'); // 补上const声明 tile.classList.add('tile'); return tile; }; const renderBoard = () => { for (let i = 0; i < 9; i++) { // 只调用一次createTiles,避免重复创建元素 board.appendChild(createTiles()); } }; // 模块初始化时自动调用渲染方法 renderBoard(); return { renderBoard }; // 依然暴露方法,方便后续手动调用 })(); });
场景2:手动控制渲染时机(比如需要在某些事件后渲染)
如果不想模块一加载就渲染,就把调用放在IIFE外面,但同样要确保DOM加载完成:
const Board = (() => { const board = document.querySelector('.board'); const createTiles = () => { const tile = document.createElement('div'); tile.classList.add('tile'); return tile; }; const renderBoard = () => { for (let i = 0; i < 9; i++) { board.appendChild(createTiles()); } }; return { renderBoard }; })(); // 页面加载完成后自动调用渲染方法 document.addEventListener('DOMContentLoaded', () => { Board.renderBoard(); });
最后再提醒一句:如果你的脚本是放在<head>标签里的,一定要用DOMContentLoaded事件包裹,否则document.querySelector('.board')会返回null——因为此时body里的元素还没加载出来,这也是很多人遇到渲染问题的常见原因哦!
内容的提问来源于stack exchange,提问作者Franz G
相关产品推荐
相关产品推荐

