Tech Racho エンジニアの「?」を「!」に。
  • 開発

jQuery: JavaScriptでイベントハンドラに好きな値を渡す方法

他の言語に慣れていると、JavaScriptのスコープチェーンが分かりづらいですね。

たとえば、jQueryでクリックイベントに関数を登録する際、外の変数を参照すると予期せぬ結果になってしまうことがあります。

例:すべてのボタンで3が表示されてしまう

<html>
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(function() {
    for (var i = 0; i < 3; i++) {
        $('#button' + i).click(function() {
            alert(i);
        });
    }
});
</script>
</head>
<body>
<button id="button0">0</button>
<button id="button1">1</button>
<button id="button2">2</button>
</body>
</html>

このような場合、以下のようにすることで、意図した動作が実現できます。

for (var i = 0; i < 3; i++) {
    $('#button' + i).click((function(i) {
        return function() {
            alert(i);
        }
    })(i));
}

しかし、毎回これをやるのも面倒なので、好きな引数を渡せるような関数を作ってしまうのも良いですね。
これなら可変長引数にもそのままで対応できます。

$.func = function() {
    var fn = arguments[arguments.length - 1];

    var arg = new Array(arguments.length - 1);
    for (var i = 0; i < arguments.length - 1; i++) {
        arg[i] = arguments[i];
    }

    return function() {
        fn.apply(this, arg);
    }
};

for (var i = 0; i < 3; i++) {
    $('#button' + i).click($.func(i, function(i) {
        alert(i);
    }));
}

jQueryにはdojo.hitch相当のものがないですが、これで似たようなことはできそうです。

追伸

4/17追記

jQuery1.4 で追加された jQuery.proxy が dojo.hitch 相当なので、これを使っても良かったですね。
まあお好みで・・・

というより、よく 1.3 までこの関数なしでやってきましたよね。必須だと思うのですが。


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。