DOM 代表文檔物件模型,它是 HTML 文檔的節點和物件表示法。瀏覽器提供了一個 API,你可以使用它來與 DOM 進行交互。這就是現代 JavaScript 框架的工作方式 - 它們使用 DOM API 告訴瀏覽器在頁面上顯示什麼。

DOM 是瀏覽器對網頁的內部表示。當瀏覽器從服務器獲取 HTML 時,解析器會分析代碼的結構並創建其模型。基於這個模型,瀏覽器在屏幕上呈現頁面。

瀏覽器提供了一個 API,你可以使用它來與 DOM 進行交互。這就是現代 JavaScript 框架的工作方式 - 它們使用 DOM API 告訴瀏覽器在頁面上顯示什麼。

在單頁應用中,DOM 不斷變化以反映屏幕上的內容,作為開發人員,你可以使用瀏覽器開發者工具來檢查它。

DOM 是無語言限制的,並且訪問 DOM 的事實上的標準方式是使用JavaScript,因為它是瀏覽器唯一能運行的語言。

DOM 由 WHATWG 在 DOM 鏈接規範中進行了標準化。

使用 JavaScript,你可以與 DOM 進行交互的操作包括:

  • 檢查頁面結構
  • 訪問頁面的元數據和標題
  • 編輯 CSS 样式
  • 附加或刪除事件監聽器
  • 編輯頁面中的任何節點
  • 更改任何節點的屬性

.. 還有更多。

DOM API 提供的兩個主要物件是 documentwindow

窗口物件

window 物件表示包含 DOM 文檔的窗口。

window.document 指向窗口中加載的 document 物件。

這個物件的屬性和方法可以直接調用,因為它表示全局物件。因此,前面的 window.document 屬性通常被稱為 document

屬性

以下是你可能需要經常使用的一些有用屬性的列表:

  • console 指向瀏覽器的調試控制台。可使用 console.logconsole.error 和其他工具(參見瀏覽器開發者工具文章)打印錯誤消息或日誌。
  • document 如前所述,指向 document 物件,是你將執行的 DOM 操作的關鍵。
  • history 可以訪問 History API
  • location 可以訪問 Location interface,從中你可以獲取 URL、協議、哈希和其他有用的信息。
  • localStorage 是對 Web Storage API 的 localStorage 物件的引用。
  • sessionStorage 是對 Web Storage API sessionStorage 物件的引用。

方法

window 物件還提供了一些有用的方法:

  • alert():用於顯示警告對話框
  • postMessage():被 Channel Messaging API 使用
  • requestAnimationFrame():以高效且對 CPU 友好的方式執行動畫
  • setInterval():每隔 n 毫秒調用一次函數,直到通過 clearInterval() 清除間隔
  • clearInterval():清除通過 setInterval() 創建的間隔
  • setTimeout():在 ’n’ 毫秒後執行一個函數
  • setImmediate():在瀏覽器準備就緒時立即執行一個函數
  • addEventListener(): 向文檔中添加事件監聽器
  • removeEventListener(): 從文檔中刪除事件監聽器

https://developer.mozilla.org/en-US/docs/Web/API/Window 查看完整的 window 物件的所有屬性和方法參考。

文檔物件

document 物件代表加載在窗口中的 DOM 樹。

以下是指向 head 和 body 標簽的 DOM 的部分表示:

DOM, body 和 head 標簽

以下是顯示了包含標題的 head 標簽的 DOM 的部分表示:

DOM, 帶有標題的 head 標簽

以下是顯示了包含了一個連結的 body 標簽的 DOM 的部分表示,以及該連結的值和帶有其值的 href 屬性:

DOM, 帶有連結的 body 標簽

可以通過 window.document 獲取 Document 物件,由於 window 是全局物件,所以你可以直接在瀏覽器控制台或 JavaScript 代碼中使用 document 快捷方式直接訪問 document 物件。

該 Document 物件有很多屬性和方法。你最常使用的是選擇器 API的方法:

  • document.getElementById()
  • document.querySelector()
  • document.querySelectorAll()
  • document.getElementsByTagName()
  • document.getElementsByClassName()

可以使用 document.title 獲取文檔標題,使用 document.URL 獲取 URL。引用者可以在 document.referrer 中獲取到,域名在 document.domain 中。

document 物件中可以獲取 Element 節點 的 body 和 head:

  • document.documentElement:Document 節點
  • document.body:body Element 節點
  • document.head:head Element 節點

可以通過 document.links 獲取特定類型的所有元素節點的列表,比如所有鏈接的 HTMLCollection,所有圖片使用 document.images,所有表單使用 document.forms

文檔cookiesdocument.cookie 中可訪問。最後修改的日期在 document.lastModified 中。

你還可以做更多的事情,甚至可以使用 document.write(),這是一個在 JavaScript 的早期日子中用於與頁面交互的方法。

https://developer.mozilla.org/en-US/docs/Web/API/Document 查看完整的 document 物件的所有屬性和方法參考。

節點類型

DOM 有不同類型的節點,其中一些你在上面的示例圖像中已經見過了。你將遇到的主要節點類型有:

  • Document:文檔節點,樹的起點
  • Element:HTML 標簽
  • Attr:標簽的屬性
  • Text:元素或 Attr 節點的文本內容
  • Comment:HTML 註釋
  • DocumentType文檔類型聲明

遍歷 DOM

DOM 是具有元素樹結構的樹,文檔節點是樹的根,指向 html Element 節點,該 Element 節點又指向其子元素節點 headbody,依此類推。

從這些元素中,你可以導航 DOM 結構並移動到不同的節點。

獲取父節點

每個元素都有一個父節點。

要獲取它,可以使用 Node.parentNodeNode.parentElement(其中 Node 表示 DOM 中的一個節點)。

除了在 html 元素上運行時,它們基本上是相同的:parentNode 返回 DOM 樹中指定節點的父節點,而 parentElement 返回節點的 parent Element,如果節點沒有父節點或其父節點不是 DOM 元素,則返回 null。

通常人們使用 parentNode

獲取子節點

要檢查節點是否有子節點,使用 Node.hasChildNodes(),它返回一個布爾值。

要訪問節點的所有子元素節點,使用 Node.childNodes

DOM 還提供了 Node.children 方法。但是,它不僅包括 Element 節點,還包括元素之間的空白空間是文本節點。這通常不是你想要的。

要獲取第一個子元素節點,使用 Node.firstElementChild。要獲取最後一個子元素節點,使用 Node.lastElementChild

DOM 也公開了 Node.firstChildNode.lastChild,它們的不同之處在於它們不僅僅“過濾”元素節點的樹。它們還顯示表示空白空間的空白文本節點。

簡而言之,要遍歷子元素節點,使用:

  • Node.childNodes
  • Node.firstElementChild
  • Node.lastElementChild

獲取兄弟節點

除了獲取父節點和子節點之外,由於 DOM 是一個樹,你還可以獲取任何元素節點的兄弟節點。

你可以使用:

  • Node.previousElementSibling
  • Node.nextElementSibling

DOM 也公開了previousSiblingnextSibling,但正如上面描述的它們的對應物一樣,它們包括空白空間作為文本節點,因此通常應避免使用它們。

編輯 DOM

DOM 提供了各種方法來編輯頁面的節點並修改文檔樹。

使用

  • document.createElement():創建一個新的 Element 節點
  • document.createTextNode():創建一個新的 Text 節點

你可以創建新的元素,並將它們添加到 DOM 中作為所需的子元素,使用 document.appendChild()

const div = document.createElement('div')
div.appendChild(document.createTextNode('Hello world!'))
  • first.removeChild(second):從節點 “first” 中刪除子節點 “second”。
  • document.insertBefore(newNode, existingNode):在 DOM 樹結構中的 “existingNode” 之前插入新的兄弟節點 “newNode”。
  • element.appendChild(newChild):修改 “element” 下的樹,在所有其他子節點之後添加新的子節點 “newChild”。
  • element.prepend(newChild):修改“element”下的樹,在其他子元素之前添加新的子節點“newChild”。可以傳遞一個或多個子節點,甚至可以傳遞一個字符串,該字符串將解釋為 Text 節點。
  • element.replaceChild(newChild, existingChild):修改“element”下的樹,在其中用新的節點“newChild”替換“existingChild”。
  • element.insertAdjacentElement(position, newElement):按照“position”參數的值,將“newElement”插入到 DOM 中的“element”位置相對應的位置。查看所有可能的值
  • element.textContent = 'something':將 Text 節點的內容更改為“something”。

標籤: DOM, Document Object Model, JavaScript, 瀏覽器, API, HTML