JavaScript では onclick プロパティに関数オブジェクトを代入することで、イベントを登録することができます。ある HTML 要素がクリックされたら指定の JavaScript コードを実行するといった動作はもはや当たり前となりましたが、自然な動作を実現しようとすると考慮しなければならないことがあります。
例えば、下記のように div 要素が div 要素を内包しており、外側の div 要素にイベントを登録した場合です。下記ではわかりやすくするために click イベントを使っています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<html> <head> <meta charset="utf-8" /> <style> #wrapper{ width: 250px; height: 250px; background: #cccccc; } #contents{ width: 200px; height: 200px; background: #eeeeee; } </style> <script> window.onload = function(){ document.getElementById('wrapper').onclick = function(){ alert('外側の要素がクリックされました。'); } } </script> </head> <body> <div id="wrapper"> 外側の要素です。 <div id="contents"> 内側の要素です。 </div> </div> </body> </html> |
上記のコードの状態では、「内側の要素」をクリックしたときに「外側の要素がクリックされました。」とアラートが表示されてしまいます。多くの場合、想定している挙動とは異なっていると思います。内側の要素がクリックされたときはアラートを表示したくないはずです。これは click イベントに限ったことではありませんが、JavaScript には「イベントのバブリング」という挙動があります。
バブリングは単語から想像できるとおり、水中の泡が上へ向かうかのように、イベントが親要素へと伝わっていく挙動のことを指します。上記のコードの例では、id contents
がクリックされると、その親要素であるid wrapper
までクリックされたことが伝わります。そのため、id contents
をクリックしたはずなのに、id wrapper
に登録したイベントが動いてしまったということです。
そこで、親要素へイベントが伝わる「バブリング」を防ぐ方法が用意されています。バブリングを防ぐには stopPropagation
メソッドを利用します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<html> <head> <meta charset="utf-8" /> <style> #wrapper{ width: 250px; height: 250px; background: #cccccc; } #contents{ width: 200px; height: 200px; background: #eeeeee; } </style> <script> window.onload = function(){ document.getElementById('wrapper').onclick = function(){ alert('外側の要素がクリックされました。'); } document.getElementById('contents').onclick = function(e){ e.stopPropagation(); } } </script> </head> <body> <div id="wrapper"> 外側の要素です。 <div id="contents"> 内側の要素です。 </div> </div> </body> </html> |
バブリングを止めるコードは21行目~23行目に追加されています。id contents
の HTML 要素がクリックされたら、イベントオブジェクト e の stopPropagation
メソッドを実行して親要素へイベントが伝わらないようにしています。
バブリングについての詳細は下記が参考になります。
http://wiki.bit-hive.com/tomizoo/pg/JavaScript%20addEventListener%28%29
[…] […]