简体   繁体   English

我如何知道何时创建DOM元素?

[英]How do I know when a DOM-element is created?

I'm trying to acquire a reference for a specific QUnit DOM-element, as soon as this element is created. 创建此元素后,我正在尝试获取特定QUnit DOM元素的引用。 I can get it by using window.setTimeout , but is there an event-driven way to do it? 我可以使用window.setTimeout来获取它,但是有一种事件驱动的方式来做到这一点吗?

I have tried various approaches, but only the least satisfying ( window.setTimeout ) actually works: 我尝试了各种方法,但是只有最不令人满意的方法( window.setTimeout )才有效:

window.onload = function() {
    var qunitTestrunnerToolbar_element = document.getElementById("qunit-testrunner-toolbar");
    console.log("from window.onload: qunitTestrunnerToolbar_element: ", qunitTestrunnerToolbar_element);
};

returns null 返回null

document.addEventListener("DOMContentLoaded", function(event) {
   var qunitTestrunnerToolbar_element = document.getElementById("qunit-testrunner-toolbar");
    console.log("from document.addEventListener(DOMContentLoaded): qunitTestrunnerToolbar_element: ", qunitTestrunnerToolbar_element);
});

returns null 返回null

document.addEventListener("load", function(event) {
    var qunitTestrunnerToolbar_element = document.getElementById("qunit-testrunner-toolbar");
    console.log("from document.addEventListener(load): qunitTestrunnerToolbar_element: ", qunitTestrunnerToolbar_element);
});

is never executed 永远不会执行

window.setTimeout(function() {
    var qunitTestrunnerToolbar_element = document.getElementById("qunit-testrunner-toolbar");
    console.log("from window.setTimeout: qunitTestrunnerToolbar_element: ", qunitTestrunnerToolbar_element);
}, 2000);

returns the DOM-reference 返回DOM引用

The code can be befiddled at this jsfiddle . 可以在此jsfiddle中添加代码。 Note that the fiddle only logs the one successful DOM-reference. 请注意,小提琴仅记录一个成功的DOM引用。 The others are somehow silenced. 其他人则无声无息。

This is how it looks when executed locally: 这是在本地执行时的外观:

在此处输入图片说明

There is the DOMMutationObserver , which allows you to subscribe to changes to the DOM. 有一个DOMMutationObserver ,它允许您订阅对DOM的更改。

var mutationObserver = new MutationObserver(function(mutations) {
      mutations.forEach(function(mutation) {
        var id = 'qunit-testrunner-toolbar',
            added = mutation.addedNodes,
            removed = mutation.removedNodes,
            i, length;

        for (i = 0, length = added.length; i < length; ++i) {
          if (added[i].id === id) {
            //  qunit-testrunner-toolbar was added
          }
        }

        for (i = 0, length = removed.length; i < length; ++i) {
          if (removed[i].id === id) {
            //  qunit-testrunner-toolbar was removed
          }
        }
      });
    });

mutationObserver.observe(target, {childList: true});

If you need to stop listening for changes (as the amount of changes to the DOM can be huge ;) ), you can simply use mutationObserver.disconnect() . 如果您需要停止监听更改(因为DOM的更改量可能很大;)),则可以简单地使用mutationObserver.disconnect()

If the #qunit-testrunner-toolbar is not the node that is added (but instead is part of another structure), the checks above will not work. 如果#qunit-testrunner-toolbar不是添加的节点(而是其他结构的一部分),则上述检查将不起作用。 If that is the case you can replace the added[i].id === id with something like 如果是这种情况,您可以使用类似以下内容的方法来替换added[i].id === id

if (added[i].querySelector('#qunit-testrunner-toolbar')) {
  // it was added
}

I should at least mention the now deprecated Mutation Events , which seem more convenient to implement but were pretty slow and inaccurate. 我至少应该提到现在已弃用的Mutation Events ,它似乎更易于实现,但速度缓慢且不准确。

document.addEventListener('DOMNodeInserted', function(e) {
  if (e.target.id === 'qunit-testrunner-toolbar') {
  }
});

Tempting to use, but don't as it is deprecated. 诱人使用,但不要使用,因为它已被弃用。

Everything you put in JSFiddle's javascript is already wrapped in onload event (so window.onload will never be fired again - it is already fired). 您在JSFiddle的javascript中放入的所有内容都已经包装在onload事件中(因此window.onload将不再被触发-它已经被触发)。 Change it to "Javascript" -> "Load time" -> "No wrap - in <head>" and you will get all of your events fired. 将其更改为“ Javascript”->“ Load time”->“ No wrap-in <head>”,您将触发所有事件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM