一、js監聽window變化的方法
1、onsize只能監聽window對象的變化
(1)、 window對象原生、jQuery方法
//原生寫法
window.onsize = function(){
console.log("11");
}
//jquery寫法
$(window).resize(function(){
console.log("22");
})
//注意:瀏覽器窗口大小改變時,這段代碼會執行多次,對性能影響大,容易造成瀏覽器假死。
(2)、實現不管窗口怎么改變,只在停止改變之后才執行代碼
var resizeTimer = null;
$(window).resize(function(){
if(resizeTimer){
clearTimeout(resizeTimer);
}
resizeTimer = setTimeout(function(){
console.log("窗口改變")
},100)
})
//通過使用定時器的方式來讓代碼延遲執行,每次窗口改變的時候就清除事件,只有停下改變之后才會繼續再執行,解決resize執行多次的問題。
二、js監聽div容器變化的方法
1、MutationObserver
(1)、介紹: MutationObserver 可以用來監聽整個DOM中的變化。
(2)、構造函數,參數為回調函數
構造函數為window.MutationObserver,它在監聽到DOM中的改變並且一系列改變結束后觸發回調函數。他與事件不同的是:它在DOM變化時,會記錄每一個DOM的變化(為一個MutationRecord對象),到DOM變化結束時觸發回調函數。DOM變化可能是一系列的(比如同時改變寬和高),那么這一系列的變化就會產生一個隊列,這個隊列會作為參數傳遞給回調函數。
由於瀏覽器差異。一些版本的瀏覽器各自支持了構造函數,但是用法一致的。實例化一個觀察者,代碼如下:
let MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; let observer = new MutationObserver(callback);
(3)、常用三個API接口
1️⃣、observe(element,options) 配置MutationObserver在DOM更改匹配給定選項時,通過其回調函數開始接收通知。
element是要監聽的DOM元素,options為監聽選項對象,可選的選項如下:

所以監聽元素寬高變化,就是監聽style屬性變化
observer.observe(element,{attributes:true,attributeFilter:['style'],attributeOldValue:true});
//這樣當元素style發生變化時,就會觸發構造函數中的callback函數。即: let observer = new MutationObserver(callback) ,觸發這里的callback。
2️⃣、 disconnect() 阻止 MutationObserver 實例繼續接收的通知,直到再次調用其observe方法,該觀察者對象包含的回調函數都不會再被調用。
3️⃣、 takeRecords() 從MutationObserver的通知隊列中刪除所有待處理的通知,並將它們返回到一個MutationRecord對象構成的新數組中。
2、vue示例
<template>
<div class="container">
<div class="resize-element">
改變大小試試
</div>
<div class="resize-record">
觸發了{{firedNum}}次resize事件。
</div>
</div>
</template>
<script>
export default {
showName: '監聽DOM變化',
data () {
return {
observer: null,
firedNum: 0,
recordOldValue: { // 記錄下舊的寬高數據,避免重復觸發回調函數
width: '0',
height: '0'
}
}
},
mounted () {
let MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver
let element = document.querySelector('.resize-element')
this.observer = new MutationObserver((mutationList) => {
for (let mutation of mutationList) {
console.log(mutation)
}
let width = getComputedStyle(element).getPropertyValue('width')
let height = getComputedStyle(element).getPropertyValue('height')
if (width === this.recordOldValue.width && height === this.recordOldValue.height) return
this.recordOldValue = {
width,
height
}
this.firedNum += 1
})
this.observer.observe(element, { attributes: true, attributeFilter: ['style'], attributeOldValue: true })
},
beforeDestroyed () {
if (this.observer) {
this.observer.disconnect()
this.observer.takeRecords()
this.observer = null
}
}
}
</script>
<style lang="stylus" scoped>
.container
position relative
.resize-element
transform translate(-50%, -50%)
position absolute
top 50%
left 50%
height 10rem
width 10rem
overflow hidden
resize both
display block
box-shadow 0 0 1px 1px #3361D8
border-radius 2px
</style>
注意:這里記錄了舊的寬高數據來避免重復觸發回調函數,這樣做的原因在於寬高數據改變時,不一定是整數,而MutationRecord.recordOldValue中記錄的是取整后的數據,這樣就會導致在拖動改變DOM元素的寬高時,數值一直在整數和小數之間跳動,會多次觸發。
