0

以下代码用于在元素插入DOM 后对元素DOMNodeInserted执行 DOM 操作。body我知道$(document).ready(function { });足以完成这项工作,但我想测试该DOMNodeInserted事件。

<!DOCTYPE html>
<html lang="en">
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script>
        function DOMmanipulation() {
            if (document.body) {
                document.removeEventListener('DOMNodeInserted', DOMmanipulation);
                // DOM manipulation start
                document.body.innerHTML = '<div class="wrapper">' + document.body.innerHTML + '</div>';
                // DOM manipulation end
            }
        }
        if (document.addEventListener) {
            document.addEventListener('DOMNodeInserted', DOMmanipulation);
        }
    </script>
</head>
<body>
    <p>Lorem ipsum dolor sit amet.</p>
</body>
</html>


如您所见,DOM 操作是将所有innerHTML内容包装body<div class="wrapper"></div>.

它确实有效。然而,奇怪的事情发生了。如果您使用 Firebug 或 Chrome 开发者工具检查被操纵的body,您会发现添加了一个神秘的元素。这是:

<div style="padding: 0px; margin: 1px 0px 0px; border: 0px none; visibility: hidden; width: 0px; height: 0px; position: static; top: 0px;"></div>

尽管操作成功,但 Firebug 仍显示此错误:

  • 未找到节点(jquery.min.js 第 2 行)

Chrome 开发人员工具显示此错误:

  • 未捕获的错误:NOT_FOUND_ERR:DOM 异常 8(jquery.min.js 第 2 行)

但如果操作只是添加className,则没有错误:

document.body.className += ' js';


最奇怪的是,如果您删除 jQuery 引用,该事件将不起作用。这是否意味着本机DOMNodeInserted事件有时需要 jQuery 才能工作?


顺便说一句,如果 DOM 操作使用 jQuery 语法:

$('body').wrapInner('<div class="wrapper"></div>');

然后神秘元素变得更加诡异:

<div style="padding: 0px; margin: 1px 0px 0px; border: 0px; visibility: hidden; width: 0px; height: 0px; position: static; top: 0px; zoom: 1; ">
    <div style="position: absolute; top: 0px; left: 0px; width: 1px; height: 1px; padding: 0px; margin: 1% 0px 0px; border: 0px; visibility: hidden; ">
        <div style="position: relative; top: 0px; left: 0px; width: 1px; height: 1px; padding: 0px; margin: 0px; border: 5px solid rgb(0, 0, 0); display: block; overflow: hidden; ">
            <div style="padding: 0px; margin: 0px; border: 0px; display: block; overflow: hidden; "></div>
        </div>
        <table style="position:absolute;top:0;left:0;width:1px;height:1px;padding:0;margin:0;border:5px solid #000;" cellpadding="0" cellspacing="0"><tbody><tr><td></td></tr></tbody></table>
    </div>
</div>



综上所述,我们可以从上面的实验中看出三个问题:

  • 添加了奇怪的元素
  • 尽管 DOM 操作成功,但仍发生错误
  • DOMNodeInserted有时似乎需要 jQuery 才能工作

任何解释将不胜感激。谢谢。

4

1 回答 1

2

jQuery 在加载后开始一些测试(未缩小版本中的第 1537 行)

// Run tests that need a body at doc ready
jQuery(function() {
var container, outer, inner, table, td, offsetSupport,
...

为此,它添加了一个div带有一些样式的元素。那是你mysterious找到的元素。

由于您的事件处理程序,此元素被包装在另一个div. 在第 1654 行,jQuery 想要删除他们的测试元素

body.removeChild( container );

失败是因为container不再是 body 的子元素。

编辑
在您的示例中,您没有向 DOM 添加元素,因此事件无法触发;)

window.onload = function() {
    document.body.appendChild(document.createElement("div"));  // will fire DOMNodeInserted
}

为什么它与 jQuery 一起“工作”?因为 jQuery 向 DOM 中添加了一个元素(神秘的测试元素):)

于 2012-07-10T05:53:45.477 回答