2

The way I did this was by getting the html elements and declaring them as global const variables inside a function() {} that encapsulates the whole program. It works, but I'm unsure if this is good practice. Is there a way to allow reusability of an element without using an omnipresent function() {} or will this be fine?

My Code:

document.addEventListener('DOMContentLoaded', function() {

    //The global const elements from HTML doc
    const square = document.getElementsByClassName("square");
    const mole = document.getElementsByClassName("mole");
    const timeLeft = document.getElementsByClassName("time-left")[0]; //# for id elements

    //Initialize score, result, and time
    let score = document.getElementsByClassName("score")[0];
    let result = 0;
    let currentTime = timeLeft.textContent;

    //Call countDown function every 1000 milliseconds or 1 second
    let timerId = setInterval(countDown, 1000);

    function main() {

        //Add an event listener for each square called mouseup
        for (let i = 0; i < square.length; i++) {
            square[i].addEventListener("mouseup", checkHit);
        }
        
        moveMole()
    }

    //Once the event triggers, check if val of current square equals to hitPosition
    //If it is, update result and hitPosition
    function checkHit(event) {
        if (this.id === hitPosition) {
            result = result + 1;
            score.textContent = result;
            hitPosition = null;
        }
    }

    //Move mole to a random square every 1000 milliseconds
    function moveMole() {
        let timerId = null;
        timerId = setInterval(randomSquare, 1000);
    }

    //Choose a randomSquare to put the mole
    function randomSquare() {

        //Remove mole from the class name to make sure there isn't any forgotten divs that were used for styling
        for (let i = 0; i < square.length; i++) {
            square[i].classList.remove("mole");
        }

        //Math.floor rounds down
        //math.random() * 9 uses a position from 1 to 9
        let randomPosition = square[Math.floor(Math.random() * 9)];

        //Set the mole to the randomPostion
        randomPosition.classList.add("mole");

        //Assign the id of the randomPositon to hitPosition for comparing later
        hitPosition = randomPosition.id;
    }

    //Counts our timer down
    function countDown() {

        //Decrement currentTime and show currentTime
        currentTime--;
        timeLeft.textContent = currentTime;

        //If currentTime is 0
        //Clear the timer set by the setInterval method
        //Stops the execution of randomSquare
        //Alert user of final score
        //Reset time and result
        if (currentTime === 0) {
            alert("GAME OVER! Your final score is " + result);

            timeLeft.textContent = 30;
            currentTime = timeLeft.textContent;
            result = 0;
            score.textContent = result;
        }
    }

    main();
})
john1999
  • 47
  • 6
  • 1
    I guess everyone is afraid of answering this question, of course including me, because of "best way". If someone posted an answer as the best way, someone else would make negative comments. I'm curious about this topic too. I hope someone will share their way as an example. – Miu Mar 20 '21 at 06:08
  • Yeah, it seems like you can do this in different ways. I just found out that by using defer when calling the javascript in the html, you can just get the html elements without using the function() {} and it works fine when using those elements in the methods. – john1999 Mar 20 '21 at 19:13

1 Answers1

1

As far as I'm concerned, the code looks fine but make sure to look at other people and see what they're doing.

Feng
  • 19
  • 6
  • Yup, I'll definitely do that. JavaScript is so different from other languages I've learned so this is all weird for me lol. – john1999 Mar 20 '21 at 03:39