user7551211
user7551211

Reputation: 707

JavaScript Event Listener's Function Doesn't Work Outside Nested Loop

I work on a js project that has a nested loop and I've got into a weird situation:

When functions are in the nested loop, e.g.

window.onload = function() {
let board = document.getElementById('board');

for ( let i = 0; i < 9; i++ ) {
    for ( let j = 0; j < 9; j++ ) {
        const block = [];
        block[i, j] = document.createElement( 'img' );
        block[i, j].src = "empty-block.png";
        block[i, j].coordinate_i = i;
        block[i, j].coordinate_j = j;
        block[i, j].addEventListener('contextmenu', function r_click(event)
        {
            coordinate_i = event.target.coordinate_i;
            coordinate_j = event.target.coordinate_j;
            block[coordinate_i, coordinate_j].src="flag.png";
            event.preventDefault();
        });
        board.appendChild(block[i, j]);
        }
    }
}

code will work as expected and when the button will get clicked with right-click, the image will be replaced.

but when I move the function outside the loop and call it from the inside, e.g.

block[i, j].addEventListener('contextmenu', r_click); 

the function won't work.

Can I get an explanation for these occurrences?

Upvotes: 1

Views: 81

Answers (1)

tstoev
tstoev

Reputation: 1435

it does not work because the function r_click is defined inline. If you pull it out as a separate function, and bind both events using its name it will work.

This is inline definition notice that the name of the function is not required, because the function is not needed because the function exists in the handler.

 block[i, j].addEventListener('contextmenu', function (event)
        {
            coordinate_i = event.target.coordinate_i;
            coordinate_j = event.target.coordinate_j;
            block[coordinate_i, coordinate_j].src="flag.png";
            event.preventDefault();
        });

This does the same as the code above, but the function is actually accessible from other places

    function r_click(event){
       coordinate_i = event.target.coordinate_i;
       coordinate_j = event.target.coordinate_j;
       block[coordinate_i, coordinate_j].src="flag.png";
       event.preventDefault();
    }
    window.onload = function() {
       //....code here ....
           block[i, j].addEventListener('contextmenu',r_click);
      //...more code here
    }

Upvotes: 1

Related Questions