ResizeObserver?API使用示例詳解
API介紹
當(dāng)我們需要知道一個(gè)元素的大小變化或者屏幕橫豎屏?xí)r,我們需要監(jiān)聽window.resize事件或者window.orientationchange方法。由于reize事件會(huì)在一秒內(nèi)觸發(fā)將近60次,所以很容易在改變窗口大小時(shí)導(dǎo)致性能問(wèn)題。換句話說(shuō),window.resize事件通常是浪費(fèi)的,因?yàn)樗鼤?huì)監(jiān)聽每個(gè)元素的大小變化(只有window對(duì)象才有resize事件),而不是具體到某個(gè)元素的變化。如果我們只想監(jiān)聽某個(gè)元素的變化的話,這種操作就很浪費(fèi)性能了。
而ResizeObserver API就可以幫助我們:監(jiān)聽一個(gè)DOM節(jié)點(diǎn)的變化,這種變化包括但不僅限于:
- 某個(gè)節(jié)點(diǎn)的出現(xiàn)和隱藏
- 某個(gè)節(jié)點(diǎn)的大小變化
ResizeObserver API是一個(gè)新的JavaScript API,與IntersectionObserver API非常相似,它們都允許我們?nèi)ケO(jiān)聽某個(gè)元素的變化。
實(shí)際上,ResizeObserver API使用了觀察者模式,也就是我們常說(shuō)的發(fā)布-訂閱模式。發(fā)布-訂閱模式是JavaScript中典型的設(shè)計(jì)模式,在很多地方都有使用到。如Nodejs的Event模塊,Vue的父子組件通信等等。對(duì)發(fā)布-訂閱模式不熟悉的同學(xué)可以看看《JavaScript設(shè)計(jì)模式與開發(fā)實(shí)踐》這本書,對(duì)Vue的通信感興趣的可以看看Vue官網(wǎng)啦。
所以呢,我個(gè)人認(rèn)為,ResizeObserver API的出現(xiàn)是用于替代window.resize方法糟糕的性能的。(不喜親噴: ()
瀏覽器兼容性
雖然可以用來(lái)替代resize事件。但是它,很新,新到只有部分瀏覽器支持。
但是不要慫呀,如果想使用它,可以使用其polyfill。最低可以兼容到IE8以上的瀏覽器啦。所以以后在開發(fā)過(guò)程中如果想使用resize事件監(jiān)聽DOM的大小變化時(shí),何不嘗試一下ResizeObserver API呢?
用法
使用ResizeObserver API非常簡(jiǎn)單。ResizeObserver是個(gè)構(gòu)造函數(shù)。在使用new關(guān)鍵字調(diào)用構(gòu)造函數(shù),返回實(shí)例對(duì)象時(shí),需要傳入一個(gè)回調(diào)函數(shù),這個(gè)回調(diào)用于監(jiān)聽實(shí)例對(duì)象某個(gè)DOM節(jié)點(diǎn)的變化。如
const myObserver = new ResizeObserver(entries => { entries.forEach(entry => { console.log('大小位置', entry.contentRect) console.log('監(jiān)聽的DOM', entry.target) }) }) myObserver.observe(document.body)
以上,調(diào)用實(shí)例對(duì)象的observe方法,監(jiān)聽整個(gè)body節(jié)點(diǎn)的變化,當(dāng)改變窗口大小或者某個(gè)DOM節(jié)點(diǎn)出現(xiàn)或隱藏時(shí)時(shí),就會(huì)觸發(fā)回調(diào)。
觸發(fā)回調(diào)后的第一個(gè)參數(shù)是一個(gè)ResizeObserverEntry對(duì)象。這里的entry.target是DOM節(jié)點(diǎn)本身,而entry.contentRect是一個(gè)對(duì)象,包含了節(jié)點(diǎn)的位置屬性,如width, height, left, right, bottom, left, x, y等。
width
:指元素本身的寬度,不包含padding,border值
height
:指元素本身的高度,不包含padding,border值
top
:指padidng-top的值
left
:指padding-left的值
right
:指left + width的值
bottom
: 值top + height的值
x
:大小與top相同
y
:大小與left相同,不知道具體是指什么
明白了contentRect之后,就可以在使用這個(gè)api的時(shí)候針對(duì)不同場(chǎng)景獲取不同的值進(jìn)行業(yè)務(wù)的開發(fā)。
接著,如果想在監(jiān)聽多個(gè)DOM節(jié)點(diǎn)的變化,直接在一個(gè)實(shí)例對(duì)象上調(diào)用多次observe方法就好了。如
const myObserver = new ResizeObserver(entries => { // 注意,entres是個(gè)數(shù)組,數(shù)組項(xiàng)為每個(gè)需要監(jiān)聽的DOM節(jié)點(diǎn) entries.forEach(entry => { console.log('大小位置 contentRect', entry.contentRect) console.log('監(jiān)聽的DOM target', entry.target) }) }) myObserver.observe(document.body) myObserver.observe(document.querySelector('#app'))
然后,實(shí)例對(duì)象myObserver方法除了有observe方法之外,還有disconnect方法和unobserve方法。
unobserve方法,顧名思義了,就是取消監(jiān)聽某個(gè)DOM節(jié)點(diǎn)。比如說(shuō)想在兩秒后取消監(jiān)聽document.body,那么這樣做就好了
window.setTimeout(() => { myObserver.unobserve(document.body) // 需要接收一個(gè)參數(shù) }, 2000)
disconnect方法呢,就是取消對(duì)所有節(jié)點(diǎn)的監(jiān)聽。比如說(shuō)想在四秒后取消監(jiān)聽所有節(jié)點(diǎn),那么
window.setTimeout(() => { myObserver.disconnect() // 此時(shí)就不會(huì)再監(jiān)聽document.body,和#app節(jié)點(diǎn)了 }, 4000)
最后,在使用ResizeObserver API的時(shí)候,在每次觸發(fā)元素的大小變化時(shí),會(huì)在1s內(nèi)觸發(fā)回調(diào)蠻多次的。如果想進(jìn)一步優(yōu)化性能,可以加上throttle節(jié)流函數(shù)處理
// throttle需要自行引入哈 const myObserver = new ResizeObserver(throttle(entries => { entries.forEach(entry => { console.log('大小位置 contentRect', entry.contentRect) console.log('監(jiān)聽的DOM target', entry.target) }) }), 500)
這樣子就能做到每個(gè)500ms觸發(fā)一次回調(diào)啦。是不是很勁(粵語(yǔ))
總結(jié)
好的,關(guān)于ResizeObserver API的介紹就到這里了,如果想要一個(gè)更加具體的例子,可以參考
JavaScript API ResizeObserver使用示例
https://github.com/que-etc/resize-observer-polyfill
更多關(guān)于ResizeObserver API使用的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- centos系統(tǒng)安裝kubectl和部署kube-apiserver的詳細(xì)過(guò)程
- json-server?如何快速搭建REST?API?服務(wù)器
- 淺析k8s中各組件和kube?apiserver通信時(shí)的認(rèn)證和鑒權(quán)問(wèn)題
- IntersectionObserver API 詳解篇
- Kubernetes組件和架構(gòu)簡(jiǎn)介
- Kubernetes關(guān)鍵組件與結(jié)構(gòu)組成介紹
- Kubernetes核心組件實(shí)戰(zhàn)解析之API?Server與Scheduler的生產(chǎn)級(jí)應(yīng)用指南
相關(guān)文章
徒手實(shí)現(xiàn)關(guān)于JavaScript的24+數(shù)組方法
數(shù)組是我們?nèi)粘9ぷ髦杏玫淖铑l繁的一類數(shù)據(jù)結(jié)構(gòu),能幫助我們解決許多問(wèn)題,而其本身也包含接近33個(gè)之多的方法,做了一個(gè)腦圖分類如下,熟練使用數(shù)組的你,是否想知道他們內(nèi)部的實(shí)現(xiàn)原理呢?接下來(lái)小編就帶大家進(jìn)入主題,希望能幫助到你2021-09-09微信小程序左右滑動(dòng)切換頁(yè)面詳解及實(shí)例代碼
這篇文章主要介紹了微信小程序左右滑動(dòng)切換頁(yè)面詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2017-02-02微信小程序 在Chrome瀏覽器上運(yùn)行以及WebStorm的使用
這篇文章主要介紹了微信小程序 在Chrome瀏覽器上運(yùn)行以及WebStorm的使用的相關(guān)資料,需要的朋友可以參考下2016-09-09Javascript使用integrity屬性進(jìn)行安全驗(yàn)證
這篇文章主要介紹了Javascript使用integrity屬性進(jìn)行安全驗(yàn)證,在html中,script標(biāo)簽可以通過(guò)src屬性引入一個(gè)js文件,引入的js文件可以是本地的,也可以是遠(yuǎn)程的,下面我們一起來(lái)看看文章詳細(xì)內(nèi)容2021-11-11Zod進(jìn)行TypeScript類型驗(yàn)證使用詳解
這篇文章主要為大家介紹了Zod進(jìn)行TypeScript類型驗(yàn)證使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09JavaScript國(guó)際化API格式化數(shù)據(jù)Intl.NumberFormat使用講解
這篇文章主要為大家介紹了JavaScript國(guó)際化API格式化數(shù)據(jù)Intl.NumberFormat使用講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06