jQuery 1.7からイベントのバインドのためにonメソッドが追加されましたね。
jQuery 3からはbind()/unbind()/delegate()/undelegate()も削除されたので、これからはonメソッドで統一していくことになります。
しかし、ライブラリやフレームワークが変わっても実際に使用しなければ変わりません。いわゆるレガシーコードというものは誰かが修正するか窓から投げ捨てなければこの世から消えることはなく、いつの日か私たちの前に立ちはだかることになります。
私の前にも人生n回目のレガシーコードをナウでヤングなコードに修正する作業がやってきました。jQuery 1.2時代の書き方がこれでもかと使用されていまして、そこら中にliveが使われているので頑張ってonに書き換えました。その際にonについてちゃんと学んでおこうと思い調べたところ、私が知っていたonは氷山の一角だったことが判明したのでまとめてみました。
基本
$('#id').on('click', function(){
alert('click!');
});
その名の通り基本形。
セレクターで指定
セレクターを指定してイベントを登録できます。
$('#table').on('click', 'tr', function(){
alert('click!');
});
$('#table tr').on('click', function(){
alert('click!');
});
上記の2つは同じようにイベントを登録できます。 いまいち使いどころがわからない。
※2017/02/01追記
両者の違いについてコメントをいただきました。
- 前者は$('#table')に対してイベントを設定する。trが何個あってもイベントは1個しか設定されない。
- 前者は$('#table')配下のtrであれば後から追加した要素でも発火する。
- 後者は$('table tr')に対してイベントを設定する。trが100個あったらイベントは100個設定されるので前者より遅い。
- 後者は後から追加した要素では発火しない。
目から鱗です。これからはちゃんと使い分けていこうと思います。
同じ要素に複数のイベントを登録
例えば一つの要素にclickとhoverの二つのイベントを実装することがあるかもしれない。
$('#id').on(
{
click: function(){
alert('click!');
},
mouseenter: function(){
alert('hover!');
},
mouseleave: function(){
alert('unhover!');
}
}
);
オブジェクトに複数入れると全部登録してくれます。賢いですね。
hoverはmouseenterとmouseleaveになるとか知らなかった……
event.dataで値を渡すことができる
第二引数にオブジェクトを渡してやると、コールバック関数に渡すことができます。
$('#id').on(
'click',
{
id: 101,
name: 'jirou'
},
function(event){
alert(event.data.id + ':' + event.data.name);
}
);
これでもうグローバル変数に値を入れておいてコールバックの中で使うとかいう石器時代のコードとは決別できますね!
triggerから値を渡す
登録したイベントはtriggerメソッドで呼び出すことができますが、triggerメソッドからでも値を渡すことができます。
$('#id').on('click', function(event){
alert(event.name));
});
$('#id').trigger('click', { name: 'tarou' });
triggerから配列で値を渡す
配列で値を渡すと、引数として扱われます。
$('#id').on('click', function(event, id, name){
alert(id + ':' + name);
});
$('#id').trigger('click', [102, 'tarou']);
もうこれで石器時代とは(ry
イベントの伝播(バブリング)を止める
コールバックにfalseを渡すか、コールバックからfalseをreturnするとイベントの伝播を止めることができます。
$('#form').on('submit', false );
$('#form').on('submit', function(){
return false;
});
$('#form').on('submit', function(event){
event.preventDefault();
event.stopPropagation();
});
デフォルト挙動と伝播の両方を止めたいならreturn falseでOKですが、片方だけ止めたい場合はそれぞれメソッドを呼びましょうねということですね。
まとめ
基本とセレクターで指定以外は全く知りませんでした……。もっと早く知っていればレガシーコードを生み出さずに済んだかもしれませんし、あの時に技術的負債を返済できたかもしれません。枕に顔をうずめてバタバタすることも少なくなるはずです。
公式のドキュメントはよく読まないといけませんね。知らないものは使えないのです。知って初めて使えるのですから。