第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

全部開發(fā)者教程

JavaScript 入門教程

DOM 事件流

DOM 事件流描述了 DOM 時(shí)間響應(yīng)的階段、路徑。

DOM 事件流也會(huì)被稱為 DOM 事件模型。

圖片描述

1. 事件流階段

事件流有三個(gè)階段:

  1. 捕獲階段 從window開始,尋找觸發(fā)事件最深層的節(jié)點(diǎn),過程中如果有節(jié)點(diǎn)綁定了對(duì)應(yīng)事件,則觸發(fā)事件
  2. 目標(biāo)階段 找到事件觸及的最深節(jié)點(diǎn)
  3. 冒泡階段 從最深節(jié)點(diǎn)按照捕獲的路徑進(jìn)行返回,過程中如果有節(jié)點(diǎn)綁定了對(duì)應(yīng)事件,則觸發(fā)事件

現(xiàn)代瀏覽器默認(rèn)都會(huì)在冒泡階段觸發(fā)事件。

通過一個(gè)例子來簡單的感受一下。

實(shí)例演示
預(yù)覽 復(fù)制
復(fù)制成功!
<style>
  .box {
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .size-100 {
    width: 100px;
    height: 100px;
    background: #4caf50;
  }

  .size-200 {
    width: 200px;
    height: 200px;
    background: chocolate;
  }

  .size-300 {
    width: 300px;
    height: 300px;
    background: wheat;
  }
</style>

<div class="box size-300">
  <div class="box size-200">
    <div class="box size-100">
    </div>
  </div>
</div>

<div class="result"></div>

<script>
  var boxes = document.querySelectorAll('.box');
  var result = document.querySelector('.result');

  boxes.forEach(function(box) {
    box.addEventListener('click', function() {
      var el = document.createElement('p');

      el.innerText = '現(xiàn)在觸發(fā)點(diǎn)擊事件的是' + this.className;

      result.appendChild(el);
    });
  });
</script>
運(yùn)行案例 點(diǎn)擊 "運(yùn)行案例" 可查看在線運(yùn)行效果

圖片描述

點(diǎn)擊后,觀察輸出可以發(fā)現(xiàn),事件是點(diǎn)擊到的最深層次的節(jié)點(diǎn)開始向上執(zhí)行的。

即從 size-100size-200size-300,這就是冒泡的過程。

如果想讓事件在捕獲階段就執(zhí)行,可以傳遞 addEventListener 方法第三個(gè)參數(shù)。

2. addEventListener 的第三個(gè)參數(shù)

addEventListener 的第三個(gè)參數(shù)用來決定事件在冒泡階段觸發(fā)還是在捕獲階段觸發(fā),其為一個(gè)布爾值,傳遞 false 則事件會(huì)在冒泡階段觸發(fā),傳遞 true 則會(huì)在捕獲階段觸發(fā)。

實(shí)例演示
預(yù)覽 復(fù)制
復(fù)制成功!
<style>
  .box {
    display: flex;
    justify-content: center;
    align-items: center;
  }

  .ele1 {
    background: wheat;
    width: 200px;
    height: 200px;
  }

  .ele2 {
    background: yellowgreen;
    width: 100px;
    height: 100px;
  }
</style>

<div class="box ele1">
  <div class="box ele2"></div>
</div>

<div class="result"></div>

<script>
var ele1 = document.querySelector('.ele1');
var ele2 = document.querySelector('.ele2');
var result = document.querySelector('.result');

function getElement(content) {
  var el = document.createElement('p');

  el.innerText = content;

  return el;
}

ele1.addEventListener('click', function() {
  result.appendChild(getElement('我是元素ele1'));
});

ele2.addEventListener('click', function() {
  result.appendChild(getElement('我是元素ele2'));
});
</script>
運(yùn)行案例 點(diǎn)擊 "運(yùn)行案例" 可查看在線運(yùn)行效果

圖片描述

根據(jù)默認(rèn)瀏覽器事件是在冒泡階段觸發(fā)的規(guī)則,上述例子會(huì)先觸發(fā)子節(jié)點(diǎn) .ele2 的事件,再觸發(fā) .ele1 的事件。

如果想讓 .ele1 在捕獲階段就觸發(fā)事件,則在綁定事件的時(shí)候傳遞第三個(gè)參數(shù)為 true 即可。

實(shí)例演示
預(yù)覽 復(fù)制
復(fù)制成功!
<style>
  .box {
    display: flex;
    justify-content: center;
    align-items: center;
  }

  .ele1 {
    background: wheat;
    width: 200px;
    height: 200px;
  }

  .ele2 {
    background: yellowgreen;
    width: 100px;
    height: 100px;
  }
</style>

<div class="box ele1">
  <div class="box ele2"></div>
</div>

<div class="result"></div>

<script>
var ele1 = document.querySelector('.ele1');
var ele2 = document.querySelector('.ele2');
var result = document.querySelector('.result');

function getElement(content) {
  var el = document.createElement('p');

  el.innerText = content;

  return el;
}

ele1.addEventListener('click', function() {
  result.appendChild(getElement('我是元素ele1'));
}, true);

ele2.addEventListener('click', function() {
  result.appendChild(getElement('我是元素ele2'));
});
</script>
運(yùn)行案例 點(diǎn)擊 "運(yùn)行案例" 可查看在線運(yùn)行效果

圖片描述

這樣 .ele1 的事件就會(huì)在捕獲階段觸發(fā)。

3. 不符合W3C標(biāo)準(zhǔn)的事件流

早期的 IE 和 Netscape Navigator 是不符合標(biāo)準(zhǔn)的。

前者是使用事件冒泡流,后者使用事件捕獲流。

前面的章節(jié)有提到過 0級(jí)DOM事件 ,其提供的綁定事件的方式是不能指定事件觸發(fā)的階段的,其原因是在那個(gè)階段下,還沒有現(xiàn)在制定的 DOM 事件流。

當(dāng)時(shí)并沒有統(tǒng)一的標(biāo)準(zhǔn),0級(jí)DOM事件也并不是一套官方出臺(tái)的標(biāo)準(zhǔn),所有相關(guān)內(nèi)功全部由瀏覽器廠商決定。

后來 W3C 很好的整合了這兩種模型,便有了現(xiàn)在的 DOM 事件流。

4. 冒泡的終點(diǎn)元素

這個(gè)問題其實(shí)經(jīng)常會(huì)在面試中被問到,通常題目會(huì)是這樣的:

請(qǐng)描述一下事件捕獲和冒泡的具體流程

其實(shí)問的是事件從那個(gè)節(jié)點(diǎn)開始捕獲,然后到目標(biāo)節(jié)點(diǎn),最后又在哪個(gè)節(jié)點(diǎn)冒泡結(jié)束。

大部分面試者會(huì)回答 document,其實(shí)根據(jù)事件對(duì)象的 path 屬性就可以得到答案。

圖片描述

path 屬性會(huì)返回事件冒泡的路徑,其最后是到 window 對(duì)象才停止的。

其實(shí)這點(diǎn)在標(biāo)準(zhǔn)中也有描述。

注意:path 屬性有兼容性問題,可以通過 can i use 確定。可以用標(biāo)準(zhǔn)中的 composedPath 代替。

5. 小結(jié)

開發(fā)過程中很少會(huì)取改變事件觸發(fā)的階段。但是事件流的概念依然重要,因?yàn)楹芏鄷r(shí)候要阻止事件冒泡。

理解了事件流,可以理解事件委托的原理,事件委托相關(guān)的內(nèi)容可以參閱事件相關(guān)的性能優(yōu)化。