【问题标题】:Firefox Javascript Events Anonymous FunctionFirefox Javascript 事件匿名函数
【发布时间】:2010-09-22 16:16:48
【问题描述】:

当用户单击 HTML 表格中的单元格时,我正在尝试注册一个匿名函数。下面是一些原始的、纯粹的代码:

document.getElementById(
    "course"+displayed_year_index+occurrences_indices[displayed_year_index]).onclick =
        eval("function() {PrintReceipt("+result.years[result_year_index].rul_code+");};");

注意eval 的使用,因为它位于一个循环中,并且匿名函数每次都不同。

可以这么说,这在 Firefox 2 中工作得非常好。但是,Firefox 3 会抛出一个“语法错误”,指向“函数”一词之后的括号内。

有人对我如何解决这个问题有任何聪明的想法吗?


为了清楚地说明我想要做什么,这里有一个非常简化的示例:

for (index=0; index<4; index++) {
    document.getElementById("div"+index).onclick = 
        eval("function () {Foo(index);};");
}

换句话说,我希望为每个div触发具有不同参数值的相同函数。

【问题讨论】:

    标签: javascript firefox event-handling closures anonymous-function


    【解决方案1】:

    你尝试过这样的事情吗?

    document.getElementById('course' + displayed_year_index + occurences_indices[displayed_year_index]) =
        function (nr)
        {
            return function () { PrintReceipt(nr) }
        } (result.years[result_year_index].rul_code);
    

    您能否发布循环以帮助我们找到问题,而不是让我们猜测您要做什么?

    【讨论】:

    • 很好的答案,但是一个很好的闭包解释的链接会有很大帮助。我理解你的代码,但它仍然让我害怕;)不知道闭包是什么的人没有机会。不幸的是,我还没有在网上看到任何关于闭包的清晰、简洁的解释:(
    • 不幸的是,我需要分配给onclick事件,因此我无法将参数传递给匿名函数。
    【解决方案2】:

    这似乎是你想要去的方向:

    document.getElementById("course"+displayed_year_index+occurrences_indices[displayed_year_index]).addeventlistener("click",  function() {
        var current_rul_code = result.years[result_year_index].rul_code;
        PrintReceipt(current_rul_code);
    }, true);
    

    这应该会导致在不同的范围内创建每个 onclick 事件(循环的每次迭代)。 Closures 将负责其余的工作。

    【讨论】:

    • 这个不行,因为在onclick调用时PrintReceipt的参数需要是常量。
    • 它不应该是一个常量,因为当事件触发时,该函数将在其原始范围内被调用。
    • 谢谢,我已经按照说明尝试了您的示例,但它不起作用。这是因为从 onClick 调用函数时 result.years[result_year_index].rul_code 不在作用域内。我真正需要的是要传递给函数的变量的值(在本例中为 13208)。
    【解决方案3】:

    使用 Tom 建议的闭包。

    这是 John Resig 的一个很好的解释:How Closures Work (pdf)

    【讨论】:

      【解决方案4】:

      恕我直言,在这种情况下不应该使用闭包,也不需要为每个 onlick 创建一个新函数(使用比必要更多的内存)并且 eval 是错误的答案。

      您知道您使用 getElementById 获得的元素是一个对象,并且您可以为它赋值吗?

      for ( /* your definition */ ) {
        var e = document.getElementById(
          "course"+displayed_year_index+occurrences_indices[displayed_year_index]
        );
        e.rul_code = result.years[result_year_index].rul_code;
        e.onclick = PrintReceipt;
      }
      

      但你应该先定义 PrintReceipt:

      function PrintReceipt() {
        //This function is called as an onclick handler, and "this" is a reference to the element that was clicked.
        if (this.rul_code === undefined) { return; }
        //Do what you want with this.rul_code
        alert (this.rul_code);
      }
      

      【讨论】:

      • 你当然是完全正确的。永远不要用大锤敲碎坚果吧?
      • 谢谢。我一直在努力寻找答案!
      猜你喜欢
      • 2010-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-06
      • 1970-01-01
      • 2013-11-22
      • 2011-01-15
      相关资源
      最近更新 更多