質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

1回答

3660閲覧

イベントバブリングしない理由

aaaaaaaa

総合スコア501

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2016/12/20 11:22

編集2022/01/12 10:55

下記ソースは、pを監視しています。

html

1<div id="superParent"> 2<p id="parent"><span id="child">あいうえお(false/バブリング)</span></p> 3</div> 4 5<div id="superParent2"> 6<p id="parent2"><span id="child2">あいうえお2(true/キャプチャ)</span></p> 7</div> 8 9<script type="text/javascript"> 10var p = document.getElementById("parent"); 11var p2 = document.getElementById("parent2"); 12 13//イベントバブリング mouseenter、mouseleaveは、バブリングしないが、mouseover、mouseoutは、バブリングする。 14p.addEventListener("mouseover", function(e) { 15test(e) 16},false); 17//イベントキャプチャ 18p2.addEventListener("mouseenter", function(e) { 19test(e) 20},true); 21 22function test(e) { 23 var t=e.target 24 if(t.nodeName=="SPAN") { 25 console.log("イベントの流れの段階",e.eventPhase+"イベント発生元要素"+t+"★"+t.nodeName+":"+e.type); 26 } 27 if(t.nodeName=="P") { 28 console.log("イベントの流れの段階",e.eventPhase+"イベント発生元要素"+t+"★"+t.nodeName+":"+e.type); 29 } 30 if(t.nodeName=="DIV") { 31 console.log("イベントの流れの段階",e.eventPhase+"イベント発生元要素"+t+"★"+t.noneName+":"+e.type); 32 } 33} 34</script>

変数pは、イベントが発生するとバブリングするのですが、コンソール画面には、
spanがイベント発生元だった場合、
イベントの流れの段階 2イベント発生元要素[object HTMLParagraphElement]★P:mouseover
イベントの流れの段階 3イベント発生元要素[object HTMLSpanElement]★SPAN:mouseover

pがイベント発生元だった場合、
イベントの流れの段階 2イベント発生元要素[object HTMLParagraphElement]★P:mouseover
と表示されます。

ここで質問ですが、なぜid:parentの親要素であるdivは、コンソール画面に表示されないのでしょうか。

イベントの流れ(eventPhase)が3→2と来ているので、恐らく1は、divだと思うのですがなぜ、表示されないのでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

質問文を編集したコード

バブリングフェーズではきちんと親要素に伝播していますよ。

シンプルなサンプルコード

出来るだけシンプルなコードを組むことをお勧めします。

HTML

1<style> 2div, p { 3 border: solid 1px #99f; 4 background-color: #eef; 5 padding: 1em; 6 margin: 1em; 7} 8</style> 9</head> 10<body> 11<div id="superParent"> 12 superParent 13 <div id="parent">parent 14 <p id="child">child</p> 15 </div> 16</div> 17<script> 18'use strict'; 19function handleClick (event) { 20 console.log(event.eventPhase, event.type, event.target, event.currentTarget); 21} 22 23var elements = [document.getElementById('child'), document.getElementById('parent'), document.getElementById('superParent'), document.body, document]; 24 25for (var i = 0, l = elements.length; i < l; ++i) { 26 elements[i].addEventListener('click', handleClick, false); 27} 28</script>

以前、紹介した uhyohyo.net もシンプルなコードです。

Re: aaaaaaaa さん

投稿2016/12/20 12:10

編集2016/12/21 11:54
think49

総合スコア18156

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aaaaaaaa

2016/12/21 10:08

ご回答有難うございます。 それでは、なぜコンソール画面に、pとspanしか表示されないのでしょうか。
think49

2016/12/21 10:13

親要素で addEventListener を指定してないからです。 回答欄に書いたjsfiddleのリンク先で親要素でもイベントが発生しているのが確認できるはずです。
aaaaaaaa

2016/12/21 11:09

ご返答有難うございました。 つまり、変数pのdocument.getElementById("parent");を document.getElementById("superParent");に変更することでdivがコンソールで表示されるようになるということですね。superParentに変更しても質問文の通りにしかなりませんでしたが、 >>for (var i = 0, l = elements.length; i < l; ++i) { elements[i].addEventListener('mouseover', test, false); elements[i].addEventListener('mouseenter', test, true); } というソースを上記のページ内のコンソール画面で確認してみるとおっしゃる通りdivが表示されていました。for文に囲まないと表示されないということでしょうか。
think49

2016/12/21 11:56 編集

for文を使わなくても問題ないので、他のコードに問題があるのでしょう。 コードを半分削除してみたりして、問題点を洗い出す(切り分けする)作業をやってみてください。 また、出来るだけシンプルなコードを組むことを強く推奨します。親記事を追記しました。
aaaaaaaa

2016/12/22 09:12

ご返答有難うございました。 質問当時は、 イベントの流れの段階 2イベント発生元要素[object HTMLParagraphElement]★P:mouseover イベントの流れの段階 3イベント発生元要素[object HTMLSpanElement]★SPAN:mouseover となったのに対し、バブリングの方は、ソースを参考にconsole.logにe.currentTargetをいれたり、getElementを配列にしたところ、 イベントの流れの段階 2 イベント発生元要素 [object HTMLSpanElement] ★ SPAN : click イベントリスナーで登録している要素 [object HTMLSpanElement] イベントの流れの段階 2 イベント発生元要素 [object HTMLSpanElement] ★ SPAN : click イベントリスナーで登録している要素 [object HTMLSpanElement] イベントの流れの段階 3 イベント発生元要素 [object HTMLSpanElement] ★ SPAN : click イベントリスナーで登録している要素 [object HTMLDivElement] イベントの流れの段階 3 イベント発生元要素 [object HTMLSpanElement] ★ SPAN : click イベントリスナーで登録している要素 [object HTMLBodyElement] イベントの流れの段階 3 イベント発生元要素 [object HTMLSpanElement] ★ SPAN : click イベントリスナーで登録している要素 [object HTMLDocument] spanが5連続表示していますが、e.currentTarget部分をみると、[object HTMLSpanElement]、[object HTMLParagraphElement]、[object HTMLDivElement]、[object HTMLBodyElement]、[object HTMLDocument] となっていて恐らくspan、p、div、body、最上位ノードとバブリングしているのだと思います。 てっきり私は、t(event.target).nodeNameが「span、p、div、body、最上位ノード」と表示してくれるものと思っていましたが、これは違うのでしょうか。 イベントバブリングではなくキャプチャだと、spanがイベント発生元としたときt(event.target).nodeNameが親要素から順に「undifined(div?)、p、span」と表示してくれるので http://fast-uploader.com/file/7037952908695/ イベントバブリングもt(event.target).nodeNameが、e.currentTargetのようにふるまってくれるものだと思っておったのですが。
aaaaaaaa

2016/12/26 05:11

ご返答有難うございます。 英語が全くできないので、日本語でも利用できるjsdoitでソースを記述しました。 「バブリングの方は、ソースを参考にconsole.logにe.currentTargetをいれたり、getElementを配列にしたところ、」のソースは、下記です。 http://jsdo.it/rrrrrrrr/IlE6
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問