【问题标题】:Listen for HTML elements, without setInterval侦听 HTML 元素,无需 setInterval
【发布时间】:2018-10-04 04:10:58
【问题描述】:

我想知道是否可以在不使用 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?

【问题讨论】:

  • 我向您保证,任何其他检查此 DOM 元素的代码都将以相同的方式运行

标签: javascript jquery


【解决方案1】:

这对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>

【讨论】:

    【解决方案2】:

    这可以使用 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/

    【讨论】:

    • @Katamari 老实说,这是一个非常酷的 hack,在尝试回答这个问题之前我也没有见过它。
    猜你喜欢
    • 2020-03-06
    • 1970-01-01
    • 1970-01-01
    • 2015-11-24
    • 2023-01-19
    • 1970-01-01
    • 2011-08-27
    • 2019-01-29
    • 1970-01-01
    相关资源
    最近更新 更多