js怎么监听元素属性变化

橙子呀
  • 176

原生js监听dom元素的属性值的变化,如果监测的目标属性发生变化。执行特定语句。
监听Dom元素的Style内部的某个特定的属性,例如display,默认为none,修改为inline时触发事件

思路:

1.Object.defineProperty
   set,get
2.Mutation Observer API
 
 
 

发生的问题:

1.defineProperty监测的目标是对象,Dom元素的属性集合[dom.attributes]也为对象{}。attributes对象是所有的属性集合的对象,style是属性集合里下属的集合,因为style的参数多。

问题:把dom.attributes当做对象监测集合下的style,当style发生改变的时候触发Set方法内的语句。但是测试的时候,当图片的display的值发生改变时,set无触发,经测试Object.defineProperty无反应。

    var m=document.getElementById("m").attributes; //对象{}
    Object.defineProperty(m,'style',{
        get:function () {
            console.log('get:'+m.style);
            return m.style.display;
        },
        set:function (v) {
            console.log('set:修改后的值'+v);
            m.alt='图片';
        }
    })

2.Mutation Observer API它等待所有脚本任务完成后,才会运行(即异步触发方式),不知道能不能实时触发修改。

回复
阅读 24.7k
2 个回答

我觉得MutationObserver可以用啊,正常情况下,这个等待DOM操作结束再执行的异步回调没什么问题吧。什么业务实时性要那么高啊? 一般一个事件里面同步的不会有同个属性改来改去的情况(有这种情况优化代码更好),如果是异步的,那MutationObserver也会异步调用,倒没什么问题

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title></title>
</head>
<body>
<div id="test" style="position: relative;" onclick="clickMe()">test</div>
<script type="text/javascript">
    var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
    var element = document.querySelector('#test');
    var observer = new MutationObserver(function(mutations) {
      mutations.forEach(function(mutation) {
        if (mutation.type == "attributes") {
          console.log('mm', new Date().getTime()) 
          console.log("attributes changed", mutation.attributeName)
        }
      });
    });

    observer.observe(element, {
      attributes: true //configure it to listen to attribute changes
    });
    
    function clickMe(){
      console.log('111', new Date().getTime())
      element.style.left = Math.random()* 10  + 'px';
      console.log('222', new Date().getTime())
      element.style.left = Math.random()* 10  + 'px';
      setTimeout(function(){
        console.log('333-timeout', new Date().getTime())
        element.style.left = Math.random()* 10  + 'px';
      }, 2000)

      console.log('click-end')
    }
</script>
</body>
</html>
宣传栏