ブログBlog

    • JQueryのclick()とon()の違いについて

    • 2015年11月16日
    • jQuery
皆さん。こんにちは。 元デスクトップアプリケーションのプロ中野です。 今はWEBアプリも開発するようになり、学習の日々です。 そんな私が、開発中に、ハマったり疑問に思ったことを書いていこうかと思います。 もうちょっと自分の中で理想形が固まったら、がっつり設計思想も書きたいと思ってます。 今回は、WEBを開発する上で避けて通れないJQueryについてです。 テーマはJQueryのclick()とon()の違いについてです。 先日、開発中に $(document).on(‘click’,’.button’,function(){alert(‘詳細情報の表示’);}); というソースと見て、 浅はかな私は なんでこんなめんどくさい書き方するんだろー。 $(‘.button’).click(function(){alert(‘詳細情報の表示’);}); これでいいじゃん。 と書き換えてしまいました。 以下サンプルソース。 ・編集前
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
  $(document).on('click','.button',function(){ //←ここ
    alert('詳細情報の表示');
  });
  $('#addRow').on('click', function() {
    $('#table_sample').append('<tr><td>D</td><td><button class="button">詳細</button></td></tr>');  
  });
});
</script>
<style type="text/css">
#table_sample {
border-collapse: collapse;
}
#table_sample th {
background-color: #cccccc;
}
</style>
</head>
<boby>
 <table id="table_sample" border=1>
  <tr><th>商品</th><th>詳細</th></tr>
  <tr><td>A</td><td><button class="button">詳細</button></td></tr>
  <tr><td>B</td><td><button class="button">詳細</button></td></tr>
  <tr><td>C</td><td><button class="button">詳細</button></td></tr>
 </table>
 <button id="addRow">行追加</button>
</boby>
</html>
・編集後
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
  $('.button').click(function(){ //←こんな風に
    alert('詳細情報の表示');
  });
  $('#addRow').on('click', function() {
    $('#table_sample').append('<tr><td>D</td><td><button class="button">詳細</button></td></tr>');  
  });
});
</script>
<style type="text/css">
#table_sample {
border-collapse: collapse;
}
#table_sample th {
background-color: #cccccc;
}
</style>
</head>
<boby>
 <table id="table_sample" border=1>
  <tr><th>商品</th><th>詳細</th></tr>
  <tr><td>A</td><td><button class="button">詳細</button></td></tr>
  <tr><td>B</td><td><button class="button">詳細</button></td></tr>
  <tr><td>C</td><td><button class="button">詳細</button></td></tr>
 </table>
 <button id="addRow">行追加</button>
</boby>
</html>
その結果、初めからグリッドに表示されているボタンは クリックイベントが有効なのですが、 後で追加された行のボタンは クリックイベントが効かなくなってしまいました…。 単純に挙動を比較すると click()によるイベント付与は、ページロード時に存在する要素にイベントを付与して その後動的に追加されたものには有効でない。 (サンプルソースの場合、$(document).ready()に記載しているので当然そうなる) on()によるイベント付与は、ページロード時後、動的に追加された要素にも イベント付与してくれる。 という違いがあることがわかりました。 on()についてもう少し調べてみると jQueryバージョン1.7から bind(),live(),delegate()が on(),off()に統合されたことがわかります。 ・bind()  イベントの付与を行う。  ⇒click()と変わらないね。 ・live()  将来追加されるセレクタにも有効。すなわち、動的に追加された要素にも有効な優れもの  ⇒これが今回ハマったon()の機能ですね。なるほど。 ・delegate()  親要素に対しイベントを付与し、バブリングで呼び出し元の要素を判定する  ⇒live()との差が難解なのですが、   live()はイベントを付与する対象がdocument全体になるという違いがあり、   delegate()のほうが高速に動くというメリットがあるようです。 で、delegate()の機能を加味するとサンプルソースは以下のように Tableに対してイベントを設定することもできることもわかりました。 この書き方だと、buttonごとにイベントを付与する必要がないので 画面の挙動も軽くできるというメリットがあります。 ・再修正後
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
  $("#table_sample").on('click','button',function(){ //←こうするとベスト
    alert('詳細情報の表示');
  });
  $('#addRow').on('click', function() {
    $('#table_sample').append('<tr><td>D</td><td><button class="button">詳細</button></td></tr>');  
  });
});
</script>
<style type="text/css">
#table_sample {
border-collapse: collapse;
}
#table_sample th {
background-color: #cccccc;
}
</style>
</head>
<boby>
 <table id="table_sample" border=1>
  <tr><th>商品</th><th>詳細</th></tr>
  <tr><td>A</td><td><button class="button">詳細</button></td></tr>
  <tr><td>B</td><td><button class="button">詳細</button></td></tr>
  <tr><td>C</td><td><button class="button">詳細</button></td></tr>
 </table>
 <button id="addRow">行追加</button>
</boby>
</html>
クライアントサイドの技術はスクリプト言語ということもあり 同じ挙動をさせるにも、複数の書き方ができたりします。 「動いて満足」ということに慢心せず、 より良い実装方法を探求していきたいですね!

この記事を書いた人 : 中野健一

一覧へ戻る

開発についてのお問い合わせはこちら

お問い合わせ

JOIN OUR TEAM

積極採用しています。私たちと一緒に働きませんか?