简体   繁体   中英

this is referencing the whole window rather than the element in forEach loop

I am new to javascript and was trying to practice what I know by building a tic-tac-toe game.

I have created a grid in the HTML and am trying to record the player's move by changing the block, that is clicked, to an X or O by adding a class name to it. I am also saving the position of the clicked block and in the end checking if the last move led to a win or not, using the winCheck function.

Below is the part of the code that raises the error:

    const square = document.querySelectorAll('.square')
    // playing : x starts
    let player = 'x'

    square.forEach(block=>{
        block.addEventListener('click', play(player))
    })

    function play(player) {
        if(!search(this.id,occupied)){
            occupied.push(this.id)
            if(player==='x'){
                this.classList.add('x')
                player = 'o'
                x.push(this.id)
            }else if(player==='o'){
                this.classList.add('o')
                player = 'x'
                o.push(this.id)
            }
            winCheck()
        }
    }

error raised:

TypeError: this.classList is undefined

When I did a console.log(this) inside the play function I saw that it was referencing the complete window( document or DOM or the right word that I don't know because I am new to front-end development )

I am sorry if the question lacks detail, hard to frame a question on the topic you don't know

First thing I would do is add just one event listener to the document, then work with the event itself. There's no point in attaching an event listener to every single square when one would do the trick.

document.addEventListener('click', (event) => {
    // then you want to make sure that the target of the event is one of your squares
    if (event.target.classList.contains('square')) {
        //you want to handle the event here, so to prevent further bubbling
        event.stopPropagation();
        //then start manipulating the appearance of your square
    }
});

The this keyword in Javascript can get quite confusing at the early stages of development. I'd avoid it until you're comfortable with the basics and ready to move on to more complex stuff.

You writing code of Vanilla JS, but you mixing the concept of jQuery and Vanilla JS.

Your function play() is event function, actually the parameter player passed in is the event itself.

So you should:

  • Rename the parameter player to event .
  • The player element should be event.currentTarget
  • And this of cause should set to player by yourself (if you want to use it)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM