jQuery の bind(click とか) でロード時ではなく後からイベントを登録し、後からも何度も呼ばれる場合次々と実行する関数を追加してしまう。こうした場合リスナーを削除する必要が出てくるわけで jQuery の場合には unbind 関数で、イベント(名)と関数を渡して削除してあげる。
$("#hoge").click(function(e) {
$(this).unbind(e, arguments.caller); // $(this).unbind(e.type, arguments.caller);
alert('foo');
});
この場合 click イベントが新たに追加される前にクリックされることが前提条件にはなるけれど。。
jQuery には一度だけ実行する関数がすでに提供されていたような気がしたので調べてみると one メソッドがあった。これに置き換えるとすっきりする。
$("#hoge").one("click", function() {
alert('foo');
});
中で何が行われているか少し興味があったので one メソッドを覗いてみるとコード量が少なそうで、これぐらいなら気軽に読める。
one: function( type, data, fn ) {
var one = jQuery.event.proxy( fn || data, function(event) {
jQuery(this).unbind(event, one);
return (fn || data).apply( this, arguments );
});
return this.each(function(){
jQuery.event.add( this, type, one, fn && data);
});
},
proxy の第二引数の関数オブジェクトを返して登録する。実行時に登録した関数をアンバインドして、実際に実行する関数を遅延実行する仕組み。また登録時に each で回しているのはセレクタ指定等で複数のオブジェクトに対応するためで、あちらこちらで each が使われている。
それから fn && data って条件文にしか使えていなかったけど、 fn が定義されていたら data を渡すようにできることをコードをみて、あ、そうかと。 true/false を返すイメージがこびり付いているけど、先頭から順に評価し有効値であれば最後まで評価し、最後のオブジェクトを返す。
やっぱりコードリーディングは大事だなあ。使えることが大事でなくて、中で何が行われているか理解していく(想像できる)ことを意識していこう。