javascript - statement - Añadir método onclick utilizando for loop
loop object javascript (1)
Estoy agregando eventos clickclick a elementos que estoy creando dinámicamente. Estoy usando el código a continuación, esta es la parte importante solamente.
Test.prototype.Show= function (contents) {
for (i = 0; i <= contents.length - 1; i++) {
var menulink = document.createElement(''a'');
menulink.href = "javascript:;";
menulink.onclick = function () { return that.ClickContent.apply(that, [contents[i]]); };
}
}
Primero dice que no está definido. Luego cambié y agregué:
var content = content[i];
menulink.onclick = function () { return that.ClickContent.apply(that, [content]); };
Lo que sucede ahora es que siempre agrega el último elemento a todos los eventos onclick (elementos aka). ¿Qué estoy haciendo mal aquí?
Es un problema clásico. Cuando se llama a la devolución de llamada, el ciclo finaliza, por lo que el valor de i
es content.length
.
Use esto por ejemplo:
Test.prototype.Show= function (contents) {
for (var i = 0; i < contents.length; i++) { // no need to have <= and -1
(function(i){ // creates a new variable i
var menulink = document.createElement(''a'');
menulink.href = "javascript:;";
menulink.onclick = function () { return that.ClickContent.apply(that, [contents[i]]); };
})(i);
}
}
Esta función llamada inmediatamente crea un alcance para una nueva variable i
, cuyo valor está así protegido.
Mejor aún, separe el código que hace que el controlador se convierta en una función, tanto para mayor claridad como para evitar crear y descartar innecesariamente las funciones del constructor:
Test.prototype.Show = function (contents) {
for (var i = 0; i <= contents.length - 1; i++) {
var menulink = document.createElement(''a'');
menulink.href = "javascript:;";
menulink.onclick = makeHandler(i);
}
function makeHandler(index) {
return function () {
return that.ClickContent.apply(that, [contents[index]]);
};
}
};
Una forma de evitar este problema por completo, si no necesita compatibilidad con IE8 , es introducir un alcance con forEach
, en lugar de utilizar un bucle for
:
Test.prototype.Show = function (contents) {
contents.forEach(function(content) {
var menulink = document.createElement(''a'');
menulink.href = "javascript:;";
menulink.onclick = function() {
return that.ClickContent.call(that, content);
};
});
}