JavaScript开发可切换尺寸幻方网格及行列对角线求和校验问题求助
问题根因&修复方案
现有代码错误点
- 全局变量
values仅在页面初始化时读取一次下拉框值,切换尺寸后没有更新,导致后续生成网格始终用初始的3x3参数 querySelectorAll返回的是静态NodeList集合,不能直接调用单个元素的remove()、removeAttribute()方法;且removeAttribute是用于删除元素属性(比如class、id),不是删除元素本身,清空网格直接清空父容器内容即可change()方法仅做了3、4尺寸的分支判断,其他尺寸没有触发生成网格的逻辑- 页面初始化时就执行
document.querySelectorAll(".box"),此时网格还没生成,拿到的是空集合,你未贴出的size3x3()方法大概率操作了空元素的textContent,导致页面加载报错
优化后完整实现
HTML
<div id="boxParent"></div> <form> <label>Choose a Size:</label> <select id="sizeSelect"> <option value="3">3 X 3</option> <option value="4">4 X 4</option> <option value="5">5 X 5</option> <option value="6">6 X 6</option> <option value="7">7 X 7</option> <option value="8">8 X 8</option> <option value="9">9 X 9</option> </select> <button type="button" id="validateBtn">校验幻方</button> </form>
CSS
* { box-sizing: border-box; } #boxParent { width: 600px; margin: 20px 0; } .row { display: flex; width: 100%; } .box { border: black 4px solid; background: white; opacity: 0.7; aspect-ratio: 1 / 1; cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 20px; flex: 1; }
JS
const sizeSelect = document.getElementById('sizeSelect'); const boxParent = document.getElementById('boxParent'); const validateBtn = document.getElementById('validateBtn'); // 初始化生成网格 createGrid(+sizeSelect.value); // 下拉框切换尺寸 sizeSelect.addEventListener('change', () => { const size = +sizeSelect.value; // 清空原有网格 boxParent.innerHTML = ''; // 生成新网格 createGrid(size); }); // 生成n阶网格 function createGrid(n) { for (let i = 0; i < n; i++) { const row = document.createElement('div'); row.className = 'row'; for (let j = 0; j < n; j++) { const box = document.createElement('div'); box.className = 'box'; // 支持直接编辑单元格数值 box.contentEditable = true; box.textContent = '0'; row.appendChild(box); } boxParent.appendChild(row); } } // 通用幻方校验函数 validateBtn.addEventListener('click', () => { const n = +sizeSelect.value; const boxes = document.querySelectorAll('.box'); // 把平铺的单元格转成二维数组 const grid = []; let index = 0; for (let i = 0; i < n; i++) { grid[i] = []; for (let j = 0; j < n; j++) { grid[i][j] = +boxes[index].textContent || 0; index++; } } // 取第一行的和作为基准校验值 const targetSum = grid[0].reduce((a, b) => a + b, 0); // 校验所有行 for (let i = 0; i < n; i++) { const rowSum = grid[i].reduce((a, b) => a + b, 0); if (rowSum !== targetSum) { alert(`校验不通过:第${i+1}行和为${rowSum},基准和为${targetSum}`); return; } } // 校验所有列 for (let j = 0; j < n; j++) { let colSum = 0; for (let i = 0; i < n; i++) { colSum += grid[i][j]; } if (colSum !== targetSum) { alert(`校验不通过:第${j+1}列和为${colSum},基准和为${targetSum}`); return; } } // 校验主对角线(左上到右下) let diagonalSum1 = 0; for (let i = 0; i < n; i++) { diagonalSum1 += grid[i][i]; } if (diagonalSum1 !== targetSum) { alert(`校验不通过:主对角线和为${diagonalSum1},基准和为${targetSum}`); return; } // 校验副对角线(右上到左下) let diagonalSum2 = 0; for (let i = 0; i < n; i++) { diagonalSum2 += grid[i][n - 1 - i]; } if (diagonalSum2 !== targetSum) { alert(`校验不通过:副对角线和为${diagonalSum2},基准和为${targetSum}`); return; } alert('校验通过!当前是合法幻方'); });
内容的提问来源于stack exchange,提问作者Shawn
相关产品推荐
相关产品推荐

