親要素のイベントが子イベントの前に発生するように見える私のコードでは、奇妙なバグを乗り越えていました。つまり、e.stopPropagation()
は何の効果もありませんでした。子要素の前に親要素のイベントが子孫セレクタにバインドされていると、なぜそれが発生するのですか?
デモ:
$(document).ready(function() {
// Binding directly to the elements
$(".red1").on("click", function(e) {
alert("Clicked red1");
});
$(".green1").on("click", function(e) {
alert("Clicked green1");
e.stopPropagation();
});
// Binding the child from a descendant selector
$(".red2").on("click", function(e) {
alert("Clicked red2");
});
$("body").on("click", ".green2", function(e) {
alert("Clicked green2");
e.stopPropagation();
});
});
.red1,
.red2 {
display: inline-block;
width: 200px;
height: 200px;
background-color: #800;
}
.green1,
.green2 {
display: inline-block;
width: 100px;
height: 100px;
background-color: #080;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="red1">
<div class="green1"></div>
</div>
<div class="red2">
<div class="green2"></div>
</div>
- 左側にある緑色の四角形をクリックすると、期待どおりに動作し、1つのアラートが表示されます。
- 右側の緑色の四角形をクリックすると、親イベントが発生し、その後に子イベントが発生します。
私は、これは私の部分でバインディングがどのように機能するのか誤解していると仮定していますが、なぜこのような順序で発生しているのかを頭に浮かべることはできません。
これはなぜ起こっているのですか?
あなたが委任されたイベントハンドラを使用しているからです。これは、イベントが発生するためには '.red2'をバブルしなければならないことを意味します(したがって、 'parent'イベントハンドラが起動します)、発信者が' .green2'であるかどうかを確認し、委任されたイベントハンドラ実行される。この動作を避けるには、委譲されたイベントハンドラを使用しないでください。親の '.red'要素にすべてのイベントを配置し、発信者を自分で確認してください。 –
@RoryMcCrossanああ、子孫セレクタを使用したバインディングは親要素に効果的にバインドされ、その後、起動されるたびにイベントの発生元を確認します。 – DBS
Roryが言ったことに基づいて展開を並べ替えるには、緑色のdivが '.red2'の内部にあるため、' .red2'が最初に起動されていますが、 '.green2'はクリックイベントが '
'要素までバブルすると、「起動」されます。その伝播には少し時間がかかります(違いはありませんが、違いを見るには十分です)。 – Jhecht