w3schools statement para loop for example javascript object onclick apply

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); }; }); }