0

I'm trying to create dynamically a menu in Javascript with a function with one argument in the onclick property using the code bellow:

function createCameraMenu() {
    var nav = document.createElement('nav');
    var ul  = document.createElement('ul');
    ul.className = "menu";

    for (var i = 0; i < cameraID.length; i = i + 1) {
        var liField = document.createElement('li');
        var aField  = document.createElement('a');

        aField.textContent = "CAMERA " + i;

        aField.onclick = function() {
            hideImages(i);
        };

        li.appendChild(aField);
        ul.appendChild(li);
    }

    nav.appendChild(ul);
    document.body.appendChild(nav);
}

and the result should be the code bellow:

<nav>
    <ul class="menu" >
        <li><a href="#" onClick="hideImages(0)">CAMERA 1</a></li>
        <li><a href="#" onClick="hideImages(1)">CAMERA 2</a></li>
        <li><a href="#" onClick="hideImages(2)">CAMERA 3</a></li>                
    </ul>
</nav>

but after creating the menu, for any item clicked, the function hideImages(3) is executed. For some reason, all my functions are created with the same argument (3), that is the value of "i" rejected in the for loop. There is no global var i in my code and I don't know why this is happening. This function is executed in a script tag in the head of the HTML file.

daniboy000
  • 1,069
  • 2
  • 16
  • 26

1 Answers1

4

You need to use a closure, e.g:

for (var i = 0; i < cameraID.length; i = i++) {
        var liField = document.createElement('li');
        var aField  = document.createElement('a');

        aField.textContent = "CAMERA " + i;

        aField.onclick = (function(i){ return function() {
            hideImages(i);
        };})(i);

        li.appendChild(aField);
        ul.appendChild(li);
    }

Now for readability, you can use a referenced method instead:

aField.onclick = hideImages.bind(aField, i);
Community
  • 1
  • 1
A. Wolff
  • 74,033
  • 9
  • 94
  • 155