2011-11-02 265 views
0

我在传递函数时遇到了一些困难。 我有这样的代码:将参数作为参数传递给jQuery的回调参数

var options = [ 
     { name: "menu 1", func: function (element) { $(element).css("color", "Red"); } }, 
     { name: "menu 2", func: function (element) { alert("menu 2"); } }, 
     { name: "menu 3", func: function (element) { alert("menu 3"); } } 
    ]; 

     // This basically creates a div with ul, and li element for each object in options, 
     // and attaches click event to each li that should fire provided func. 
     (function menuMaker(options) { 
      var menuDiv = $("<div id='test' />"); 
      var menuUl = $("<ul>"); 
      menuDiv.append(menuUl); 

      for (var i = 0; i < options.length; i++) { 
       var li = $("<li>" + options[i].name + "</li>"); 
       // **li.click(function() { options[i].func(menuDiv); });** 
       //>> The line above gives "options[i] is undefined" error. Looks like a scoping issue. 

       var userFunc = options[i].func; 
       **li.click(function(){ userFunc(menuDiv);});** 
       //>> The line above always fires the last function (alert("menu 3")) 

       menuUl.append(li); 
      } 
      $(document.body).append(menuDiv); 
     })(options); 

和我得到我评论这些错误。 任何想法我做错了什么?

谢谢!

+0

所以我最终重写了这样的for循环: for(var i = 0;我”+ options [i] .name +“”); var func = function(uf){return function(){uf(menuDiv); }} //改变范围 li.click(func(options [i] .func)); menuUl.append(li); } 闭合和范围..杜! – Evgeni

回答

1

误解封闭的典型例子。看看如何解决这个问题here

+0

很好的参考!不能相信我到目前为止错过了它。 – hugomg

+0

确实很好的参考,谢谢! – Evgeni

1

这个问题确实是一个范围。 for循环不会创建一个新的范围,所以你必须创建一个里面想:

for (var i=0; i<10; i++) { 
    (function(i) { 
     // "i" will be local here, and be accessible 
     // form any function defined inside this closure 
    })(i); 
} 
1

试试这个,它遍历数组添加<li>元素了。要调用的函数被分配给本地的'func'变量,然后在click处理函数中使用。

$.each(options, function() { 
    var func = this.func; 

    menuUl.append(
     $('<li>').text(this.name).click(function() { 
      func(menuDiv); 
     }) 
    ); 
}); 
1

卸下“(功能menuMaker(选项){ ”选项变量已设定的功能之外。“选项”参数通过添加其作为参数的函数查找的“的说法选项“,而不是选项的预定义变量

我不是很擅长解释的东西,但至于通过for循环和每个单独的单击事件传递函数,创建一个像下面这样的空函数,这样它就不会引用使用的最后一个值

测试!Works!

var options = [ 
    { name: "menu 1", func: function (element) { $(element).css("color", "Red"); } }, 
    { name: "menu 2", func: function (element) { alert("menu 2"); } }, 
    { name: "menu 3", func: function (element) { alert("menu 3"); } } 
]; 

(function menuMaker() { 
    var menuDiv = $('<div id="test" />'), 
     menuUl = $('<ul />').appendTo(menuDiv); 

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

     (function() { 
      var func = options[i].func; 
      $('<li>' + options[i].name + '</li>') 
      .click(function(){ func(menuDiv); }) 
      .appendTo(menuUl);   
     })(); 

    } 

    $(document.body).append(menuDiv); 
})(); 
+0

我宁愿有内部闭包得到我参数的版本。你的解决方案是可行的,因为他设置了中间的“func”变量,但如果在事件处理程序中添加了“i”的任何其他用途,就会中断。 – hugomg