JS監(jiān)聽和響應(yīng)DOM元素的變化的方法
前言
在前端開發(fā)中,處理動(dòng)態(tài)變化的 DOM(文檔對(duì)象模型)很是常見的需求。
比如
- 根據(jù)一些動(dòng)態(tài)內(nèi)容是否超出容器來處理容器寬度和高度,
- 在用戶填寫表單時(shí),某些字段需要即時(shí)驗(yàn)證
- 自動(dòng)化測(cè)試中,可能需要監(jiān)控 DOM 變化來驗(yàn)證測(cè)試條件
- 一個(gè)自定義的下拉菜單組件可能需要監(jiān)聽其內(nèi)容的變化,并根據(jù)內(nèi)容更新菜單的顯示。 等等常用的場(chǎng)景。
MutationObserver 簡(jiǎn)介
MutationObserver
是一個(gè)用于監(jiān)聽 DOM 樹中變動(dòng)的接口。與舊的 Mutation Events(如 DOMSubtreeModified
)相比,MutationObserver
更加高效且提供了更好的性能,適用于復(fù)雜和頻繁的 DOM 操作。
MutationObserver.observe() 方法
MutationObserver.observe()
方法用于開始監(jiān)聽指定 DOM 節(jié)點(diǎn)的變化。其基本語(yǔ)法如下:
mutationObserver.observe(targetNode, options);
targetNode
:要觀察的 DOM 節(jié)點(diǎn)。options
:一個(gè)配置對(duì)象,用于指定要觀察的變化類型和其他選項(xiàng)。
options 配置對(duì)象
options
是一個(gè)對(duì)象,具有以下屬性:
childList
:布爾值,指示是否觀察子節(jié)點(diǎn)的添加和刪除。attributes
:布爾值,指示是否觀察屬性的變化。characterData
:布爾值,指示是否觀察文本內(nèi)容的變化。subtree
:布爾值,指示是否觀察目標(biāo)節(jié)點(diǎn)的所有后代節(jié)點(diǎn)(即,遞歸地觀察所有子孫節(jié)點(diǎn))。
以下是這些屬性的解釋:
childList
:設(shè)置為true
時(shí),MutationObserver
將監(jiān)聽目標(biāo)節(jié)點(diǎn)下的子節(jié)點(diǎn)的增加或刪除。attributes
:設(shè)置為true
時(shí),MutationObserver
將監(jiān)聽目標(biāo)節(jié)點(diǎn)的屬性的變化。characterData
:設(shè)置為true
時(shí),MutationObserver
將監(jiān)聽目標(biāo)節(jié)點(diǎn)及其子節(jié)點(diǎn)中的文本內(nèi)容的變化。subtree
:設(shè)置為true
時(shí),MutationObserver
將遞歸地監(jiān)聽目標(biāo)節(jié)點(diǎn)的所有子節(jié)點(diǎn)。
示例代碼
下面是一個(gè)使用 MutationObserver.observe()
的簡(jiǎn)單示例:
// 創(chuàng)建一個(gè) MutationObserver 實(shí)例 const observer = new MutationObserver((mutationsList) => { for (const mutation of mutationsList) { if (mutation.type === 'childList') { console.log('子節(jié)點(diǎn)發(fā)生變化'); } else if (mutation.type === 'attributes') { console.log(`屬性 ${mutation.attributeName} 發(fā)生變化`); } } }); // 選擇需要觀察的目標(biāo)節(jié)點(diǎn) const targetNode = document.getElementById('target'); // 配置觀察選項(xiàng) const config = { childList: true, attributes: true, subtree: true }; // 啟動(dòng)觀察 observer.observe(targetNode, config); // 示例:修改 DOM document.getElementById('target').innerHTML = '<p>新的內(nèi)容</p>'; document.getElementById('target').setAttribute('data-test', 'value');
代碼解析
創(chuàng)建
MutationObserver
實(shí)例:- 通過
new MutationObserver(callback)
創(chuàng)建MutationObserver
實(shí)例,并提供回調(diào)函數(shù)callback
?;卣{(diào)函數(shù)會(huì)在 DOM 發(fā)生變化時(shí)被調(diào)用,并傳遞一個(gè)MutationRecord
對(duì)象數(shù)組,其中包含所有變化的詳細(xì)信息。
- 通過
選擇目標(biāo)節(jié)點(diǎn):
- 使用
document.getElementById('target')
獲取要觀察的 DOM 節(jié)點(diǎn)。
- 使用
配置觀察選項(xiàng):
- 通過
config
對(duì)象指定要觀察的變化類型。設(shè)置childList
和attributes
為true
,表示監(jiān)聽子節(jié)點(diǎn)的變化和屬性的變化,同時(shí)subtree
設(shè)置為true
表示遞歸觀察目標(biāo)節(jié)點(diǎn)的所有后代節(jié)點(diǎn)。
- 通過
啟動(dòng)觀察:
- 使用
observer.observe(targetNode, config)
開始觀察目標(biāo)節(jié)點(diǎn)的變化。
- 使用
修改 DOM:
- 當(dāng)修改了目標(biāo)節(jié)點(diǎn)的內(nèi)容和屬性,觸發(fā)
MutationObserver
的回調(diào)函數(shù)。
- 當(dāng)修改了目標(biāo)節(jié)點(diǎn)的內(nèi)容和屬性,觸發(fā)
停止觀察
如果需要停止觀察 DOM 變化,可以使用 disconnect()
方法:
observer.disconnect();
實(shí)際開發(fā)中 MutationObserver 的具體用途:
1. 動(dòng)態(tài)內(nèi)容更新
場(chǎng)景描述:
當(dāng)應(yīng)用程序需要在后臺(tái)更新內(nèi)容并反映到前端時(shí),例如,異步加載新內(nèi)容或從服務(wù)器獲取數(shù)據(jù)并將其添加到頁(yè)面中。
示例:
一個(gè)社交媒體應(yīng)用可能會(huì)動(dòng)態(tài)加載新帖子。當(dāng)新帖子被添加到 DOM 中時(shí),你可以使用 MutationObserver
來實(shí)時(shí)更新 UI,例如顯示新帖子通知。
const observer = new MutationObserver((mutationsList) => { for (const mutation of mutationsList) { if (mutation.type === 'childList') { console.log('New content added'); // 執(zhí)行相關(guān)操作,例如更新通知或重新渲染 UI } } }); const feed = document.getElementById('feed'); observer.observe(feed, { childList: true });
2. 動(dòng)態(tài)表單驗(yàn)證
場(chǎng)景描述:
在用戶填寫表單時(shí),某些字段可能需要即時(shí)驗(yàn)證。例如,用戶輸入數(shù)據(jù)時(shí)檢查格式或有效性。
示例:
當(dāng)用戶在輸入框中輸入內(nèi)容時(shí),你可以使用 MutationObserver
來監(jiān)控 value
屬性的變化,并實(shí)時(shí)驗(yàn)證輸入數(shù)據(jù)。
const observer = new MutationObserver((mutationsList) => { for (const mutation of mutationsList) { if (mutation.type === 'attributes' && mutation.attributeName === 'value') { validateInput(mutation.target.value); } } }); const inputField = document.getElementById('input'); observer.observe(inputField, { attributes: true });
3. 實(shí)時(shí) UI 組件更新
場(chǎng)景描述:
某些 UI 組件可能需要根據(jù)數(shù)據(jù)變化實(shí)時(shí)更新。例如,某些圖表或可視化組件需要反映數(shù)據(jù)源的最新狀態(tài)。
示例:
一個(gè)圖表組件可以監(jiān)控?cái)?shù)據(jù)容器的變化,并在數(shù)據(jù)變化時(shí)重新渲染圖表。
const observer = new MutationObserver(() => { updateChart(); // 更新圖表 }); const dataContainer = document.getElementById('data-container'); observer.observe(dataContainer, { childList: true, subtree: true });
4. 自定義組件或庫(kù)
場(chǎng)景描述:
在創(chuàng)建自定義 Web 組件或庫(kù)時(shí),可能需要監(jiān)控和處理其內(nèi)部 DOM 的變化。
示例:
一個(gè)自定義的下拉菜單組件可能需要監(jiān)聽其內(nèi)容的變化,并根據(jù)內(nèi)容更新菜單的顯示。
const observer = new MutationObserver((mutationsList) => { for (const mutation of mutationsList) { if (mutation.type === 'childList') { updateDropdown(); // 更新下拉菜單 } } }); const dropdownContent = document.getElementById('dropdown-content'); observer.observe(dropdownContent, { childList: true });
5. 支持第三方庫(kù)或框架
場(chǎng)景描述:
在與第三方庫(kù)或框架集成時(shí),需要監(jiān)控這些庫(kù)對(duì) DOM 進(jìn)行的修改。
示例:
某些第三方 UI 庫(kù)可能會(huì)動(dòng)態(tài)生成或修改 DOM 元素,使用 MutationObserver
可以確保你的代碼能夠檢測(cè)到這些變化并作出相應(yīng)處理。
const observer = new MutationObserver(() => { handleLibraryChanges(); // 處理第三方庫(kù)的變化 }); const targetNode = document.getElementById('target'); observer.observe(targetNode, { childList: true, attributes: true });
總結(jié)
MutationObserver
提供了一種高效、靈活的方式來監(jiān)控 DOM 的變化。通過使用 observe()
方法,你可以設(shè)置詳細(xì)的觀察選項(xiàng)來滿足不同的需求。善用這些功能將有助于開發(fā)中更好地處理動(dòng)態(tài)內(nèi)容的變化。
以上就是JS監(jiān)聽和響應(yīng)DOM元素的變化的方法的詳細(xì)內(nèi)容,更多關(guān)于JS監(jiān)聽和響應(yīng)DOM變化的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
利用js實(shí)現(xiàn)Vue2.0中數(shù)據(jù)的雙向綁定功能
vue數(shù)據(jù)雙向綁定是通過數(shù)據(jù)劫持結(jié)合發(fā)布者-訂閱者模式的方式來實(shí)現(xiàn)的,下面這篇文章主要給大家介紹了關(guān)于如何利用js實(shí)現(xiàn)Vue2.0中數(shù)據(jù)的雙向綁定功能的相關(guān)資料,需要的朋友可以參考下2021-07-07JS小知識(shí)之如何將CSV轉(zhuǎn)換為JSON字符串
CSV文件一般是以逗號(hào)為分隔值的文件(Comma-Separated?Values,CSV,有時(shí)也稱為字符分隔值,因?yàn)榉指糇址部梢圆皇嵌禾?hào)),其文件以純文本形式存儲(chǔ)表格數(shù)據(jù)(數(shù)字和文本),下面這篇文章主要給大家介紹了JS小知識(shí)之如何將CSV轉(zhuǎn)換為JSON字符串的相關(guān)資料,需要的朋友可以參考下2023-06-06Bootstrap實(shí)現(xiàn)登錄校驗(yàn)表單(帶驗(yàn)證碼)
本文給大家介紹使用Bootstrap新制作的一個(gè)登錄框,帶驗(yàn)證碼,帶校驗(yàn),非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友可以參考下2016-06-06js技巧之十幾行的代碼實(shí)現(xiàn)vue.watch代碼
相信很多的用vue的人都知道vue雙向綁定的原理建立在,給屬性綁定了getter和setter,在屬性被改變的同時(shí)觸發(fā)視圖的再渲染。而本期也是借助這兩個(gè)內(nèi)置方法實(shí)現(xiàn)vue內(nèi)的watch2018-06-06詳解如何用webpack打包一個(gè)網(wǎng)站應(yīng)用項(xiàng)目
本篇文章主要介紹了如何用webpack打包一個(gè)網(wǎng)站應(yīng)用,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-07-07JavaScript 計(jì)算笛卡爾積實(shí)例詳解
這篇文章主要介紹了JavaScript 計(jì)算笛卡爾積實(shí)例詳解的相關(guān)資料,這里附有實(shí)例代碼,需要的朋友可以參考下2016-12-12