无法在"节点"上执行"removeChild":参数 1 不是"节点"类型。(它确实从 DOM 中删除了元素,但只有一次)



这有点挑战!!我知道以前有很多这样的问题,但它们都是针对具体情况的。

我正在使用模块设计模式创建一个掷字游戏。我使用下面的函数创建两个函数来渲染X &它还把它们附加到dom上。gameFlow函数是一个setInterval,所以当玩家点击dom时,x &O被渲染。该函数还从gameBoard模块(也在下面)获取棋盘,然后添加X &O

const gameFlow = () => {
const board = gameBoard.getBoard()
const box = document.querySelectorAll('.gameBox')
let x = true // Put this in the global scope if there is an error.
const renderX = (e) => {
for (let i = 0; i < board.length; i++) {
const target = e.target
const data = target.getAttribute('data-index')
const el = document.createElement('p')
el.classList.add('elstyle')
if (board[i] === '') {
if (i === Number(data)) {
gameBoard.fillBoard(i, 1, '❌')
el.textContent = `${board[i]}`
target.appendChild(el)
x = false
} 
}
}
}
const renderO = (e) => {
for (let i = 0; i < board.length; i++) {
const target = e.target
const data = target.getAttribute('data-index')
const el = document.createElement('p')
el.classList.add('elstyle')
if (board[i] === '') {
if (i === Number(data)) {
gameBoard.fillBoard(i, 1, '⭕')
el.textContent = `${board[i]}`
target.appendChild(el)
x = true
} 
}
}
}
box.forEach(el => el.addEventListener('click', ((e) => {
if (x) {
renderX(e)
} else {
renderO(e)
}
})))
}

下面是gameBoard模块。如gameFlow函数所示,gameBoard中的2个函数也填充板数组。Xs,然后通过迭代board数组将o渲染到dom。

const gameBoard = (() => {
let board = [
'', '', '',
'', '', '',
'', '', ''
]
const getBoard = () => {
return board
}
const fillBoard = (index, count, el) => {
board.splice(index, count, el)
}
const resetBoard = () => {
board.splice(0, board.length)
}
const setBoard = () => {
board = [
'', '', '',
'', '', '',
'', '', ''
]
}
return {getBoard, fillBoard, resetBoard, setBoard}
})()

最后,下面是重新启动模块,错误从这里记录。

const restartGame = (() => {
const mainThree = document.getElementById('mainThree')
const restart = document.getElementById('restartBtn')
const boxes = document.querySelectorAll('.gameBox')
restart.addEventListener('click', () => {
mainThree.style.display = 'none'
// gameBoard.resetBoard()
gameBoard.setBoard()
boxes.forEach(el => el.removeChild(el.firstChild))
})
})()

所以,每当我重新启动游戏时,dom中的元素(x和o)都会从dom中清除(但错误会记录在控制台)。但是当我再次播放并重新启动后,元素被清除或一些元素被清除(删除)而另一些元素没有。

是完整的app.js文件的链接。[在此输入链接描述][1][1]: https://github.com/rabtennamgyal/TOP-Project-tictactoe/blob/main/app.js

谢谢你的帮助。

引用

在您的重启代码中,boxes.forEach(el => el.removeChild(el.firstChild))被调用为类gameBox的每个元素。然而,这些元素中只有一部分有子元素(游戏中使用的X和O)>在某些情况下,el.firstChild等于null。因此,您尝试调用el.removeChild(null),这将抛出错误,因为null不是节点。要解决这个问题,您应该检查是否。firstChild存在,只有当它不为空时才调用removeChild。

谢谢你们俩的帮助。我通过创建一个删除所有dom元素的新函数来解决这个问题。我认为错误在于,在每一款游戏中,x和o都被附加到dom中,因为x和o可以在不同的游戏过程中被放入不同的盒子中;有些盒子包含两个元素,而有些盒子只有一个元素等等。之前我只删除了firstChild所以出现了错误。我必须删除每一个孩子。我使用代码

for (let i = 0; i < boxes.length; i++) {
while (boxes[i].firstChild) {
boxes[i].removeChild(boxes[i].firstChild);
}
}
const restartGame = (() => {
const mainThree = document.getElementById('mainThree')
const restart = document.getElementById('restartBtn')
const boxes = document.querySelectorAll('.gameBox')
function goAgain() {
mainThree.style.display = 'none'
// gameBoard.resetBoard()
gameBoard.setBoard()
for (let i = 0; i < boxes.length; i++) {
while (boxes[i].firstChild) {
boxes[i].removeChild(boxes[i].firstChild);
}
}
}
restart.addEventListener('click', goAgain)
})()
谢谢你们俩的帮助。和平

最新更新