JavaScript将参数传递给按钮onclick函数

时间:2012-07-31 20:43:46

标签: javascript html function button

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

我的代码:

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

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

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

我确信这有一些常见的设计模式。

谢谢!

3 个答案:

答案 0 :(得分:3)

一种方法是,对于每个按钮,调用一个“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代替上述代码。)

答案 1 :(得分: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的新范围。 #39; t用于任何外部功能。这使闭包仅超过立即值,将其从i中分离出来,这就是你想要的。对此here进行了更深入的解释。

  3. 请注意,此页面上的另一个答案重复使用i,这可能令人困惑。这将起作用,但是内部函数内部i被引用的内部不清楚!我认为最好通过使用不同的变量名来避免混淆。

答案 2 :(得分:0)

您使用的是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属性来访问自定义属性。这是您可以实现它的一种方式。