js 檢測元素的寬度或高度變化


一、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元素的寬高時,數值一直在整數和小數之間跳動,會多次觸發。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM