this.id is undefined. I get this error while coding the classic tic tac toe.

huangapple go评论61阅读模式
英文:

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 = () =&gt; {
    board = [
        [&#39; &#39;, &#39; &#39;, &#39; &#39;],
        [&#39; &#39;, &#39; &#39;, &#39; &#39;],
        [&#39; &#39;, &#39; &#39;, &#39; &#39;]
    ]

    for(let r = 0 ; r &lt; 3; r++) {
        for(let c = 0 ; c &lt; 3; c++) {
            let tile = document.createElement(&quot;div&quot;)
            tile.id = r.toString() + &quot;-&quot; + c.toString();
            tile.classList.add(&quot;col-4&quot;, &quot;box&quot;, &quot;d-flex&quot;, &quot;justify-content-center&quot;, &quot;align-items-center&quot;);
            
            tile.addEventListener(&quot;click&quot;, setTile);
            document.getElementById(&quot;board&quot;).append(tile);
        }
    }
}

const setTile = () =&gt; {
    if (gameOver) {
        return;
    }
    let coords = this.id.split(&quot;-&quot;)  //splits the id string &quot;1-1&quot; into an array[&quot;1&quot;, &quot;1&quot;]
    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) =&gt; {
    if (gameOver) {
        return;
    }
    let coords = event.target.id.split(&quot;-&quot;)  //splits the id string &quot;1-1&quot; into an array[&quot;1&quot;, &quot;1&quot;]
    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 = () =&gt; {
  board = [
    [&#39; &#39;, &#39; &#39;, &#39; &#39;],
    [&#39; &#39;, &#39; &#39;, &#39; &#39;],
    [&#39; &#39;, &#39; &#39;, &#39; &#39;]
  ];

  const boardElement = document.getElementById(&quot;board&quot;);

  for (let r = 0; r &lt; 3; r++) {
    for (let c = 0; c &lt; 3; c++) {
      let tile = document.createElement(&quot;div&quot;)
      tile.id = r.toString() + &quot;-&quot; + c.toString();
      tile.classList.add(&quot;col-4&quot;, &quot;box&quot;, &quot;d-flex&quot;, &quot;justify-content-center&quot;, &quot;align-items-center&quot;);

      tile.addEventListener(&quot;click&quot;, () =&gt; {
        setTile(tile);
      });

      boardElement.append(tile);
    }
  }
}

const setTile = (tile) =&gt; {
  if (gameOver) {
    return;
  }

  let coords = tile.id.split(&quot;-&quot;) //splits the id string &quot;1-1&quot; into an array[&quot;1&quot;, &quot;1&quot;]
  let r = parseInt(coords[0]);
  let c = parseInt(coords[1]);

  board[r][c] = currPlayer;
  tile.innerText = currPlayer;
}

huangapple
  • 本文由 发表于 2023年2月7日 04:10:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/75366087.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定