MutationObserver、IntersectionObserver、ResizeObserver

前言

閱讀本文你可以獲取到以下3個知識點
通過原生javascript的API

  • 監聽DOM元素的改變(文字、大小、背景等等)
  • 監聽DOM元素之間是否相交等信息
  • 監聽DOM元素大小改變,基本可以放棄全局監聽window.rize

動動小手,先點贊再觀看😂🤣🤣

MutationObserver

MutationObserver 創建一個觀察器,提供了對監視DOM樹更改的能力,是DOM3 Events規範的一部分

通過這個接口,我們可以輕鬆的實現對DOM 樹變化的監聽了😍

先來看下MutationObserver 都有哪些方法吧

方法 參數 描述
observe(targetNode, config) targetNode:DOM節點
config:監控配置(object)
開啓監聽DOM節點
disconnect() 取消監聽,直到重新調用其observe()方法
takeRecords() 阻止MutationObserver監聽並返回一個MutationRecord數組

這裏config的可選參數有這些(至少寫一項)

{
    childList: true,  // 觀察目標子節點的變化,是否有添加或者刪除
    attributes: true, // 觀察屬性變動
    subtree: true     // 觀察後代節點,默認爲 false
}

看完基本的屬性後,下面來實際操作一下吧👌

<!--html-->
<div id="main">
    <h2>MutationObserver</h2>
    <div id="main2"></div>
</div>
<button id="btn-change">改變文字</button>
<button id="btn-cancel">取消監聽</button>
// javascript
let mainEl = document.querySelector('#main')
let h2El = document.querySelector('#main>h2')
let btnChangeEl = document.querySelector('#btn-change')
let btnCancelEl = document.querySelector('#btn-cancel')

// 實例化MutationObserver,並傳入監聽回調
let observer = new MutationObserver((mutationsList) => {
    console.log('mutationsList:', mutationsList)
    //這裏打印的Dom改變的信息
    // mutationsList:[{type: "attributes", target: h2, addedNodes: NodeList(0), removedNodes: NodeList(0), previousSibling: null, …}]
})

// 設置監聽Dom並配置需要監聽的選項
observer.observe(mainEl, {
    // 需要測試的話,自行配置
    attributes: true,
    childList: true,
    subtree: true
})

btnChangeEl.onclick = () => {
    h2El.style.height = '50px'
    h2El.innerText = '前端Jsoning'

    // const list = observer.takeRecords()
    // console.log('takeRecords:',list) 
    // 需要測試takeRecords方法的小夥伴,打開上面註釋即可。
    // 這裏打印的Dom改變的信息,並切不會進入實例中的回調
    // mutationsList:[{type: "attributes", target: h2, addedNodes: NodeList(0), removedNodes: NodeList(0), previousSibling: null, …}]
}
btnCancelEl.onclick = () => {
    // 取消監聽
    observer.disconnect()
}

以上註釋已經很詳細了,需要測試的小夥伴,自行更改部分設置即可,這裏就不在贅述了🤞

最後,再來看一下 MutationObserver兼容性(反正有polyfill,擔心個🔨)

IntersectionObserver

IntersectionObserver 提供了一種異步觀察目標元素與其祖先元素或頂級文檔視窗(viewport)交叉狀態的方法

這個接口可以監聽到目標元素和祖先元素之間是否相交,通過IntersectionObserver 我們可以實現很多功能,例如懶加載、遊戲裏面的物體碰撞等等🎉

先來看下MutationObserver 都有哪些屬性和方法吧

屬性 參數 描述
IntersectionObserver.root 只讀 所監聽對象的祖先元素,默認爲窗口
IntersectionObserver.rootMargin 只讀 盒子交叉的偏移量,默認值爲’0px 0px 0px 0px’
IntersectionObserver.thresholds 只讀 閥值,0-1之間,監聽目標與邊界盒交叉區域的比例值
方法 參數 描述
observe(clallback, config) clallback: 元素相交超過閥值之後的回調
config: 配置生成MutationObserver實例的參數
監聽目標元素
unobserve(targetNode) targetNode: 取消監聽的元素節點(必傳) 取消監聽特定目標元素
takeRecords() 返回觀察目標的對象數組
disconnect() 停止所有元素的監聽

這裏config的可選參數有這些:

{
    root: '', // 監聽元素的祖先元素
    rootMargin: '', //元素之間交叉的偏移量,默認值爲'0px 0px 0px 0px',
    threshold: '', //閥值,0-1之間,監聽目標與邊界盒交叉區域的比例值,這裏配置會優先滿足閥值後再去驗證rootMargin
    
}

看完基本的屬性後,下面來實際操作一下吧👌

<!--html-->
<style>
#box {
    position: absolute;
    top: 10px;
    left: 10px;
    width: 100px;
    height: 100px;
    background-color: cadetblue;
    animation: animate 5s;
}
#content {
    position: relative;
    width: 400px;
    height: 400px;
    border: 1px solid #f00;
}

@keyframes animate {
    from {
        left: 10px;
    }
    to {
        left: 500px;
    }
}
</style>

 <div id="content">
    <div id="box"></div>
</div>
// javascript

let boxEl = document.querySelector('#box')
let contentEl = document.querySelector('#content')

const options = {
    root: contentEl,
    rootMargin: "10px 10px 10px 10px",
    threshold: 1.0
}
const intersectionObserver = new IntersectionObserver((entries) => {
    console.log(entries)
}, options)

// 開始監聽
intersectionObserver.observe(boxEl);

// 停止監聽一個元素
// intersectionObserver.unobserve(boxEl)

// 停止監聽全部元素
// intersectionObserver.disconnect()

以上註釋已經很詳細了,需要測試的小夥伴,自行更改部分設置即可,這裏就不在贅述了😜

最後,再來看一下 IntersectionObserver 的兼容性(反正有polyfill,擔心個🔨)

ResizeObserver

ResizeObserver 創建一個新的ResizeObserver對象監聽元素大小變化

這個接口可以監聽到元素的變化,以前我們只能通過window.resize來監聽頁面變化,現在有了這個API任何元素都可以監聽,趕腳很強大啊(該API目前還處於實驗性,不過谷歌瀏覽器上目前已經有這個API了)🤳

先來看下ResizeObserver 都有方法吧

方法 參數 描述
observe(clallback, config) clallback: 元素變化之後的回調
config: 配置生成ResizeObserver實例的參數
監聽目標元素
unobserve(targetNode) targetNode: 取消監聽的元素節點(必傳) 取消監聽特定目標元素
disconnect() 停止所有元素的監聽

由於這個API還處於實驗性,config這個參數這裏就不羅列了

看完基本的屬性後,下面來實際操作一下吧👌

<!--html-->
<textarea id="main"></textarea>
// javascript

let mainEl = document.querySelector('#main')
const resizeObserver = new ResizeObserver(entries => {
    console.log(entries)
})

//拉動textarea的大小,即可看到輸出
// 監聽元素大小改變
resizeObserver.observe(mainEl) //ResizeObserverEntry [{target: textarea#main, contentRect:  {x: 2, y: 2, width: 143, height: 43, top: 2, …}}]

// 取消某個元素監聽
//resizeObserver.unobserve(mainEl)

// 取消全部元素監聽
//resizeObserver.disconnect()

最後,再來看一下 ResizeObserver 的兼容性(雖然還處於實驗性有polyfill,擔心個🔨)

總結

可以看到上面3個API,用法基本類似。對於這些較新的API我們可以嘗試在項目中使用,可以極大的提升了工作效率和用戶體驗。碼字不易,如果文章對你有幫助,不要吝嗇你的贊哦👍👍👍,也可以關注我的公衆號一起學習!!!

如果文章讓你有收穫,歡迎關注公衆號,每日推送優質文章!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章