前言
閱讀本文你可以獲取到以下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我們可以嘗試在項目中使用,可以極大的提升了工作效率和用戶體驗。碼字不易,如果文章對你有幫助,不要吝嗇你的贊哦👍👍👍,也可以關注我的公衆號一起學習!!!
如果文章讓你有收穫,歡迎關注公衆號,每日推送優質文章!!!