Простая ванильная JS-игра

#javascript #arrays #oop

Вопрос:

Я попытался написать простую игру vanilla JS memories. У меня возникла проблема, когда я попытался использовать селектор запросов для дивов, созданных в классе Square. Приставка.журнал возвращает пустой список узлов или массив. Я подозреваю, что эта функция выполняется до создания дивов. Как я могу получить этот элемент с помощью селектора запросов или другого метода ?

 // 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> 

Ответ №1:

Вы можете просто сделать это:

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

Комментарии:

1. Большое вам спасибо, но куда я должен поместить этого слушателя событий ?

2. Куда бы ты ни захотел. Всегда ждите, пока DOM не загрузится. или вы можете использовать свойство отсрочки: developer.mozilla.org/en-US/docs/Web/HTML/Element/script

Ответ №2:

Удалите тайм-аут

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

Измените порядок ini() и используйте 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()
    }
 

Комментарии:

1. Я должен заменить свою переменную const на этот установленный тайм-аут ? Я получил ошибку типа, потому что я пытаюсь заменить значение const, и когда я изменяю эту переменную на let, но все равно ничего не происходит

2. Моя ошибка, оберните части, которые нуждаются в элементах dom

3. по-прежнему ничего 🙁 может быть, это моя ошибка в другой части кода ? я заворачиваю его, как вы говорите, и помещаю squareCreator.creator(); вне этого тайм-аута

4. Хаха. Я понимаю, в чем проблема. Вы выполняете выбор запроса перед созданием и добавлением класса shadow в divs. Удалите параметр setTimeout в addShadow, переместите инициализацию тени после addShadow в init() и используйте параметр querySelector после добавленных классов.

5. omg 😀 спасибо за ваше время ! теперь я понимаю