英文:
this.id is undefined. I get this error while coding the classic tic tac toe
问题
我尝试从另一个函数中的事件侦听器中使用此代码来调用瓷砖ID。像这样:
const setGame = () => {
board = [
[' ', ' ', ' '],
[' ', ' ', ' '],
[' ', ' ', ' ']
]
for(let r = 0; r < 3; r++) {
for(let c = 0; c < 3; c++) {
let tile = document.createElement("div")
tile.id = r.toString() + "-" + c.toString();
tile.classList.add("col-4", "box", "d-flex", "justify-content-center", "align-items-center");
tile.addEventListener("click", setTile);
document.getElementById("board").append(tile);
}
}
}
const setTile = () => {
if (gameOver) {
return;
}
let coords = this.id.split("-") //将ID字符串“1-1”分割成数组["1", "1"]
let r = parseInt(coords[0]);
let c = parseInt(coords[1]);
board[r][c] = currPlayer;
this.innerText = currPlayer;
}
关于"this"的问题,我不是一个专家... 我知道它调用来自类的对象... 在这种情况下,当我单击我创建的div元素时,它会调用瓷砖对象... 但在控制台上,我收到以下错误:
Uncaught TypeError: this.id is undefined
setTile http://127.0.0.1:5501/js/game.js:54
setGame http://127.0.0.1:5501/js/game.js:43
onload http://127.0.0.1:5501/js/game.js:27
EventHandlerNonNull* http://127.0.0.1:5501/js/game.js:26
在第一个函数setGame()中,我创建了用于创建3 x 3棋盘的div,并为每个div分配类似0,0 0,1 0,2 1,0等的ID。并添加了一个事件监听器,因此当单击它们中的任何一个时,它会执行以下函数setTile()
当单击时调用setTile()时,我期望从瓷砖(div元素)获取ID,使用'this.'调用瓷砖,将字符串转换为数组,并使用它们告诉HTML当前玩家在棋盘上的位置。
英文:
I am trying to call the tile id with this. id from an EventListener in another function.
Like this:
const setGame = () => {
board = [
[' ', ' ', ' '],
[' ', ' ', ' '],
[' ', ' ', ' ']
]
for(let r = 0 ; r < 3; r++) {
for(let c = 0 ; c < 3; c++) {
let tile = document.createElement("div")
tile.id = r.toString() + "-" + c.toString();
tile.classList.add("col-4", "box", "d-flex", "justify-content-center", "align-items-center");
tile.addEventListener("click", setTile);
document.getElementById("board").append(tile);
}
}
}
const setTile = () => {
if (gameOver) {
return;
}
let coords = this.id.split("-") //splits the id string "1-1" into an array["1", "1"]
let r = parseInt(coords[0]);
let c = parseInt(coords[1]);
board[r][c] = currPlayer;
this.innerText = currPlayer;
}
I am not an expert with "this"... I know it calls an object from a class... In this case it would be calling the tile object when I click on the div element that i am creating.. but on console I get this error:
Uncaught TypeError: this.id is undefined
setTile http://127.0.0.1:5501/js/game.js:54
setGame http://127.0.0.1:5501/js/game.js:43
onload http://127.0.0.1:5501/js/game.js:27
EventHandlerNonNull* http://127.0.0.1:5501/js/game.js:26
With the first function setGame().. I create the divs that create the 3 x 3 board and give each div ids like 0,0 0,1 0,2 1,0 .. etc. And add an eventlistener so when we click in any of them.. it executes the following function, setTile()
When setTile() is called on the click, I was expecting to get the id from tiles (div element), calling tiles with this.
to convert the string into an array and use them to tell the html where the current Player is on the board.
答案1
得分: 0
在这种情况下,你应该在你的“setTile”回调函数中捕获事件,而不是使用这个。
尝试在你的事件回调中进行这个更改。
还要检查你的“board”数组是否在你的回调函数范围内。
const setTile = (event) => {
if (gameOver) {
return;
}
let coords = event.target.id.split("-");
let r = parseInt(coords[0]);
let c = parseInt(coords[1]);
board[r][c] = currPlayer;
this.innerText = currPlayer;
}
英文:
In that case you should capture the event in your "setTile" callback function instead of using this.
Try to do this change in your event callback.
Also check that your "board" array is within reach of your callback function.
const setTile = (event) => {
if (gameOver) {
return;
}
let coords = event.target.id.split("-") //splits the id string "1-1" into an array["1", "1"]
let r = parseInt(coords[0]);
let c = parseInt(coords[1]);
board[r][c] = currPlayer;
this.innerText = currPlayer;
}
答案2
得分: 0
这可以通过多种方式解决。但首先你需要知道,箭头函数表达式与常规的函数表达式在处理this
时不同。因此,在你的setTile
函数中,this
将引用包裹你的代码的第一个常规函数表达式,或者window
对象。
除此之外,在事件处理程序中使用this
可能会难以理解,因为this
可能引用事件监听器已添加到的元素之外的许多其他内容。
最简单的解决方法是将tile
元素作为参数传递给setTile
函数,并在使用传递的tile
而不是this
。
英文:
This can be solved in multiple ways. But first you need to know that arrow function expressions don't handle this
the same as a regular function expression. So in your setTile
function, this
will either reference the first regular function expression that is a wrapping your code, or the window
object.
Besides that, using this
in an event handler can be hard to understand as this
could reference many things beside the element that the event listener has been added to.
The easiest workaround is to pass the tile
element to the setTile
function as an argument and use the passed tile
instead of this
.
const setGame = () => {
board = [
[' ', ' ', ' '],
[' ', ' ', ' '],
[' ', ' ', ' ']
];
const boardElement = document.getElementById("board");
for (let r = 0; r < 3; r++) {
for (let c = 0; c < 3; c++) {
let tile = document.createElement("div")
tile.id = r.toString() + "-" + c.toString();
tile.classList.add("col-4", "box", "d-flex", "justify-content-center", "align-items-center");
tile.addEventListener("click", () => {
setTile(tile);
});
boardElement.append(tile);
}
}
}
const setTile = (tile) => {
if (gameOver) {
return;
}
let coords = tile.id.split("-") //splits the id string "1-1" into an array["1", "1"]
let r = parseInt(coords[0]);
let c = parseInt(coords[1]);
board[r][c] = currPlayer;
tile.innerText = currPlayer;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论