简体   繁体   English

点击事件监听器被重复触发而没有任何点击?

[英]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.我正在开发一个“战舰”游戏,其中包含两个由 div 组成的网格,目前正在尝试向所有 div 添加一个单击事件侦听器。

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...我遇到的问题是,当我刷新页面时,事件监听器被反复触发(直到每个 div 都被点击),我不明白为什么......

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:其中 humanPlayer 是由工厂 function 生成的 object:

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:和 gameboardFactory 是:

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:您尝试在此处添加实际的 function 调用作为侦听器:

 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.因此,在事件侦听器初始化时,您实际上调用了 function 而不是将其作为侦听器传递。

You can pass it like this instead:你可以像这样传递它:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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