JavaScript

トップ > チップス > JavaScript
2013-06-05, js

引数付きの関数をイベントハンドラ(onclick)に登録する

以下のような、引数によって動作を変える関数を複数のボタンやリンクに配置するケースを想定します。下記の例はjQueryの利用を前提としたコードになっています。

function foo(i){
    alert("You clicked "+i+".");
}

シンプルな解決先は以下のようにそれぞれの意図した引数を渡して実行する関数を設定してあげることです。

シンプルな方法 1
$("#b1").click(function(){foo(1);});
$("#b2").click(function(){foo(2);});
$("#b3").click(function(){foo(3);});

しかし、ボタンの数が多い場合など、変数を使って引数を設定しようとするとこれは(恐らく)あなたの意図に反した動きをします。このループを抜けるときに既に変数iの値は4になっていて、ボタンをクリックした際にその値が利用されてしまいます。

うまく行かない方法
# Wrong case! All button return "You clicked 4.".
for(var i = 1; i <= 3; i++){
  $("#b"+i).click(function(){foo(i);});
}

じゃあどうすれば?と悩んで、下記の参考URLに辿り着きました。関数の値渡しの性質を利用して、上記の関数を生成する無名関数をもう一枚被せてあげれば解決します。

うまく行く方法
for(var i = 1; i <= 3; i++){
  $("#b"+i).click(function(j){return function(){foo(j);};}(i));
}

しかし、これでは最早、暗号です…。少なくとも私には、後でこのコードを見直して、何をしようとしていたのか、言い当てる自信がありません。ここはもっとシンプルに考えましょう。HTML上のonclick属性には、元々文字列で実行すべき関数を指定することができます。「関数を渡す」なんて格好良いことを諦めれば、これはこれで十分実用性があるのではないでしょうか。

シンプルな方法 2
for(var i = 1; i <= 3; i++){
  $("#b"+i).attr("onclick","foo("+i+")");
}

参考URL

この記事は役に立ちましたか?