Only the last menu is working

The value of u and v are coming correctly as 1 and 0… but the values are not being used in the statement “t[i].children[v].onclick=function(){}” ..!! This works perfectly when I used 1 in the place of u and 0 in the place of v!!! Here is the code :

    <div class="dropdown">
    <span class="menu-toggler">Menu</span>
    <ul>
    <li>First Part</li>
    <li>Second Part</li>
    </ul>
</div>

<div class="dropdown">
    <span class="menu-toggler">Menu</span>
    <ul>
    <li>First Part</li>
    <li>Second Part</li>
    </ul>
    </div>

    <script type="text/javascript">

   function init()
   {
    t = document.getElementsByClassName("dropdown");
    for(var i=0;i<t.length;i++)
    {
        v = parseInt(getMenuToggler(t[i]));
        u = parseInt(getDropDown(t[i]));

    (function (v, u){

    t[i].children[v].onclick = function() {
    if (this.parentNode.children[u].classList.contains("menu-open")) {
        this.parentNode.children[u].classList.remove("menu-open");
      } else {
        this.parentNode.children[u].classList.add("menu-open");
      }
    };

   })(getMenuToggler(t[i]), getDropDown(t[i]));
    }
    }

    function getDropDown(x)//this function is perfectly ok
    {
    for(j=0;j<x.childElementCount;j++)
    {
        if(x.children[j].classList.contains("dropdown-menu"))
        return j;
    }
    return -1;
    }

   function getMenuToggler(y) // this function is perfectly ok
   {
    for(k=0;k<y.childElementCount;k++)
    {
        if(y.children[k].classList.contains("menu-toggler"))
        return k;
    }
    return -1;
    }
     </script>
    <script>window.onload=init;</script>

thank you in advance… 🙂

Answer

As you are using the variables in an event handler bound in a loop, you need one set of variables for each iteration in the loop. Otherwise all event handlers will use the same variables, and get the values for the last item in the loop.

Use a function wrapper to create a set of varibles for each iteration:

for (var i = 0; i < t.length; i++) {

  (function (v, u){

    t[i].children[v].onclick = function() {
      if (this.parentNode.children[u].classList.contains("menu-open")) {
        this.parentNode.children[u].classList.remove("menu-open");
      } else {
        this.parentNode.children[u].classList.add("menu-open");
      }
    };

  })(getMenuToggler(t[i]), getDropDown(t[i]));

}

Leave a Reply

Your email address will not be published. Required fields are marked *