JavaScript网页卡牌开发中innerHTML返回undefined问题排查
问题原因及修复方案
核心问题
play函数仅完成了牌组数据的打乱生成,没有调用addCardCat执行卡片渲染逻辑,也没有向该函数传入卡牌数值、技能参数,未触发的函数自然不会生成对应内容,无参数传入也会导致取值为undefined。fs是Node.js服务端专属API,浏览器网页环境不支持require语法和本地文件系统读写能力,你写的文件读取逻辑会直接报错,data数组根本无法正确获取data.txt的内容,所有读取data下标的操作都会得到undefined。- 换行符分割逻辑仅适配Windows的
\r\n换行,mac/Linux系统下换行符为\n,会导致分割后的data数组元素错乱,此外如果data.txt末尾存在空行,也会导致数据读取异常。 - 你预设
numberArray是54个元素,对应需要data.txt有108行有效数据,若data.txt行数不足,j*2+1会超出data数组的最大下标,读取到undefined。
修复步骤
- 替换文件读取逻辑:网页环境下改用
fetch异步读取data.txt内容,或者直接将卡牌数据定义为JS数组写入代码中,规避浏览器不支持fs的问题。 - 补全
play函数中的渲染逻辑:scrambleDeck执行完成后,遍历deck数组,每两个元素为一组调用addCardCat,传入数值和技能名称。 - 优化换行符分割逻辑:改用正则匹配所有换行符,同时过滤空行。
- 每次调用
play时清空deck数组,避免重复调用导致数据叠加。
参考修改代码
let counter = 0; var deck = []; let data = []; // 预先加载卡牌数据 async function loadCardData() { const res = await fetch('data.txt'); const text = await res.text(); // 兼容所有换行符,过滤空行 data = text.split(/\r?\n/).filter(line => line.trim() !== ''); } loadCardData(); let numberArray = Array.from(Array(54).keys()) function scrambleArray(array){ let currentIndex = array.length, randomIndex; while (currentIndex != 0){ randomIndex = Math.floor(Math.random() * currentIndex); currentIndex--; [array[currentIndex], array[randomIndex]] = [ array[randomIndex], array[currentIndex]]; } return array; } function scrambleDeck(array){ // 每次生成牌组前清空旧数据 array.length = 0; // 确保数据足够再遍历 const maxCard = Math.min(54, Math.floor(data.length/2)); for(var i = 0; i < maxCard; i++){ var j = numberArray[i]; array.push(data[j*2]); array.push(data[j*2+1]); } return array; } function addCardCat(number, power) { counter++; var newDiv = document.createElement("div"); newDiv.className += " cat__card"; newDiv.id = 'card-' +counter; document.getElementById('cat').appendChild(newDiv); var newH1 = document.createElement("h1"); var newH3 = document.createElement("h3"); newDiv.appendChild(newH1); newDiv.appendChild(newH3); newH1.innerHTML = number; newH3.innerHTML = power; } async function play() { // 确保数据加载完成再执行后续逻辑 if(data.length === 0) await loadCardData(); document.getElementById("play").style.display = "none"; scrambleArray(numberArray); scrambleDeck(deck); // 遍历牌组渲染卡片 for(let i=0; i<deck.length; i+=2) { addCardCat(deck[i], deck[i+1]); } }
内容的提问来源于stack exchange,提问作者Deividas Sitdykov
相关产品推荐
相关产品推荐

