簡單的DOM的相關總結

語言: CN / TW / HK

DOM 全稱是Document object model,翻譯為,文檔對象模型,是 HTML 和 XML 文檔的編程接口。
把 HTML 中各個標籤定義出的元素以對象的形式包裝起來,然後可通過 JS 對標籤進行增刪改查。
DOM 結構以樹的形態存在,最小單位是節點。

DOM的節點類型

節點類型主要有:

  • Document:指這份文件,也就是這份 HTML 檔的開端。當瀏覽器載入 HTML 文檔, 它就會成為 Document 對 象。
  • Element:指 HTML 文件內的各個標籤,像是<div>、<span> 這樣的各種 HTML 標籤定義的元素
  • Text:指被各個標籤包起來的文字,像是<div>就是這段文字</div>
  • Attribute:指元素的特性,就是各個標籤上的屬性
  • Comment:指文檔註釋<!-- 註釋 -->

DOM 的增刪改查

  • 增:document.createElement('span')、parent.appendChild(x)
  • 刪:y.parent.removeChild(y)
  • 改:x.someAttr = '...'、y.parent.insertBefore(appendElement,ele)
  • 查 querySelector、querySelectorAll、getElementById/ClassName/TagName

DOM 事件體系

先説下專有名詞:

  • 事件:在瀏覽器裏的動作,可以是用户觸發的,也可以是瀏覽器觸發的。如click mouseover
  • 事件監聽函數:也叫事件處理程序,是事件發生後,瀏覽器如何響應,其實就是用來應答事件的函數,。
  • 事件流(事件的流向):事件在頁面中傳播的順序

體系主要從四方面理解:

  • DOM 事件流,分 3 個階段:事件捕獲階段、目標階段、冒泡階段(V字形)
  • 事件對象:當事件 DOM 元素中穿梭時,會觸發當前元素上綁定的相應事件處理函數,此時會產生一個事件對象 event 作為處理函數的入參。其囊括了與事件有關的信息,比如由觸發事件的元素、事件的類型等
  • 自定義事件
  • 事件代理

事件對象

e.currentTarget 和 e.target 事件對象兩個屬性很容易混淆,簡單説下聯繫和區別:

  • 本質上e.currentTarget是綁定事件的當前元素,e.target是觸發事件的元素。
  • 因為有捕獲和冒泡階段,所以這兩可能不一樣
  • 假設有個div,裏面有一個 span 標籤和 b 標籤,給 div 綁定點擊事件的時候,e.currentTarget始終是 div,但是如果點擊的是span標籤,e.target就是span
  • 重點!!!如果點擊這兩標籤之外的但又是 div 內部的區域,e.target就是div,此時和e.currentTarget是一致的

常用的兩個方法:

  • event.stopPropagation(),讓事件不再冒泡,將事件的影響面控制在目標元素這個範圍內
  • event.preventDefault(),阻止瀏覽器的默認動作,比如點擊 a 標籤會跳轉

自定義事件

除了瀏覽器的默認事件click之類,開發者可以自己創建新事件。

比如現在有三個同級元素a b c,點擊 a 之後,想要 b 和 c 也知道 a 被點擊。

那麼可以創建一個clickA事件,然後讓 b 和 c 綁定這個事件,點擊 a 之後就讓 b 和 c 觸發這個事件

看個例子:

<div>
  <div id="a">a</div>
  <div id="b">b</div>
  <div id="c">c</div>
</div>
<script>
  // 新建一個自定義事件
  var clickA = new Event("clickA");
  document.querySelector("#a").addEventListener("click", function() {
    // a點擊之後,就是clickA事件觸發的時候,但瀏覽器不認識它,所以感知和派發,可以自己來實現:
    document.querySelector("#b").dispatchEvent(clickA);
    document.querySelector("#c").dispatchEvent(clickA);
  });
  document.querySelector("#b").addEventListener("clickA", () => {
    console.log("b");
  });
  document.querySelector("#b").addEventListener("clickA", () => {
    console.log("c");
  });
</script>
複製代碼

事件代理

事件在冒泡階段的時候,會將事件一層層傳播,直到整個文檔。而從事件對象的target屬性,可以知道傳播到哪裏了。

於是,利用事件的冒泡特性,可以將多個子元素的同一類型的監聽邏輯,合併到父元素上通過一個監聽函數來管理的行 為,就是事件代理。

通過事件代理,我們可以減少內存開銷、簡化註冊步驟,大大提高開發效率。

<ul>
  <li>1</li>
  <li>2</li>
</ul>
<script>
  var ul = document.querySelector("ul");
  ul.addEventListener("click", function(e) {
    // 這裏點擊不同的li就會輸出相應的內容,e.target就是正在點擊的元素
    console.log(e.target.innerHTML);
  });
</script>
複製代碼