Search code examples
javascriptclasseventsmouseenter

Class-wide Event is Malfunctioning


I create a 16x16 grid of divs in JavaScript. Each div has a mouse enter event (inherited based on common class) that should change its black background to white.

Here's my problem: whereas each div should change color when it's hovered over, all divs (when hovered over) cause the same bottom-right div to change color, rather than themselves.


I believe all of the events reference the final div under the className "squares" (bottom right div). How do I make each event reference its own div?

SNAPSHOT enter image description here

CODE

    //GRID CREATION (30x30)
    var container = document.getElementById('container');
    var size = 30;

    //Row Creation (30)
    for(j=0; j < size; j++) {
        var row = document.createElement('div');
        row.classList.add("row");

        //Square Creation (30 per Row)
        for(i=0; i<size; i++) {
            var square = document.createElement('div')
            square.classList.add("square");

            //div background-color changes on mouse-enter   
            square.addEventListener('mouseenter', () => { 
                this.square.style.background = 'white';
            });

            row.appendChild(square);
        }
        container.append(row);
    }

Solution

  • It’s strange to find this.square in your event listener when nothing else refers to this.square. Perhaps you originally tried square.style.background, which didn’t work for the reason described in JavaScript closure inside loops – simple practical example, then tried to fix it with this.style.background = 'white';, which didn’t work because it was an arrow function, then tried to make this.square work…?

    Anyway, use either a non-arrow function, to get this inside to be the element the event listener was attached to instead of the same as the this outside:

    square.addEventListener('mouseenter', function () { 
        this.style.background = 'white';
    });

    or better, declare your variables with let – which must be available, since you were using an arrow function – and refer to square:

    //GRID CREATION (30x30)
    let container = document.getElementById('container');
    let size = 30;
    
    //Row Creation (30)
    for (let j = 0; j < size; j++) {
        let row = document.createElement('div');
        row.classList.add("row");
    
        //Square Creation (30 per Row)
        for (let i = 0; i < size; i++) {
            let square = document.createElement('div');
            square.classList.add("square");
    
            //div background-color changes on mouse-enter   
            square.addEventListener('mouseenter', () => { 
                square.style.background = 'white';
            });
    
            row.appendChild(square);
        }
        container.append(row);
    }
    

    Declarations for j and i were missing, too. You should enable strict mode and never use var to avoid these types of problems.