Olay köpürme ve yakalama arasındaki fark nedir? Ne zaman kabarcıklanma ve yakalama kullanılmalıdır?
Olay köpürme ve yakalama arasındaki fark nedir? Ne zaman kabarcıklanma ve yakalama kullanılmalıdır?
Yanıtlar:
Olay köpürme ve yakalama, başka bir öğenin içindeki bir öğede bir olay meydana geldiğinde ve her iki öğe de o olay için bir tanıtıcı kaydettiğinde, HTML DOM API'sında olay yaymanın iki yoludur. Olay yayma modu , öğelerin olayı hangi sırayla alacağını belirler .
Köpürme ile, olay önce en içteki eleman tarafından yakalanır ve ele alınır ve daha sonra dış elemanlara yayılır.
Yakalama ile, olay ilk olarak en dıştaki eleman tarafından yakalanır ve iç elemanlara yayılır.
Yakalama, yayılma sırasını hatırlamaya yardımcı olan "damlama" olarak da adlandırılır:
damlatmak, havaya uçurmak
Eski günlerde, Netscape olay yakalamayı savunurken, Microsoft olay kabarcıklanmasını teşvik etti. Her ikisi de W3C Belge Nesne Modeli Olayları standardının (2000) bir parçasıdır .
IE <9 yalnızca olay köpürme kullanır , IE9 + ve tüm büyük tarayıcılar her ikisini de destekler. Öte yandan, olay köpürme performansı karmaşık DOM'lar için biraz daha düşük olabilir .
addEventListener(type, listener, useCapture)
Olay işleyicilerini köpürme (varsayılan) veya yakalama modunda kaydetmek için kullanabiliriz . Yakalama modelini kullanmak için üçüncü argümanı olarak iletin true
.
<div>
<ul>
<li></li>
</ul>
</div>
Yukarıdaki yapıda, li
öğede bir tıklama etkinliğinin oluştuğunu varsayın .
Yakalama modelinde, olay div
ilk (önce tetiklenecek olan tıklama işleyicileri div
), daha ul
sonra hedef öğede, son olarak, tarafından işlenecektir li
.
Köpürme modelinde bunun tersi gerçekleşir: olay ilk önce li
, sonra ul
, ve sonunda div
eleman tarafından ele alınacaktır .
Daha fazla bilgi için, bkz
Aşağıdaki örnekte, vurgulanan öğelerin herhangi birine tıklarsanız, olay yayılma akışının yakalama aşamasının önce köpürme aşamasının gerçekleştiğini görebilirsiniz.
var logElement = document.getElementById('log');
function log(msg) {
logElement.innerHTML += ('<p>' + msg + '</p>');
}
function capture() {
log('capture: ' + this.firstChild.nodeValue.trim());
}
function bubble() {
log('bubble: ' + this.firstChild.nodeValue.trim());
}
function clearOutput() {
logElement.innerHTML = "";
}
var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++) {
divs[i].addEventListener('click', capture, true);
divs[i].addEventListener('click', bubble, false);
}
var clearButton = document.getElementById('clear');
clearButton.addEventListener('click', clearOutput);
p {
line-height: 0;
}
div {
display:inline-block;
padding: 5px;
background: #fff;
border: 1px solid #aaa;
cursor: pointer;
}
div:hover {
border: 1px solid #faa;
background: #fdd;
}
<div>1
<div>2
<div>3
<div>4
<div>5</div>
</div>
</div>
</div>
</div>
<button id="clear">clear output</button>
<section id="log"></section>
useCapture
artık IE'de destekleniyor> = 9. kaynak
triclkling
aynı mı capturing
? Hakkında Crockford görüşmeler Trickling v. Bubbling
bu videonun konuşma - youtube.com/watch?v=Fv9qT9joc0M&list=PL7664379246A246CB etrafında 1 hr 5 minutes
.
trickle down
=> onElement
=>bubble up
Açıklama:
quirksmode.org bunun güzel bir açıklamasına sahiptir. Özetle (quirksmode'dan kopyalandı):
Etkinlik yakalama
Etkinlik yakalamayı kullandığınızda
| | ---------------| |----------------- | element1 | | | | -----------| |----------- | | |element2 \ / | | | ------------------------- | | Event CAPTURING | -----------------------------------
ilk olarak element1 olay işleyicisi tetiklenir, son olarak element2 olay işleyicisi tetiklenir.
Olay köpürme
Olay köpürme kullandığınızda
/ \ ---------------| |----------------- | element1 | | | | -----------| |----------- | | |element2 | | | | | ------------------------- | | Event BUBBLING | -----------------------------------
ilk olarak element2 olay işleyicisi tetiklenir, son olarak element1 olay işleyicisi tetiklenir.
Ne kullanılır?
Bu ne yapmak istediğinize bağlıdır. Daha iyisi yok. Fark, olay işleyicilerin yürütme sırasıdır. Çoğu zaman olay işleyicilerini köpürme aşamasında ateşlemek iyi olacaktır, ancak daha önce ateşlemek de gerekebilir.
Eğer eleman 1 ve eleman 2'de iki eleman varsa, eleman 2 eleman 1'in içindedir ve her iki elemanın da onClick diyelim bir olay işleyicisi ekleriz. Şimdi eleman 2'ye tıkladığımızda her iki eleman için eventHandler çalıştırılacaktır. Şimdi soru, olayın hangi sırada yürütüleceği sorusudur. Eleman 1 ile iliştirilen olay ilk önce yürütülürse, olaya olay yakalama denir ve 2 nolu eleman ile iliştirilen olay ilk olarak yürütülürse buna olay köpürme denir. W3C'ye göre olay, hedefe ulaşana kadar yakalama aşamasında başlayacak ve daha sonra köpürmeye başlayacaktır.
Yakalama ve köpürme durumları, addEventListener yönteminin useCapture parametresi tarafından bilinir.
eventTarget.addEventListener (tip, dinleyici, [useCapture]);
Varsayılan olarak useCapture yanlıştır. Bu köpürme aşamasında olduğu anlamına gelir.
var div1 = document.querySelector("#div1");
var div2 = document.querySelector("#div2");
div1.addEventListener("click", function (event) {
alert("you clicked on div 1");
}, true);
div2.addEventListener("click", function (event) {
alert("you clicked on div 2");
}, false);
#div1{
background-color:red;
padding: 24px;
}
#div2{
background-color:green;
}
<div id="div1">
div 1
<div id="div2">
div 2
</div>
</div>
Lütfen doğru ve yanlış değiştirmeyi deneyin.
the event will start in the capturing phase untill it reaches the target comes back to the element and then it starts bubbling
. Ben sadece addEventListeneruseCapture
true veya false olarak ayarlanabilen bir parametreye sahip bulundu ; ve HTML 4.0'da, olay dinleyicileri bir öğesinin özelliklerine olarak belirtilmiş ve useCapture defaults to false
. Ne yazdığınızı doğrulayan bir spesifikasyona bağlanabilir misiniz?
Bu konuyu açıklarken çok net olması için javascript.info bu öğretici buldum . Ve sonunda 3 puanlık özeti gerçekten önemli noktalardan bahsediyor. Burada alıntı yapıyorum:
- Olaylar önce en derin hedefe kadar yakalanır, sonra kabarır. IE <9 da sadece kabarcıklar.
- Tüm işleyiciler , olayı yakalama sahnesinde yakalamanın tek yolu olan
addEventListener
son argümanla köpüren sahne istisnaları üzerinde çalışırtrue
.- Köpürme / yakalama
event.cancelBubble=true
(IE) veyaevent.stopPropagation()
diğer tarayıcılar tarafından durdurulabilir .
Ayrıca Event.eventPhase
, etkinliğin hedefte olup olmadığını veya başka bir yerden gelip gelmediğini size söyleyebilecek bir özellik de vardır .
Tarayıcı uyumluluğunun henüz belirlenmediğini unutmayın. Chrome (66.0.3359.181) ve Firefox (59.0.3) üzerinde test ettim ve orada destekleniyor.
Kabul edilen yanıttan zaten büyük snippet'e genişleyen , bu eventPhase
özelliği kullanan çıktıdır
var logElement = document.getElementById('log');
function log(msg) {
if (logElement.innerHTML == "<p>No logs</p>")
logElement.innerHTML = "";
logElement.innerHTML += ('<p>' + msg + '</p>');
}
function humanizeEvent(eventPhase){
switch(eventPhase){
case 1: //Event.CAPTURING_PHASE
return "Event is being propagated through the target's ancestor objects";
case 2: //Event.AT_TARGET
return "The event has arrived at the event's target";
case 3: //Event.BUBBLING_PHASE
return "The event is propagating back up through the target's ancestors in reverse order";
}
}
function capture(e) {
log('capture: ' + this.firstChild.nodeValue.trim() + "; " +
humanizeEvent(e.eventPhase));
}
function bubble(e) {
log('bubble: ' + this.firstChild.nodeValue.trim() + "; " +
humanizeEvent(e.eventPhase));
}
var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++) {
divs[i].addEventListener('click', capture, true);
divs[i].addEventListener('click', bubble, false);
}
p {
line-height: 0;
}
div {
display:inline-block;
padding: 5px;
background: #fff;
border: 1px solid #aaa;
cursor: pointer;
}
div:hover {
border: 1px solid #faa;
background: #fdd;
}
<div>1
<div>2
<div>3
<div>4
<div>5</div>
</div>
</div>
</div>
</div>
<button onclick="document.getElementById('log').innerHTML = '<p>No logs</p>';">Clear logs</button>
<section id="log"></section>