Code
function asignarEventos() {
var uno = document.getElementById("uno");
var dos = document.getElementById("dos");
var tres = document.getElementById("tres");
var arreglo = [uno, dos, tres];
for (var i = 0; i < arreglo.length; i++) {
var elemento = arreglo[i];
var texto = elemento.innerHTML.trim();
elemento.onclick = function(){
alert(texto);
};
}
}
asignarEventos();
<html>
<head>
</head>
<body>
<a id="uno">
Uno
</a>
<a id="dos">
Dos
</a>
<a id="tres">
Tres
</a>
</body>
</html>
Goal
The variable arreglo
contains a list of HTML elements, which are previously obtained using document.getElementById()
. Later I want to dynamically assign an event to the HTML element using the .onclick
DOM Element property.
What I want is that when clicking on any of the elements <a>
, a function is displayed alert()
or a function is executed showing the text contained in them.
Problem
In this section of the code:
var elemento = arreglo[i];
var texto = elemento.innerHTML.trim();
elemento.onclick = function(){
alert(texto);
};
I get the element contained in the variable arreglo
, and later I get its value innerHTML
, that is, the text it contains, then I assign the attribute onclick
by assigning an anonymous function that will execute a alert()
showing the text that contains the HTML element.
But clicking on any of the elements always prints the innerHTML
last element, in this case it is the word "three". When should be the value of each element individually.
Ask
How can an event be assigned onClick()
to an element obtained with document.getElementById()
?
Note
It should be clarified that I must solve the problem using pure JavaScript , it does not help me to use a library like jQuery or others, since in said environment I cannot use it.
The problem occurs due to scope/scope issues. Remember:
hosting example
As you can see, in the first example,
x
it is still available even outside the for loop, this happens because the ES5 variables undergo a different process when they are declared; this doesn't happen in ES6 withlet
andconst
.In your code, the variable
texto
, being of function scope, always stores the last reference assigned to it , that is, the text of the last element of the array. What you should do is use a closure or uselet
orconst
.For each iteration that it does
for
, the value of the variable is writtentexto
. Try accessing the element itself withthis
and thus reading the content:Using a Closure :
Why doesn't the original code work?
The function you have defined for the event
onClick
reads the value of the external variabletexto
at run time, instead of copying its value when the function is defined. Any subsequent modification of the external variable affects the execution of the function.Try displaying the text with something
this
like this: