【问题标题】:JavaScript passing arguments to button onclick functionsJavaScript 将参数传递给按钮 onclick 函数
【发布时间】:2012-07-31 20:43:45
【问题描述】:

我正在尝试通过循环创建一堆按钮,并使用循环迭代器作为每个按钮 onclick 函数的参数。

我的代码:

var testFnc = function(i) { alert("Arg: " + i); }

mainDiv.append(create_button(name, "buttonCSS", testFnc(i)));

但是,当页面加载和放置按钮时,这些函数会自动调用(即我会立即看到警报)。

我确信这有一些共同的设计模式。

谢谢!

【问题讨论】:

标签: javascript html function button


【解决方案1】:

一种方法是,为每个按钮调用一个“self-executing”函数来创建一个单独的函数。

mainDiv.append(create_button(name, "buttonCSS", (function(i) {

    // For the function below, i comes from
    // this function's scope, not the outside scope.

    return function() {
        testFnc(i);
    };

})(i) ));

这将允许您在函数外部更改i 的值,并且不影响现有按钮。

(如果您要创建很多按钮(可能是数千个),最好更改 create_button 函数以将属性添加到按钮元素本身并让您的函数进行检查。或者如果您的代码没有需要在 Internet Explorer 8 或更低版本中工作,您可以使用bind() function 代替上述代码。)

【讨论】:

  • 谢谢。这可以很容易地扩展到多个参数,对吧?
  • @YoungMoney:是的,只需添加附加参数即可。在上面的代码中,您需要将所有三个出现的(i) 替换为(i, j) 以添加新参数j
【解决方案2】:

注意:关于这个的非常详细的解释,请看我的previous answer to an identical question

  1. 通过使用括号,您调用 testFnc 并将其返回值传递给create_button 函数,因此它当然会立即发出警报。相反,您需要传入一个实际的函数对象而不调用它。通过将testFnc 包装在匿名函数中来做到这一点,ala function() { testFunc(i); }。你能看到这如何返回一个稍后运行而不是立即运行的函数吗?
  2. 这本身仍然不起作用,因为i 参与了一个围绕它的闭包,因此当点击事件运行时它使用最新的值 i (循环结束时的值),而不是绑定时的值。为了解决这个问题,围绕一个不同的变量创建一个新的闭包——只位于你的回调的直接范围内,而不是更高的——这将被赋予i,以便点击事件具有绑定时的值,而不是绑定函数执行时的值。

    这里是如何做到这一点:

    for (i = 0; i < len; i++) {
       mainDiv.append(
          create_button(name, "buttonCSS", (function(val) {
             return function() {
                testFnc(val);
             };
          }(i)))
       );
    }
    

    我确定这看起来有点令人困惑,但关键是,将被调用的函数(返回的函数)包装在另一个函数中会创建一个新的范围,其中包含一个未使用的变量 val任何外部功能。这使得闭包仅覆盖直接值,将其与i 分离,这正是您想要的。这个here有更深的解释。

请注意,此页面上的另一个答案重复使用 i,这可能会造成混淆。这将起作用,但是在内部函数内部不清楚 i 被引用!我认为使用不同的变量名来避免任何混淆是更好的做法。

【讨论】:

    【解决方案3】:

    你在使用 jQuery 吗?您可以引用按钮的类

    <button class='my-custom-class' data-index='0'>This button</button>
    

    document.ready:

    $(document).ready(function () {   
      buildButtons();
    
      $('.my-custom-class').on('click', function () { 
        var index = $(this).attr('data-index');
        alert('Arg: ' + index);
      });
    });
    

    我建议使用自定义data-* 属性,因为您可以使用jQuery 中的attr 属性来访问自定义属性。这是您可以实现它的一种方式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-26
      • 1970-01-01
      • 2019-04-01
      • 1970-01-01
      • 2015-02-07
      • 1970-01-01
      • 2013-12-16
      • 2018-04-19
      相关资源
      最近更新 更多