<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【每日一題NO.87】說(shuō)說(shuō)你對(duì)DOM事件流的理解

          共 3141字,需瀏覽 7分鐘

           ·

          2021-11-18 16:21

          事件

          JavaScriptHTML 之間的交互是通過(guò)事件實(shí)現(xiàn)的。
          事件就是通過(guò)文檔或?yàn)g覽器窗口發(fā)生的一些特定的交互瞬間。
          可以使用 監(jiān)聽(tīng)器 (或者事件處理程序) 來(lái)預(yù)定事件,以便來(lái)執(zhí)行相應(yīng)的代碼

          事件流

          描述的是頁(yè)面中事件傳播的順序
          當(dāng)事件發(fā)生的時(shí)候,會(huì)在元素節(jié)點(diǎn)之間按照特定的順序傳播,這個(gè)傳播的過(guò)程叫做 DOM 的事件流
          這個(gè)傳播過(guò)程是:事件捕獲 -- 事件目標(biāo) -- 事件冒泡
          而早期的 IE 和 NetScape 提出了完全相反的事件流概念,IE 是事件冒泡,而 NetScape 的事件流就是事件捕獲。

          事件冒泡、事件捕獲

          • IE 提出的事件流是事件冒泡,即從下到上,從目標(biāo)觸發(fā)的元素逐級(jí)往下向上傳播,直到 window 對(duì)象。
          • 而 NetScape 的事件流就是事件捕獲,即從 document 對(duì)象逐級(jí)向下傳播到目標(biāo)元素。由于 IE 低版本瀏覽器不支持,所以很少使用事件捕獲。
          • 后來(lái) ECMAScript 在 DOM2 中對(duì)事件流進(jìn)行了進(jìn)一步規(guī)范,基本上就是上述二者的結(jié)合,

          DOM2 中事件規(guī)定的事件流包括三個(gè)階段:

          1. 事件 捕獲 階段:事件從Document節(jié)點(diǎn)上 自上而下 向目標(biāo)節(jié)點(diǎn)傳播的階段
          2. 處于目標(biāo)階段:真正的目標(biāo)節(jié)點(diǎn)正在處理事件的階段
          3. 事件 冒泡 階段:事件從目標(biāo)節(jié)點(diǎn) 自下而上 向Document傳播的階段
          image

          DOM 事件處理

          DOM 節(jié)點(diǎn)增加了對(duì)事件處理,其分為四個(gè)級(jí)別

          DOM0

          DOM0 級(jí)事件具有極好的跨瀏覽器優(yōu)勢(shì),會(huì)以最大的速度綁定

          第一種方式是內(nèi)聯(lián)模型【行內(nèi)模式】

          <div?onclick="btnClick()">clickdiv>
          <script>
          ??function?btnClick(){
          ????console.log("hello");
          ??}
          script>

          缺點(diǎn)是:不符合 W3C 中關(guān)于內(nèi)容與行為分離的基本規(guī)范

          第二種方式是腳本模式

          <div?id="btn">點(diǎn)擊div>
          <script>
          ??var?btn=document.getElementById("btn");
          ??btn.onclick=function(){
          ????console.log("sunny");
          ??}
          script>

          但是會(huì)存在問(wèn)題

          <div?id="btn">點(diǎn)擊div>
          <script>
          ??var?btn=document.getElementById("btn");
          ??btn.onclick=function(){
          ????console.log("sunny");
          ??}
          ??btn.onclick=function(){
          ????console.log("sunny-sunny");
          ??}
          script>

          這個(gè)時(shí)候只能輸出 sunny-sunny。很明顯的是:

          第一個(gè)事件函數(shù)被第二個(gè)事件函數(shù)給覆蓋掉了,所以腳本模型的缺點(diǎn)就是:同一個(gè)節(jié)點(diǎn)只能添加一次同類型事件

          <div?id="btn3">
          ????btn3
          ????<div?id="btn2">
          ????????btn2
          ????????<div?id="btn1">
          ????????????btn1
          ????????div>
          ????div>
          div>
          <script>
          ????let?btn1?=?document.getElementById("btn1");
          ????let?btn2?=?document.getElementById("btn2");
          ????let?btn3?=?document.getElementById("btn3");
          ????btn1.onclick=function(){
          ????????console.log(1)
          ????}
          ????btn2.onclick=function(){
          ????????console.log(2)
          ????}
          ????btn3.onclick=function(){
          ????????console.log(3)
          ????}
          script>

          當(dāng)點(diǎn)擊 btn1 的時(shí)候,會(huì)依次輸入 1,2,3,這就是事件冒泡,DOM0 級(jí)只支持冒泡階段

          DOM2

          DOM2定義了兩個(gè)方法:

          1. addEventListener 添加事件偵聽(tīng)器
          2. removeEventListener 刪除事件偵聽(tīng)器

          這兩個(gè)方法均有三個(gè)參數(shù):

          • 第一個(gè)參數(shù)是要處理的時(shí)間名稱
          • 第二個(gè)參數(shù)是作為事件處理程序的函數(shù)名稱
          • 第三個(gè)參數(shù)是一個(gè)布爾值,默認(rèn)false表示使用冒泡機(jī)制,true表示捕獲機(jī)制
          <div?id="btn">點(diǎn)擊div>

          <script>
          var?btn=document.getElementById("btn");
          btn.addEventListener("click",hello,false);
          btn.addEventListener("click",helloagain,false);
          function?hello(){
          ????console.log("hello");
          }
          function?helloagain(){
          ????console.log("hello?again");
          }
          script>

          捕獲冒泡的順序

          <div?id="btn3">
          ????????btn3
          ????????<div?id="btn2">
          ????????????btn2
          ????????????<div?id="btn1">
          ????????????????btn1
          ????????????div>
          ????????div>
          ????div>
          ????<script>
          ????????let?btn1?=?document.getElementById("btn1");
          ????????let?btn2?=?document.getElementById("btn2");
          ????????let?btn3?=?document.getElementById("btn3");
          ????????btn1.addEventListener('click',?function?()?{
          ????????????console.log('btn1捕獲')
          ????????},?true)
          ????????btn1.addEventListener('click',?function?()?{
          ????????????console.log('btn1冒泡')
          ????????},?false)

          ????????btn2.addEventListener('click',?function?()?{
          ????????????console.log('btn2捕獲')
          ????????},?true)
          ????????btn2.addEventListener('click',?function?()?{
          ????????????console.log('btn2冒泡')
          ????????},?false)

          ????????btn3.addEventListener('click',?function?()?{
          ????????????console.log('btn3捕獲')
          ????????},?true)
          ????????btn3.addEventListener('click',?function?()?{
          ????????????console.log('btn3冒泡')
          ????????},?false)
          ????
          script>

          點(diǎn)擊btn1,其結(jié)果為:btn3捕獲 btn2捕獲 btn1捕獲 btn1冒泡 btn2冒泡 btn3冒泡

          阻止冒泡

          btn2.addEventListener(
          ??"click",
          ??function?(ev)?{
          ????ev.stopPropagation();
          ????console.log("btn2捕獲");
          ??},
          ??true
          );


          所有《每日一題》的 知識(shí)大綱索引腦圖 整理在此:https://www.yuque.com/dfe_evernote/interview/everyday
          你也可以點(diǎn)擊文末的 “閱讀原文” 快速跳轉(zhuǎn)


          用一個(gè)十年拉扯自己長(zhǎng)大,
          那時(shí)未來(lái)已達(dá),星辰開(kāi)花。


          瀏覽 36
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国内精品毛片 | 成人AV天天干 | 国产精品 A片在线 | 精品夜夜澡人妻无码AV | 色婷婷国产精品高潮呻吟AV久久 |