侦听HTML元素,而无需setInterval

时间:2018-10-03 19:46:00

标签: javascript jquery

我想知道是否可以像现在正在使用setInterval一样监听DOM中的元素:

var interval = setInterval(() => {
  var div = document.querySelector('.test');
  if (div != null) {
    clearInterval(interval);
    console.log(div);
  }
}, 1000);

我的问题是,此特定div会在10-12分钟后随机加载到DOM中。 而且我认为setInterval我只是一个丑陋的解决方案。所以我的问题是,甚至可以在不使用间隔的情况下监听DOM中的新div?

2 个答案:

答案 0 :(得分:3)

这对Mutation Observer来说似乎是一项好工作。它将在您的DOM上观察到一个静态父对象,并警告您结构的任何更改。您可以侦听要添加的类test的子节点。例如:

// this setTimeout is only to show this example working. it is not needed 
setTimeout(() => {
  let aDiv = document.createElement('div');
  aDiv.className = 'test';
  document.getElementById('parent').appendChild(aDiv);
}, 3000);

let targetNode = document.getElementById('parent');

let config = {
  attributes: false,
  childList: true,
  subtree: true
};

// Callback function to execute when mutations are observed
let callback = function(mutationsList, observer) {
  for (let mutation of mutationsList) {
    if (mutation.type == 'childList') {
      for (let node of mutation.addedNodes) {
        if (node.className === "test") {
          console.log("a node with class test was added!");
          // stop observing
          observer.disconnect();
        }
      }
    }
  }
};

// Create an observer instance linked to the callback function
let observer = new MutationObserver(callback);

// Start observing the target node for configured mutations
observer.observe(targetNode, config);
<div id="parent">

</div>

答案 1 :(得分:1)

这可以通过CSS关键帧动画来实现。

Javascript:

(function(){

    var count = 1,
    event = function(event){
        if (event.animationName == 'nodeInserted')
     event.target.textContent = 'Element ' + count++ + ' has been parsed!';
    }

    document.addEventListener('animationstart', event, false);
    document.addEventListener('MSAnimationStart', event, false);
    document.addEventListener('webkitAnimationStart', event, false);

    // this is test code which imitates your div being created
    // after a delay
    setTimeout(function(){
        var div = document.createElement('div');
        div.setAttribute('class', 'some-control');

        document.getElementById('test').appendChild(div)
    }, 2000);

})();

CSS:

    @keyframes nodeInserted {  
        from {  
            outline-color: #fff; 
        }
        to {  
            outline-color: #000;
        } 
    }

    @-moz-keyframes nodeInserted {  
        from {  
            outline-color: #fff; 
        }
        to {  
            outline-color: #000;
        }  
    }

    @-webkit-keyframes nodeInserted {  
        from {  
            outline-color: #fff; 
        }
        to {  
            outline-color: #000;
        }  
    }

    @-ms-keyframes nodeInserted {  
        from {  
            outline-color: #fff; 
        }
        to {  
            outline-color: #000;
        } 
     }

    @-o-keyframes nodeInserted {  
        from {  
            outline-color: #fff; 
        }
        to {  
            outline-color: #000;
        }  
    } 

    div.some-control {
        padding: 50px;
        background: #FF6A6A;
        animation-duration: 0.01s;
        -o-animation-duration: 0.01s;
        -ms-animation-duration: 0.01s;
        -moz-animation-duration: 0.01s;
        -webkit-animation-duration: 0.01s;
        animation-name: nodeInserted;
        -o-animation-name: nodeInserted;
        -ms-animation-name: nodeInserted;        
        -moz-animation-name: nodeInserted;
        -webkit-animation-name: nodeInserted;
    }

    div.some-control div.some-control {
        background: #87CEFF;
    }

信用至:http://www.backalleycoder.com/2012/04/25/i-want-a-damnodeinserted/