简体   繁体   中英

Click event listener is being repeatedly triggered without any clicks?

I am developing a "Battleship" game with two grids made up of divs and am currently attempting to add a click event listener to all of the divs.

The issue that I am having is that the event listener is being repeatedly triggered (until every single div has been clicked) when I refresh my page and I can't understand why...

Here's the event listener in question:

 let aiGridCells = document.querySelectorAll(".ai-grid__game-cell");
 aiGridCells.forEach(cell => {
    cell.addEventListener("click", humanPlayer.humanAttack(cell.getAttribute('data-ai'),aiPlayer))
 });

Where humanPlayer is an object that has been generated by a factory function:

const humanPlayer = playerFactory('human');
import gameboardFactory from './gameboardFactory';

const playerFactory = (name) => {

    const playerBoard = gameboardFactory();

    const humanAttack = (cell, player) => {   // Where player is opponent
        if (player.playerBoard.gameBoard[cell].id !== 'miss') {
            player.playerBoard.receiveAttack(cell);
        };
    };

    const aiAttack = (player) => {   // Where player is opponent
        const availableCells = [];
        for (let i = 0; i < player.playerBoard.gameBoard.length; i++) {
            if (player.playerBoard.gameBoard[i].id === null) {
                availableCells.push(i);
            };
        };
        const attackCell = Math.floor(Math.random() * availableCells.length); 
        player.playerBoard.receiveAttack(attackCell);
    };

    return {
        name,
        playerBoard,
        humanAttack,
        aiAttack
    }

};

export default playerFactory;

and gameboardFactory is:

import shipFactory from './shipFactory';

const gameboardFactory = () => {
    const gameBoard = [];
    const shipYard = [];

    const init = () => {
        for (let i = 0; i<100; i++) {
            gameBoard.push({id: null})
        };
    };

    const checkValidCoordinates = (direction, start, end) => {
        if (direction === 'horizontal') {
            if ((start <= 9) && (end <= 9)) {
                return true;
            } else {
                let newStart = (start/10).toString(10);
                let newEnd = (end/10).toString(10);
                if ((newStart.charAt(0)) === (newEnd.charAt(0))) {
                    return true;
                };
            };
        } else {
            if ((start <= 9) && (end <= 9)) {
                return false
            } else if (start <= 9) {
                let newStart = start.toString(10);
                let newEnd = end.toString(10);
                if ((newStart.charAt(0)) === (newEnd.charAt(1))) {
                    return true;
                };
            } else {
                let newStart = start.toString(10);
                let newEnd = end.toString(10);
                if ((newStart.charAt(1)) === (newEnd.charAt(1))) {
                    return true;
                };
            };
        };
        return false
    };

    const checkIfShipPresent = (direction, start, end) => {
        if (direction === 'horizontal') {
            for (let i = start; i <= end; i++) {
                if (gameBoard[i].id !== null) {
                    return true;
                }
            };
            return false;
        } else {
            for (let i = start; i <= end; i += 10) {
                if (gameBoard[i].id !== null) {
                    return true;
                }
            };
            return false;
        };
    };

    const placeShip = (id, direction, start, end) => {

        if (!checkValidCoordinates(direction, start, end)) {
            return;
        };

        if (checkIfShipPresent(direction, start, end)) {
            return;
        };
        
        const newShip = [];

        if (direction === 'horizontal') {
            for (let i = start; i <= end; i++) {
                gameBoard[i].id = id;
                newShip.push(i);
            };
        } else {
            for (let i = start; i <= end; i += 10) {
                gameBoard[i].id = id;
                newShip.push(i);  
            };
        };
        
        shipYard.push(shipFactory(id, newShip));
    };

    const receiveAttack = (cell) => {

        console.log(cell)
       
        if (gameBoard[cell].id !== null) {
            const attackedShip = shipYard.filter((ship) => {
                return ship.id === gameBoard[cell].id;
            })[0];
            if (!attackedShip.hits.includes(cell)) {
                attackedShip.hits.push(cell);
            };
        } else {
            gameBoard[cell].id = 'miss';
        };
    };

    const checkIfAllShipsSunk = () => {
        let allShipsSunk = true;
        shipYard.forEach((ship) => {
            if (ship.isSunk() === false) {
                allShipsSunk = false;
            };
        });
        return allShipsSunk;
    };

    if (gameBoard.length === 0) {
        init();
    };

    return { 
        gameBoard,
        placeShip,
        receiveAttack,
        shipYard,
        checkIfAllShipsSunk
    };
};

export default gameboardFactory;

I'm completely lost to what the issue could be and have tried countless things to rectify it. Any suggestions would be hugely appreciated.

Thank you!

You trying to add actual function call as listener here:

 let aiGridCells = document.querySelectorAll(".ai-grid__game-cell");
 aiGridCells.forEach(cell => {
    cell.addEventListener("click", humanPlayer.humanAttack(cell.getAttribute('data-ai'),aiPlayer))
 });

So on your event listener initialization you actually call your function instead of passing it as a listener.

You can pass it like this instead:

 aiGridCells.forEach(cell => {
    cell.addEventListener("click",  () => humanPlayer.humanAttack(cell.getAttribute('data-ai'),aiPlayer))
 });

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