日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

html dom 高级,DOM 高级工程师不完全指南

發布時間:2025/3/20 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 html dom 高级,DOM 高级工程师不完全指南 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原標題:DOM 高級工程師不完全指南

本文轉載于 SegmentFault 社區專欄:凱里的前端專欄

譯者:kyrieliu

“我不敢徒手撕 DOM 了”

絕大多數前端er都有這樣的困擾,但本著基礎為大的原則,手撕 DOM 應當是一個前端攻城獅的必備技能,這正是本文誕生的初衷 —— DOM 并沒有那么難搞,如果能去充分利用它,那么你離愛上它就不遠了。

三年前我初入前端坑的時候,發現了一個叫做 jQuery 的寶貝,她有一個神奇的 $ 函數,可以讓我快速選中某一個或一組 DOM 元素,并提供鏈式調用以減少代碼的冗余。雖然現在提到 jQuery 這個名詞,你會覺得老土,“9102 都快過去了你跟我說 Nokia?”。土歸土,但也是真的香。盡管這幾年風生水起的 Vue、React 加劇了 jQuery 的沒落,但全世界仍有超過 6600 萬個網站在使用 jQuery,占全球所有網站數量的 74%。

jQuery 也給業界留下了產生深遠影響的“遺產”,W3C 就仿照其 $ 函數實現了 querySelector 和 querySelectorAll。而諷刺的是,也正是這兩個原生方法的出現,大大加快了 jQuery 的沒落,因為它們取代了前者最常用的功能 —— 快捷的選擇 DOM 元素。

雖然這兩個新方法寫起來有點長(問題不大,封裝一哈),但是它們是真的賊好用。來,沖!

獲取單個 DOM 元素

向 document.querySelector 中傳入任何有效的 css 選擇器,即可選中單個 DOM 元素:

如果頁面上沒有指定的元素時,返回 null。

獲取 DOM 元素集合

使用 document.querySelectorAll 可以獲取一個元素集合,它的傳參和 document.querySelector 一毛一樣。它會返回一個靜態的 NodeList ,如果沒有元素被查找到,則會返回一個空的 NodeList 。

NodeList 是一個可遍歷的對象(aka:偽數組),雖然和數組很像,但它確實不是數組,雖然可以利用 forEach 遍歷它,但它并不具備數組的一些方法,比如 map、reduce、find。

那么問題來了,如何將一個偽數組轉化為數組呢?ES6 為開發者提供了兩個便利的選擇

遠古時代,開發者們常用 getElementsByTagName 和 getElementsByClassName 去獲取元素集合,但不同于 querySelectorAll,它們獲取的是一個動態的 HTMLCollection,這就意味著,它的結果會一直隨著 DOM 的改變而改變。

元素的局部搜索

當需要查找元素時,不一定每次都基于 document 去查找。開發者可以在任何 HTMLElement 上進行 DOM 元素的局部搜索:

事實證明,每個優秀的開發者都是很懶的。為了減少對寶貝鍵盤的損耗,我一般會這么干:

保護機械鍵盤,從我做起。

少年,爬上這棵 DOM 樹

上述內容的主題是查找 DOM 元素,這是一個自上而下的過程:從父元素向其包含的子元素發起查詢。

但沒有一個 API 可以幫助開發者借由子元素向父元素發起查詢。

迷惑之際,MDN 給我提供了一個寶藏方法:closest

Starting with the Element itself, the closest method traverses parents (heading toward the document root) of the Element until it finds a node that matches the provided selectorString. Will return itself or the matching ancestor. If no such element exists, it returns null.

也就是說,closest 方法可以從特定的 HTMLElement 向上發起查詢,找到第一個符合指定 css 表達式的父元素(也可以是元素自身),如果找到了文檔根節點還沒有找到目標時,就會返回 null 。

添加 DOM 元素

如果用原生 Java 向 DOM 中添加一個或多個元素,一般開發者的內心都是抗拒的,為啥呢?假設向頁面添加一個 a 標簽:

正常情況下,需要寫出如下的代碼:

真的麻煩。

而老大哥 jQuery 可以簡化為:

但,各位觀眾,如今原生 Java 也可以實現這一操作了:

這個方法允許你將任何有效的 HTML 字符串插入到一個 DOM 元素的四個位置,這四個位置由方法的第一個參數指定,分別是:

'beforebegin':元素之前

'afterbegin':元素內,位于現存的第一個子元素之前

'beforeend':元素內,位于現存的最后一個子元素之后

'afterend': 元素之后

舒服了呀。

更舒服的是,它還有兩個好兄弟,讓開發者可以快速地插入 HTML 元素和字符串:

移動 DOM 元素

上面提到的兄弟方法 insertAdjacentElement 也可以用來對已存在的元素進行移動,換句話說:當傳入該方法的是已存在于文檔中的元素時,該元素僅僅只會被移動(而不是復制并移動)。

如果你有以下 HTML:

然后操作一下,把

搞到

的后面去:

于是我們就得到了這樣的結果:

替換 DOM 元素

replaceChild? 這是幾年前的做法了,每當開發者需要替換兩個 DOM 元素,除了需要拿到這必須的兩個元素之外,還需要獲取他們的直接父元素:

而如今,開發者們可以使用 replaceWith 就可以完成兩個元素之間的替換了:

從用法上來說,要比前者清爽一些。

需要注意的是:

? 如果傳入的 newElement 已經存在于文檔中,那么方法的執行結果將是 newElement 被移動并替換掉 oldElement

?如果傳入的 newElement 是一個字符串,那么它將作為一個 TextNode 替換掉原有的元素

移除 DOM 元素

和替換元素的老方法相同,移除元素的老方法同樣需要獲取到目標元素的直接父元素:

現在只需要在目標元素上執行一次 remove 方法就 ok 了:

用 HTML 字符串創建 DOM 元素

細心的你一定發現了,上文提到的 insertAdjacent 方法允許開發者直接將一段 HTML 插入到文檔當中,如果我們此刻只想生成一個 DOM 元素以備將來使用呢?

DOMParser 對象的 parseFromString 方法即可滿足這樣的需求。該方法可以實現將一串 HTML 或 XML 字符串轉化為一個完整的 DOM 文檔,也就是說,當我們需要獲得預期的 DOM 元素時,需要從方法返回的 DOM 文檔中獲取這個元素:

做一個檢查 DOM 的小能手

標準的 DOM API 為開發者們提供了很多便利的方法去檢查 DOM 。比如,matches 方法可以判斷出一個元素是否匹配一個確定的選擇器:

contains 方法可以檢測出一個元素是否包含另一個元素(或者:一個元素是否是另一個元素的子元素):

判斷兩個元素的位置關系

compareDocumentPosition 是一個強大的 API ,它可以快速判斷出兩個 DOM 元素的位置關系,諸如:先于、跟隨、是否包含。它返回一個整數,代表了兩個元素之間的關系。

標準語句:

返回值定義如下:

1: 兩個元素不在同一個文檔內

2: otherElement 在 element 之前

4: otherElement 在 element 之后

8: otherElement 包含 element

16: otherElement 被 element 所包含

那么問題來了,為什么上面例子中第一行的結果是20、第二行的結果是10呢?

因為 h1 同時滿足“被 container 所包含(16)” 和 “在 container 之后”,所以語句的執行結果是 16+4=20,同理可推出第二條語句的結果是 8+2=10。

DOM 觀察者: Mutation Observer

在處理用戶交互的時候,當前頁面的 DOM 元素通常會發生很多變化,而有些場景需要開發者們監聽這些變化并在觸發后執行相應的操作。MutationObserver 是瀏覽器提供的一個專門用來監聽 DOM 變化的接口,它強大到幾乎可以觀測到一個元素的所有變化,可觀測的對象包括:文本的改變、子節點的添加和移除和任何元素屬性的變化。

如同往常一樣,如果想構造任何一個對象,那就 new 它的構造函數:

傳入構造函數的是一個回調函數,它會在被監聽的 DOM 元素發生改變時執行,它的兩個參數分別是:包含本次所有變更的列表 MutationRecords 和 observer 本身。其中,MutationRecords 的每一條都是一個變更記錄,它是一個普通的對象,包含如下常用屬性:

type: 變更的類型,attributes / characterData / childList

target: 發生變更的 DOM 元素

addedNodes: 新增子元素組成的 NodeList

removedNodes: 已移除子元素組成的的 NodeList

attributeName: 值發生改變的屬性名,如果不是屬性變更,則返回 null

previousSibling: 被添加或移除的子元素之前的兄弟節點

nextSibling: 被添加或移除的子元素之后的兄弟節點

根據目前的信息,可以寫一個 callback 函數了:

至此,我們有了一個 DOM 觀察者 observer,也有了一個完整可用的 DOM 變化后的回調函數 callback,就差一個需要被觀測的 DOM 元素了:

在上面的代碼中,我們通過調用觀察者對象的 observe 方法,對 id 為 target 的 DOM 元素進行了觀測(第一個參數就是需要觀測的目標元素),而第二個元素,我們傳入了一個配置對象:開啟對屬性的觀測 / 只觀測 class 屬性 / 屬性變化時傳遞屬性舊值 / 開啟對子元素列表的觀測。

配置對象支持如下字段:

attributes: Boolean,是否監聽元素屬性的變化

attributeFilter: String[],需要監聽的特定屬性名稱組成的數組

attributeOldValue: Boolean,當監聽元素的屬性發生變化時,是否記錄并傳遞屬性的上一個值

characterData: Boolean,是否監聽目標元素或子元素樹中節點所包含的字符數據的變化

characterDataOldValue: Boolean,字符數據發生變化時,是否記錄并傳遞其上一個值

childList: Boolean,是否監聽目標元素添加或刪除子元素

subtree: Boolean,是否擴展監視范圍到目標元素下的整個子樹的所有元素

當不再監聽目標元素的變化時,調用 observer 的 disconnect 方法即可,如果需要的話,可以先調用 observer 的 takeRecords 方法從 observer 的通知隊列中刪除所有待處理的通知,并將它們返回到一個由 MutationRecord 對象組成的數組當中:

The End

盡管大部分 DOM API 的名字都很長(寫起來很麻煩),但它們都是非常強大并且通用的。這些 API 往往旨在為開發者提供底層的構建單元,以便在此之上建立更為通用和簡潔的抽象邏輯,因此從這個角度出發,它們必須提供一個完整的名稱以變得足夠明確和清晰。

只要能發揮出這些 API 本應該發揮出的潛能,多敲幾下鍵盤又何妨呢?

DOM 是每個 Javs 開發者必不可少的知識,因為我們幾乎每天都在使用它。莫怕,大膽激發自己操作 DOM 的洪荒之力吧,盡早成為一個 DOM 高級工程師。

本文干貨部分翻譯自: Use the DOM like a Pro

https://itnext.io/using-the-dom-like-a-pro-163a6c552eba?gi=9cacb5510dff

譯者:kyrieliu(劉凱里)

SegmentFault 社區文章鏈接:

https://segmentfault.com/a/1190000021199145

責任編輯:

總結

以上是生活随笔為你收集整理的html dom 高级,DOM 高级工程师不完全指南的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。