我正在尝试构建一个 Tic Tac Toe 游戏,因此我尝试先使用
getElementsByClassName()
来收集数组中的游戏框区域,然后再使用展开运算符将集合转换为数组。
但是当我尝试使用arr.every()
方法来检查是否所有的盒子都被播放时,即使所有的盒子都被填满了我仍然得到false
这是我的HTML代码
<div class="board">
<div class="board-sections">
<div class="play-box"></div>
<div class="play-box"></div>
<div class="play-box"></div>
<div class="play-box"></div>
<div class="play-box"></div>
<div class="play-box"></div>
<div class="play-box"></div>
<div class="play-box"></div>
<div class="play-box"></div>
</div>
</div>
首先我收集了所有的游戏盒。
let boxes = document.getElementsByClassName("play-box");
let numOfBoxes = boxes.length;
然后我将集合转换为数组并应用条件来检查所有框是否不为空
let boxesArr = [...boxes];
let checkBoxes = boxesArr.every(function(box) {
return box.innerHTML !== "";
});
然后我创建了一个函数来检查是否所有的框都不为空
function checkBoard() {
if (checkBoxes) {
console.log("All Filled");
}
}
然后我创建了一个函数来向每个框添加文本,并通过调用 checkBoard() 函数 onclick 检查是否所有框都已填充。
for (var i = 0; i < numOfBoxes; i++) {
boxes[i].addEventListener("click", addChip);
}
addChip()
函数在单击时向每个框添加文本,然后检查是否所有框都已填充
function addChip() {
this.innerHTML = "X";
checkBoard();
}
框在单击时被填充,我希望
checkBoard()
函数在所有框都填充后返回 true
,但是在所有框都填充后 checkBoard()
函数仍然返回 false.
这是完整代码的样子
let boxes = document.getElementsByClassName("play-box");
let numOfBoxes = boxes.length;
let boxesArr = [...boxes];
let checkBoxes = boxesArr.every(function(box) {
return box.innerHTML !== "";
});
function checkBoard() {
if (checkBoxes) {
console.log("All Filled");
}
}
for (var i = 0; i < numOfBoxes; i++) {
boxes[i].addEventListener("click", addChip);
}
function addChip() {
this.innerHTML = "X";
checkBoard();
}
.board {
text-align: center;
max-width: 100%;
width: 500px;
margin: auto;
}
.board-sections {
display: grid;
grid-template-columns: auto auto auto;
background: #ccc;
gap: 5px;
align-content: center;
}
.play-box {
height: 100px;
background: transparent;
border: 1px solid #000;
min-width: 100px;
display: flex;
align-items: center;
justify-content: center;
}
<div class="board">
<div class="board-sections">
<div class="play-box"></div>
<div class="play-box"></div>
<div class="play-box"></div>
<div class="play-box"></div>
<div class="play-box"></div>
<div class="play-box"></div>
<div class="play-box"></div>
<div class="play-box"></div>
<div class="play-box"></div>
</div>
</div>
没有实际代码很难回答你的问题。下面我组装了一个实际可行的可能场景。或许对你有帮助?
const pb=[...document.querySelectorAll(".play-box")];
document.querySelectorAll("button").forEach(b=>{
b.addEventListener("click",ev=>{
if(b.textContent=="check")
console.log(pb.every(p=>p.textContent!=""))
else
pb.forEach(p=>p.textContent="X");
})
})
.play-box {display:inline-block; width:40px;height:40px; border:1px solid grey}
<div class="board">
<div class="board-sections">
<div class="play-box"></div>
<div class="play-box"></div>
<div class="play-box"></div><br>
<div class="play-box"></div>
<div class="play-box"></div>
<div class="play-box"></div><br>
<div class="play-box"></div>
<div class="play-box"></div>
<div class="play-box"></div>
</div>
</div>
<button>check</button> <button>fill</button>
我想说的是,
.textContent
元素的.play-box
必须在after 被填充后进行检查。 OP 的原始脚本只在页面加载后立即进行了一次检查。
解释:
上面代码片段中的关键部分是表达式
pb.every(p=>p.textContent!="")
如果所有的盒子都以某种方式填满,它会返回
true
。在您的井字游戏中,这需要在每次设置“X”或“O”后执行。
你的
checkBoard
函数应该是这样的:
function checkBoard() {
if (boxesArr.every(p=>p.textContent!="")) {
console.log("All Filled");
}
}
你的
checkBoxes
持有一个布尔值,而不是一个函数:
// This is wrong
let checkBoxes = boxesArr.every(function(box) {
return box.innerHTML !== "";
});
它只会返回游戏开始前的状态值。你不能在游戏中像
if (checkBoxes)
那样重复使用它并期望更新值。if (checkBoxes()) {
:
const boxes = document.querySelectorAll(".board-box");
const numOfBoxes = boxes.length;
const checkBoxes = () => [...boxes].every((box) => box.textContent.trim() !== "");
function checkBoard() {
if (checkBoxes()) {
console.log("All Filled");
}
}
boxes.forEach((box) => {
box.addEventListener("click", addChip);
});
function addChip() {
this.textContent = "X";
checkBoard();
}
.board {
text-align: center;
max-width: 100%;
width: 500px;
margin: auto;
}
.board-sections {
display: grid;
grid-template-columns: auto auto auto;
background: #ccc;
gap: 5px;
align-content: center;
}
.board-box {
height: 100px;
background: transparent;
border: 1px solid #000;
min-width: 100px;
display: flex;
align-items: center;
justify-content: center;
}
<div class="board">
<div class="board-sections">
<div class="board-box"></div>
<div class="board-box"></div>
<div class="board-box"></div>
<div class="board-box"></div>
<div class="board-box"></div>
<div class="board-box"></div>
<div class="board-box"></div>
<div class="board-box"></div>
<div class="board-box"></div>
</div>
</div>
此外,使用
textContent
返回 text 而不是 innerHTML
此外,您可以将代码简化为:
const boxes = document.querySelectorAll(".board-box");
const tot = boxes.length;
let turn = 0;
const isBoxEmpty = (box) => box.textContent.trim() === "";
const checkBoard = () => {
if (![...boxes].some(isBoxEmpty)) {
console.log("All Filled");
}
};
const addChip = (ev) => {
const box = ev.currentTarget;
if (!isBoxEmpty(box)) return; // Not an empty box. Exit function here.
this.textContent = (turn % 2) ? "O" : "X";
checkBoard();
// Increment turn
turn += 1;
}
boxes.forEach((box) => box.addEventListener("click", addChip));
.board {
font: 14vmin/1 sans-serif;
margin: auto;
display: inline-grid;
grid-template-columns: repeat(3, 1fr);
gap: 5px;
}
.board-box {
height: 20vmin;
aspect-ratio: 1;
border: 2px solid #000;
display: flex;
align-items: center;
justify-content: center;
user-select: none;
}
<div class="board">
<div class="board-box"></div>
<div class="board-box"></div>
<div class="board-box"></div>
<div class="board-box"></div>
<div class="board-box"></div>
<div class="board-box"></div>
<div class="board-box"></div>
<div class="board-box"></div>
<div class="board-box"></div>
</div>