【问题标题】:Simple Vanilla JS game简单的香草 JS 游戏
【发布时间】:2025-12-16 09:00:01
【问题描述】:

我尝试编写简单的香草 JS 记忆游戏。当我尝试对在 Square 类中创建的 div 使用查询选择器时遇到问题。 Console.log 返回空节点列表或数组。我怀疑这个功能是在创建 div 之前完成的。如何通过查询选择器或其他方法获得此元素?

// CLASS SQUARE

export class Square {
    constructor (number,type,field) {
        this.number = number;
        this.type = type;
        this.field = field;
        this.colors = ['red','red','blue','blue','orange','orange','green','green','gold','gold','pink','pink','cadetblue','cadetblue','purple','purple','beige','beige','cyan','cyan']
        this.divs = [];
    }
    creator() {
        for(let i = 0; i < this.number; i++) {
            let create = document.createElement(this.type)
            this.field.appendChild(create)
            create.classList.add('square')
            create.setAttribute('id','square')
            this.divs.push(create);
            console.log(this.divs)
        }
   
    }
    addColor() {
        this.divs.forEach((div)=>{
            let chooseColor = Math.floor(Math.random()* this.colors.length);
            div.style.backgroundColor = this.colors[chooseColor]
            this.colors.splice(chooseColor,1)

        })
    }
    addShadow() {
        this.divs.forEach((div)=>{
            const shadow = () => {
            div.classList.add('shadow')
            }
            setTimeout(shadow,2000)
        })
    }
}

// CLASS SHADOW

export class Shadow  {
    constructor(shadowDivs) {
        this.shadowDivs = shadowDivs;
    }
    revealDiv() { // THERE IS MY PROBLEM
        this.shadowDivs.forEach((shadowDiv)=>{  
     
            shadowDiv.addEventListener('click',()=>{ 
                console.log(this.shadowDivs)
          
                shadowDiv.classList.remove('shadow')  
            })
        })
    }
}

//MAIN JS FILE

import { Square } from "./Square.js";
import { Shadow } from "./Shadow.js";


class Game {

    elements = {
        number: 20,
        type: 'div',
        field: document.getElementById('field'),
        divs: document.querySelectorAll('.shadow') //THERE I TRY GAIN ELEMENTS
    }

    init() {
      const squareCreator = new Square(this.elements.number,this.elements.type,this.elements.field);
      const shadows = new Shadow(this.elements.divs) // AND THERE I CREATE NEW SHADOW
      squareCreator.creator();
      squareCreator.addColor();
      squareCreator.addShadow();
     // squareCreator.revealDiv()
      shadows.revealDiv()

    }
}

const game = new Game();
game.init()
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="gameField" id='field'></div>



    <script src="js/script.js" type="module"></script>
</body>
</html>

【问题讨论】:

    标签: javascript arrays oop


    【解决方案1】:

    你可以这样做:

    addEventListener("DOMContentLoaded", () => {
      game.init(); 
    });
    

    【讨论】:

    【解决方案2】:

    取消超时

        addShadow() {
            this.divs.forEach((div)=>{
              div.classList.add('shadow')
            })
        }
    

    重新排序 ini() 并在 addShadow 之后使用 querySelector 否则将没有任何选择。

        init() {
          const squareCreator = new Square(this.elements.number,this.elements.type,this.elements.field);
          squareCreator.creator();
          squareCreator.addColor();
          squareCreator.addShadow();
          const shadows = new Shadow(document.querySelectorAll('.shadow')) // AND THERE I CREATE NEW SHADOW
          shadows.revealDiv()
        }
    

    【讨论】:

    • 我应该用这个设置的 Timeout 替换我的 const 变量吗?我收到类型错误,因为我尝试替换 const 值,当我将此变量更改为 let,但仍然没有任何反应
    • 我的错,把需要dom元素的部分包起来
    • 还是什么都没有 :( 可能是我的代码的另一部分不好?我按照你说的把它包装起来,然后把 squareCreator.creator(); 放在这个超时之外
    • 哈哈。我知道是什么问题。在创建阴影类并将其添加到 div 之前,您正在使用 querySelector。移除 addShadow 中的 setTimeout,将 Shadow 初始化移到 init() 中 addShadow 之后,并在添加完类之后使用 querySelector。
    • omg :D 感谢您的宝贵时间!现在我明白了