JS怎樣監(jiān)聽DOM內(nèi)容變化 5個DOM變化監(jiān)聽方法助你實時追蹤節(jié)點變更

mutationobserver是監(jiān)聽dom內(nèi)容變化的首選方案,其步驟包括:1.創(chuàng)建實例并傳入回調(diào)函數(shù);2.指定觀察目標節(jié)點和配置選項(如childlist、attributes等);3.調(diào)用disconnect()停止觀察。相較于其他方法,mutationobserver具有異步執(zhí)行、性能高、信息詳細等優(yōu)勢。其他方法如domnodeinserted/domnoderemoved事件已廢棄,且同步執(zhí)行影響性能;domcharacterdatamodified同樣被棄用;propertychange僅適用于ie;setinterval輪詢檢測則消耗資源且不夠精確。選擇監(jiān)聽方法時應優(yōu)先考慮mutationobserver,僅在兼容舊瀏覽器時謹慎使用其他方式。為監(jiān)聽動態(tài)創(chuàng)建元素,可觀察父節(jié)點并在回調(diào)中判斷新增節(jié)點類型;避免無限循環(huán)的方法是在回調(diào)中臨時斷開觀察器,修改dom后再重新連接。

JS怎樣監(jiān)聽DOM內(nèi)容變化 5個DOM變化監(jiān)聽方法助你實時追蹤節(jié)點變更

JS監(jiān)聽DOM內(nèi)容變化,簡單來說,就是讓你能在網(wǎng)頁內(nèi)容發(fā)生改變時,立即知道并做出反應。這對于構建動態(tài)網(wǎng)頁、實時更新ui至關重要。

JS怎樣監(jiān)聽DOM內(nèi)容變化 5個DOM變化監(jiān)聽方法助你實時追蹤節(jié)點變更

MutationObserver是首選方案,功能強大且性能優(yōu)秀,但也要了解其他方法,以便在特定場景下靈活應用。

JS怎樣監(jiān)聽DOM內(nèi)容變化 5個DOM變化監(jiān)聽方法助你實時追蹤節(jié)點變更

MutationObserver:現(xiàn)代瀏覽器的首選

MutationObserver是監(jiān)聽DOM變化的現(xiàn)代API。它允許你觀察DOM樹的特定部分,并在這些部分發(fā)生變化時收到通知。相較于傳統(tǒng)的事件監(jiān)聽,MutationObserver具有更高的性能和靈活性。

JS怎樣監(jiān)聽DOM內(nèi)容變化 5個DOM變化監(jiān)聽方法助你實時追蹤節(jié)點變更

  • 配置觀察器: 首先,你需要創(chuàng)建一個MutationObserver實例,并傳入一個回調(diào)函數(shù)。這個回調(diào)函數(shù)會在每次DOM變化時被調(diào)用。
const observer = new MutationObserver(mutations => {   mutations.forEach(mutation => {     console.log(mutation); // 打印每次變化的信息   }); });
  • 指定觀察目標和選項: 接下來,你需要指定要觀察的DOM節(jié)點和配置選項。選項包括childList(觀察子節(jié)點變化)、attributes(觀察屬性變化)、characterData(觀察文本內(nèi)容變化)等。
const targetNode = document.getElementById('myElement'); const config = {   childList: true,   attributes: true,   subtree: true,   characterData: true };  observer.observe(targetNode, config);
  • 停止觀察: 當你不再需要觀察DOM變化時,可以調(diào)用disconnect()方法停止觀察器。
observer.disconnect();

MutationObserver的優(yōu)勢在于異步執(zhí)行,不會阻塞UI線程,而且提供了詳細的變更信息,可以精確地知道哪些節(jié)點發(fā)生了哪些變化。

DOMNodeInserted/DOMNodeRemoved:古老的事件監(jiān)聽方式

雖然不推薦使用,但了解一下也無妨。DOMNodeInserted和DOMNodeRemoved是較早的DOM事件,分別在節(jié)點被插入或移除時觸發(fā)。

document.addEventListener('DOMNodeInserted', function(event) {   console.log('節(jié)點被插入:', event.target); });  document.addEventListener('DOMNodeRemoved', function(event) {   console.log('節(jié)點被移除:', event.target); });

這種方式的缺點是同步執(zhí)行,可能會影響性能,并且無法提供詳細的變更信息。另外,這些事件已經(jīng)被廢棄,不應在新項目中使用。

DOMCharacterDataModified:監(jiān)聽文本內(nèi)容變化

DOMCharacterDataModified事件在節(jié)點文本內(nèi)容發(fā)生變化時觸發(fā)。

document.addEventListener('DOMCharacterDataModified', function(event) {   console.log('文本內(nèi)容發(fā)生變化:', event.target.data); });

同樣,這個事件也已經(jīng)被廢棄,建議使用MutationObserver替代。

propertychange:ie瀏覽器的專屬

propertychange是IE瀏覽器特有的事件,用于監(jiān)聽元素的屬性變化。

element.attachEvent('onpropertychange', function(event) {   console.log('屬性發(fā)生變化:', event.propertyName); });

由于IE瀏覽器已經(jīng)逐漸退出歷史舞臺,因此不建議使用這種方式。

定時器setInterval:輪詢檢測

如果以上方法都無法滿足你的需求,或者你需要在不支持MutationObserver的舊瀏覽器中使用,可以考慮使用定時器輪詢檢測DOM變化。

let previousInnerHTML = document.getElementById('myElement').innerHTML;  setInterval(function() {   const currentInnerHTML = document.getElementById('myElement').innerHTML;   if (currentInnerHTML !== previousInnerHTML) {     console.log('DOM內(nèi)容發(fā)生變化');     previousInnerHTML = currentInnerHTML;   } }, 100);

這種方式的缺點是會消耗大量的CPU資源,并且無法精確地知道哪些節(jié)點發(fā)生了變化。所以,盡量避免使用。

如何選擇合適的DOM變化監(jiān)聽方法?

選擇哪種方法取決于你的具體需求和瀏覽器兼容性要求。如果你的項目只需要支持現(xiàn)代瀏覽器,那么MutationObserver是最佳選擇。如果需要兼容舊瀏覽器,可以考慮使用定時器輪詢檢測,但要注意性能問題。

MutationObserver的回調(diào)函數(shù)執(zhí)行頻率是怎樣的?

MutationObserver的回調(diào)函數(shù)不是每次DOM操作都立即執(zhí)行的。瀏覽器會將一段時間內(nèi)的DOM操作合并成一個MutationRecord,然后一次性調(diào)用回調(diào)函數(shù)。這有助于提高性能,避免頻繁的回調(diào)。

如何監(jiān)聽動態(tài)創(chuàng)建的DOM元素?

如果你需要在DOM元素被動態(tài)創(chuàng)建后立即監(jiān)聽其變化,可以使用MutationObserver結合事件委托。首先,觀察包含動態(tài)元素的父節(jié)點,然后在回調(diào)函數(shù)中判斷新插入的節(jié)點是否是目標元素,如果是,則開始觀察目標元素。

const parentNode = document.getElementById('parent'); const observer = new MutationObserver(mutations => {   mutations.forEach(mutation => {     if (mutation.type === 'childList') {       mutation.addedNodes.forEach(node => {         if (node.id === 'dynamicElement') {           // 開始觀察動態(tài)元素           observer.observe(node, { attributes: true, characterData: true, subtree: true });         }       });     }   }); });  observer.observe(parentNode, { childList: true, subtree: true });

如何避免MutationObserver的無限循環(huán)?

在使用MutationObserver時,需要注意避免無限循環(huán)。例如,如果在回調(diào)函數(shù)中修改了被觀察的DOM節(jié)點,可能會再次觸發(fā)回調(diào)函數(shù),導致無限循環(huán)。為了避免這種情況,可以在回調(diào)函數(shù)中臨時停止觀察器,修改DOM節(jié)點后重新啟動觀察器。

const observer = new MutationObserver(mutations => {   observer.disconnect(); // 臨時停止觀察器   // 修改DOM節(jié)點   observer.observe(targetNode, config); // 重新啟動觀察器 });

? 版權聲明
THE END
喜歡就支持一下吧
點贊14 分享