Kedfygo
Kedfygo

Reputation: 33

How to fix addEventListener in my code? It seems like it's being canceled at any time

I'm trying to make a grid with a determined number of squares inside a container. I have used a function with a default 16x16 squares and added an EventListener (mouseover) to add a class to any div. It works perfectly when I first refresh the page. The problem is that when I want to reset the number of squares with a personalized function, my code do the job, but the EventListener stops working. Any Help Here?

const container = document.getElementById('container');

const buttonsDiv = document.querySelector('#buttons-div');

setGrid();

function resetGrid() {
    clearGrid();

    while (container.firstChild) {
        container.removeChild(container.firstChild);
    };

    let numberOfsquares = prompt('Number of squares??? 1-64:');
    return setGrid(numberOfsquares);
}

function setGrid(numberOfsquares = 16) {
    let heightAndWidth = 960 / numberOfsquares;
    for (let i = 0; i < numberOfsquares; i++) {
        for (let j = 0; j < numberOfsquares; j++) {
            const divNode = document.createElement('div');
            divNode.classList.add('unit');
            divNode.style.width = heightAndWidth + 'px';
            divNode.style.height = heightAndWidth + 'px';
            container.appendChild(divNode);
        }
    }
    return numberOfsquares;
}

function clearGrid() {
    squares.forEach((square) => {
        square.classList.remove('hover');
    });
}

let squares = document.querySelectorAll('.unit');
squares.forEach((square) => {
    square.addEventListener('mouseover', (e) => {
        console.log('listened');
        square.classList.add('hover');
    });
});

const clearButton = document.createElement('button');
clearButton.textContent = 'Clear';
clearButton.classList.add('reset-button');
clearButton.setAttribute('id', 'clearButton');
buttonsDiv.appendChild(clearButton);

const resetButton = document.createElement('button');
resetButton.textContent = 'Reset';
resetButton.classList.add('reset-button');
resetButton.setAttribute('id', 'resetButton');
buttonsDiv.appendChild(resetButton);

const buttons = document.querySelectorAll('button');
buttons.forEach((button) => {
    button.addEventListener('click', (e) => {
        if (button.id === 'clearButton') {
            clearGrid();
        } else if (button.id === 'resetButton') {
            resetGrid();
        }
    });
});

Upvotes: 1

Views: 48

Answers (1)

philipp
philipp

Reputation: 16495

As stated in the comments. The resetGrid function removes the elements from the DOM, so the attached Event Listener wont be called any more, since the Element just does not exist anymore. I recommend to use "event delegation" for this. So attach the Event Listener to the container and use e.target witin the callback to figure out which item was hit.

container.addEventListener('mouseover', e => {
  const { target } = e;
  //use the child index for instance, or add col and row using a data attribute
})

Upvotes: 1

Related Questions