DOM 加载和纯 HTML 添加

3
通常情况下,当我想在页面的DOM完全加载后执行一些代码(99%的情况是初始化代码)时,我会使用domReady()函数(无论是jQuery的还是手动编写的)。

现在,我需要将一些HTML模板附加到DIV元素中,但之后我需要获取添加到其中的一些元素并对它们进行操作(更改文本、附加事件、设置验证消息和掩码等)。

div.innerHTML += htmlTemplate; // Template which has the "someInput" input
var someInput = document.getElementById('someInput');

事情是这样的:可以安全地假设input已加载到DOM中吗?在我将HTML附加到DIV之后,是否必须将依赖于新DOM元素的代码作为回调发送到domReady函数?
div.innerHTML += htmlTemplate;
domReady(function(){
    var someInput = document.getElementById('someInput');
    // ...
});

就技术而言...每次向元素添加纯HTML时,DOM都会进入加载状态吗?

-- 编辑

这是我正在使用的domReady()函数:

function domReady(f) {
    /in/.test(document.readyState) ? setTimeout('domReady('+f+')', 9) : f();
}

PS:我需要一个简单/短/不依赖API的函数,所以我在一段时间前在SE上找到了这个。

提前致谢。


DOM事件“load”仅在第一次加载时触发一次。更多信息:http://www.w3.org/TR/DOM-Level-3-Events/#event-type-load - Uncle Aaroh
实际上,我当前的“domReady()”函数依赖于文档的就绪状态... 我会将其添加到问题中。 - everton
请查看Event developer guide MDN - Givi
我不明白...我是否需要为我添加HTML的DIV添加“ready”事件处理程序? - everton
像这样附加HTML(innerHTML += more_stuff;)会导致浏览器重新解析受影响容器的所有内容。 这不是最有效的方法。 - Pointy
由于此容器在那时是空的,我猜这应该不是问题。 - everton
3个回答

4
每次添加纯HTML元素时,DOM是否会进入加载状态?
不会。在“innerHTML=”调用结束后,您可以确信元素已经存在。请查看this jsbin,我使用“innerHTML”花费了1秒钟添加
  • 元素,并使用“ .querySelectorAll”检查以前的元素是否存在。
    设置 element.innerHTML 是同步的:浏览器停止正在进行的工作,以相应地更新DOM(这并不意味着页面已视觉化更新,如所链接示例所示),并且控制权直到完成后不返回您的代码。

    在已分离的DOM节点中进行操作的示例:

    var tempDiv = document.createElement("div");
    tempDiv.innerHTML = getTemplateSomehow();
    
    // Manipulate a button inside the template,
    // even though it is not in the DOM yet
    var button = tempDiv.querySelector("button");
    button.style.color = "red";
    button.addEventListener("click", function() {
      alert("button clicked");
    });
    
    // Append all children from the parsed template into the DOM
    var child;
    var target = document.body;
    
    // Keep moving tempDiv's children to the target until it is empty
    while(child = tempDiv.firstChild) {
      target.appendChild(child);
    }
    

    工作示例:http://jsbin.com/isuLeMi/1/edit


  • 谢谢!我在哪里可以找到确认(文档),证明element.innerHTML附加是与DOM加载同步的? - everton
    我很担心因为我要添加的模板可能很大,如果我依赖未加载的元素,可能会发生奇怪的事情。你有什么想法来测试这个吗? - everton
    也许你可以尝试一个类似于我的测试,但是使用更大的模板...作为替代方案,你可能想在一个分离的DOM节点上进行操作,以帮助浏览器更高效地执行操作。你能否在问题中添加一些你需要进行的转换类型的示例? - Renato Zannon
    你不用jQuery吗?好勇敢啊 :) 我加了一个小例子,请看一下 - Renato Zannon
    1
    你只需要将倒数第二行的 document.body 更改为你的 div。 - Renato Zannon
    显示剩余5条评论

    0
    如果你在domReady中谈论onload事件,那么这个事件只会在页面生命周期中触发一次,当文档被浏览器完全加载时。要观察特定的元素,你需要为这些元素添加'change'监听器。

    当用户提交元素值的更改时,<input>、<select>和<textarea>元素会触发change事件。与input事件不同,change事件并不一定会在每次元素值更改时都被触发。 - Givi
    抱歉,我不明白它如何适用于这种情况。 - everton

    0
    事实是,当 JavaScript 运行时,浏览器会停止执行任何东西。这意味着当您添加一个带有 id "Example" 的 div 时,您无法在同一事件中访问它。
    然而,在我看来,有一个干净的解决方法:
    通过
    window.setTimout(func, 0); 执行访问动态创建内容的代码部分。
    这允许浏览器执行其他任务(如渲染、DOM 编辑等),并在浏览器完成工作队列后立即执行访问代码。

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接