I cannot access the index of a for inside addeventlistener

Asked

Viewed 43 times

-1

   docReady(function () {
    var arr = ["usuario/cadastroum"];
    var lis = document.querySelector(".metro").getElementsByTagName("li");

    for (var i = 0; i < lis.length; i++) {
        lis[i].addEventListener("click", () => {
            console.log(i);
            if (arr[i]) {
                apontar(arr[i], false);
            }
        });
    }
   });

In the console.log appears 5 (because there are 6 <li>), be the first, the second, the third, etc... When I click on the first <li>, I want 0 to appear and not 5, however, always appears 5, can help me?

2 answers

2

Barter var for let even solves and yes, the use of this is correct, but the point at this point is that the main problem is trying to take something that neither "there was more", I mean, in the var i when you accessed apontar(arr[i], false); it took the value as the last operation of the loop, this could be simply solved by isolating in a function and using the this, for example:

var arr = ["usuario/cadastroum"];
var lis = document.querySelector(".metro").getElementsByTagName("li");

for (var i = 0; i < lis.length; i++) {
    lis[i].addEventListener("click", apontarClick);
}

function apontarClick() {
    apontar(this, false);
}

function apontar(elemento, acao) {
    console.log(elemento, acao);
}
.metro li {
    padding: 15px 5px;
}

.metro li:hover {
    background: #fc0;
}
<ul class="metro">
   <li>1</li>
   <li>2</li>
   <li>3</li>
   <li>4</li>
   <li>5</li>
   <li>6</li>
</ul>

This way it even isolates and facilitates possible future maintenance in the code.

You could also use Event.currentTarget to take the element associated with the event, as in the example we passed the parameter (e) =>

for (var i = 0; i < lis.length; i++) {
    lis[i].addEventListener("click", (e) => apontar(e.currentTarget, false));
}

1


This is due to the scope problem of var in your loop where you have the for (var i = 0; i < lis.length; i++), read more about this.

But basically what happens is that with each iteration of the loop, Voce ends up redefining the value of i because of the scope problem.

I think simply replacing var for let, solves your problem. It would look like your code:

docReady(function () {
    var arr = ["usuario/cadastroum"];
    var lis = document.querySelector(".metro").getElementsByTagName("li");

    // for (var i = 0; i < lis.length; i++) {
    for (let i = 0; i < lis.length; i++) {
        lis[i].addEventListener("click", () => {
            console.log(i);
            if (arr[i]) {
                apontar(arr[i], false);
            }
        });
    }
   });

Run the tests and tell me if you’ve solved.

Learn more:

  • Man, I don’t know how to thank you, thank you very much! I didn’t know that difference! + 1

Browser other questions tagged

You are not signed in. Login or sign up in order to post.