使用JS监听DOM元素的属性及动画、CSS过渡

这里我们要是用的JS的api,MutationObserver,进行监听DOM元素的监听

注意:MutationObserver如果用来监听宽高等,只能监听其内部属性,比如style中的width属性,无法监听class中的width改变
如果想要监听动画或者CSS过渡事件,MutationObserver是无法监听到的,可以使用addEventListener中的监听方法

监听动画或CSS过渡


<style>
  #demo{
    width:200px;
    transition: width 0.5s ease-out;
  };
  #demo:hover{
    width:0;
  }
</style>

<div id='demo'>我是DEMO</div>

var element = document.getElementById('demo')
//监听过渡完成transitionend    监听动画完成animationend
element.addEventListener('transitionend', handle, false)
function handle(){
    console.log('css事件过渡效果完成');
}

注意:元素从display:none 到block opacity从0到1,无法触发过渡效果。
无法触发过渡效果原因:
元素从none到block,刚生成未能即时渲染,导致过渡失效。所以需要主动触发页面重绘,刷新DOM。
页面重绘可以通过改变一些CSS属性来触发,例如:offsetTop、offsetLeft、offsetWidth、scrollTop等。

使用MutationObserver监听DOM属性

配置MutationObserver

MutationObserver使用示例

<template>

  <div class="container">
    <div class="resize-element">
      改变大小试试
    </div>
    <div class="resize-record">
      触发了{{firedNum}}次resize事件。
    </div>
  </div>
</template>

<script>
  export default {
    name: "test",
    data () {
      return {
        observer: null,
        firedNum: 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')
        console.log(width)
        this.firedNum += 1;
      })
      this.observer.observe(element, { attributes: true, attributeFilter: ['style'], attributeOldValue: true })
    },
    beforeDestroyed () {
      // disconnect()  阻止 MutationObserver 实例继续接收的通知,直到再次调用其observe方法,该观察者对象包含的回调函数都不会再被调用。
      // takeRecords() 从MutationObserver的通知队列中删除所有待处理的通知,并将它们返回到一个MutationRecord对象构成的新数组中。

      //销毁DOM监听
      if (this.observer) {
        this.observer.disconnect()
        this.observer.takeRecords()
        this.observer = null
      }
    }
  }
</script>

<style scoped>
  .container{
    position:relative
  }
  .resize-element{
    position: absolute;
    top :50%;
    left :50%;
    height: 10rem;
    width :10rem;
    overflow: hidden;
    /*通过resize属性改变DOM中的style,或者直接使用js更改Style*/
    resize :both;
    display :block;
    box-shadow: 0 0 1px 1px #3361D8;
  }
</style>
posted @ 2021-02-13 09:37  爱代码三千  阅读(2287)  评论(0编辑  收藏  举报