簡體   English   中英

點擊事件監聽器被重復觸發而沒有任何點擊?

[英]Click event listener is being repeatedly triggered without any clicks?

我正在開發一個“戰艦”游戲,其中包含兩個由 div 組成的網格,目前正在嘗試向所有 div 添加一個單擊事件偵聽器。

我遇到的問題是,當我刷新頁面時,事件監聽器被反復觸發(直到每個 div 都被點擊),我不明白為什么......

這是有問題的事件偵聽器:

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

其中 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;

和 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;

我完全不知道這個問題可能是什么,並嘗試了無數的方法來糾正它。 任何建議將不勝感激。

謝謝!

您嘗試在此處添加實際的 function 調用作為偵聽器:

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

因此,在事件偵聽器初始化時,您實際上調用了 function 而不是將其作為偵聽器傳遞。

你可以像這樣傳遞它:

 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