JS監(jiān)聽(tīng)dom高度變化幾種常用方法總結(jié)
前言
有時(shí)候我們需要監(jiān)聽(tīng)dom的變化,例如有時(shí)候圖片未加載完就取 dom 的高度,這樣會(huì)導(dǎo)致高度不正確,所以需要監(jiān)聽(tīng) dom 的高度變化。才能準(zhǔn)確獲取dom的高度,那么有哪些監(jiān)聽(tīng)dom高度變化的方法呢?今天簡(jiǎn)單列舉一下。
監(jiān)聽(tīng)dom樹(shù)變化DOMNodeInserted
可以用DOMNodeInserted事件監(jiān)聽(tīng)子元素是否改變,但是不是很準(zhǔn)確。
var dom = document.getElementById('dom'); var height = dom.offsetHeight; dom.addEventListener('DOMNodeInserted', function () { var newHeight = dom.offsetHeight; if (newHeight !== height) { console.log('dom高度變化了'); height = newHeight; } });
MutationObserver 構(gòu)造函數(shù)
Mutation Observer API 用來(lái)監(jiān)視 DOM 變動(dòng)。DOM 的任何變動(dòng),比如節(jié)點(diǎn)的增減、屬性的變動(dòng)、文本內(nèi)容的變動(dòng),這個(gè) API 都可以得到通知。 目前來(lái)看,IE11及以上都可以兼容。兼容性還可以,可以大膽使用。
MutationObserver 構(gòu)造函數(shù)的實(shí)例傳的是一個(gè)回調(diào)函數(shù),該函數(shù)接受兩個(gè)參數(shù),第一個(gè)是變動(dòng)的數(shù)組,第二個(gè)是觀察器的實(shí)例。
var observer = new MutationObserver(function (mutations, observer){ mutations.forEach(function (mutaion) { console.log(mutation); }) })
MutationObserver 的應(yīng)用
var haoroomsId = document.getElementById('haorooms'); var MutationObserver = window.MutationObserver || window.webkitMutationObserver || window.MozMutationObserver; var recordHeight = 0; var mutationObserver = new MutationObserver(function (mutations) { console.log(mutations); let height = window.getComputedStyle(haoroomsId).getPropertyValue('height'); if (height === recordHeight) { return; } recordHeight = height; console.log('高度變化了'); // 之后更新外部容器等操作 }) mutationObserver.observe(haoroomsId, { childList: true, // 子節(jié)點(diǎn)的變動(dòng)(新增、刪除或者更改) attributes: true, // 屬性的變動(dòng) characterData: true, // 節(jié)點(diǎn)內(nèi)容或節(jié)點(diǎn)文本的變動(dòng) subtree: true // 是否將觀察器應(yīng)用于該節(jié)點(diǎn)的所有后代節(jié)點(diǎn) })
針對(duì)動(dòng)畫animation、transform監(jiān)聽(tīng)不到的情況,可以在動(dòng)畫完成監(jiān)聽(tīng)高度就可以了
el.addEventListener('animationend', onHeightChange) el.addEventListener('transitionend', onHeightChange)
ResizeObserver
ResizeObserver 是新的API,處于實(shí)驗(yàn)階段,因此,兼容性不太好,文檔:ResizeObserver - Web API 接口參考 | MDN
使用很簡(jiǎn)單
// create an Observer instance const resizeObserver = new ResizeObserver((entries) => console.log('Body height changed:', entries[0].target.clientHeight) ); // start observing a DOM node resizeObserver.observe(document.body);
ResizeObserver Polyfill
實(shí)驗(yàn)性的 API 不足,可以用 Polyfill 來(lái)彌補(bǔ)
ResizeObserver Polyfill 利用事件冒泡,在頂層 document 上監(jiān)聽(tīng)動(dòng)畫 transitionend;
監(jiān)聽(tīng) window 的 resize 事件;
其次用 MutationObserver 監(jiān)聽(tīng) document 元素;
兼容IE11以下 通過(guò) DOMSubtreeModified 監(jiān)聽(tīng) document 元素。
/** * Initializes DOM listeners. * * @private * @returns {void} */ ResizeObserverController.prototype.connect_ = function () { // Do nothing if running in a non-browser environment or if listeners // have been already added. if (!isBrowser || this.connected_) { return; } // Subscription to the "Transitionend" event is used as a workaround for // delayed transitions. This way it's possible to capture at least the // final state of an element. document.addEventListener('transitionend', this.onTransitionEnd_); window.addEventListener('resize', this.refresh); if (mutationObserverSupported) { this.mutationsObserver_ = new MutationObserver(this.refresh); this.mutationsObserver_.observe(document, { attributes: true, childList: true, characterData: true, subtree: true }); } else { document.addEventListener('DOMSubtreeModified', this.refresh); this.mutationEventsAdded_ = true; } this.connected_ = true; };
小結(jié)
以上就是總結(jié)的js如何監(jiān)聽(tīng)dom變化的方法,假如你不用兼容老的瀏覽器,可以用最新的ResizeObserver,當(dāng)然也可以用ResizeObserver,配合Polyfill來(lái)進(jìn)行。
總結(jié)
到此這篇關(guān)于JS監(jiān)聽(tīng)dom高度變化方法的文章就介紹到這了,更多相關(guān)JS監(jiān)聽(tīng)dom高度變化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- java中常見(jiàn)XML解析器的使用詳解(JAXP,DOM4J,Jsoup,JsoupXPath)
- js獲取dom元素寬高的幾種方法
- javascript?DOM?querySelectorAll()?使用方法
- jsp有兩個(gè)按鈕來(lái)控制Timer的開(kāi)始和結(jié)束方法
- 詳解Nodejs的timers模塊
- 在JavaScript中使用timer示例
- TimergliderJS 一個(gè)基于jQuery的時(shí)間軸插件
- JavaScript Timer實(shí)現(xiàn)代碼
- javascript 寫的一個(gè)簡(jiǎn)單的timer
- JavaScript中的DOM和Timer的基本操作
相關(guān)文章
微信小程序?qū)崿F(xiàn)3D輪播圖效果(非swiper組件)
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)3D輪播圖效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09純JavaScript創(chuàng)建一個(gè)簡(jiǎn)單的待辦事項(xiàng)列表
這篇文章主要給大家介紹了關(guān)于純JavaScript創(chuàng)建一個(gè)簡(jiǎn)單的待辦事項(xiàng)列表的相關(guān)資料,清單通常用于記錄我們?cè)谀骋惶煨枰瓿傻乃惺马?xiàng),將最關(guān)鍵的任務(wù)放在最上方,將最不重要的事項(xiàng)放在最下方,需要的朋友可以參考下2024-01-01從父頁(yè)面調(diào)用iframe中的JavaScript代碼的方法
在Web前端開(kāi)發(fā)中,iframe(內(nèi)嵌框架)是一種常用的技術(shù),用于在一個(gè)頁(yè)面中嵌入另一個(gè)HTML頁(yè)面,然而,有時(shí)候我們需要從父頁(yè)面與iframe內(nèi)的內(nèi)容進(jìn)行交互,本文將詳細(xì)介紹如何從父頁(yè)面調(diào)用iframe中的JavaScript代碼,提供詳細(xì)的代碼示例和最佳實(shí)踐,需要的朋友可以參考下2024-11-11微信小程序 自定義復(fù)選框?qū)崿F(xiàn)代碼實(shí)例
這篇文章主要介紹了微信小程序 自定義復(fù)選框?qū)崿F(xiàn)代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09JavaScript異步編程的干貨知識(shí)點(diǎn)分享
異步是什么意思?如何實(shí)現(xiàn)異步編程?不同的異步模式有哪些?本文將圍繞這些問(wèn)題和大家分享JavaScript異步編程中的重要知識(shí)點(diǎn),需要的可以學(xué)習(xí)一下2023-06-06