DOMNodeInserted在body上执行DOM操作时表现得很奇怪

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

      function DOMmanipulation() { if (document.body) { document.removeEventListener('DOMNodeInserted', DOMmanipulation); // DOM manipulation start document.body.innerHTML = '
' + document.body.innerHTML + '
'; // DOM manipulation end } } if (document.addEventListener) { document.addEventListener('DOMNodeInserted', DOMmanipulation); }

Lorem ipsum dolor sit amet.

如您所见,DOM操作是将body所有innerHTML包装到

它确实有效。 但是,发生了一件奇怪的事情。 如果您使用Firebug或Chrome Developer Tool检查被操纵的body ,您会发现添加了一个神秘的元素。 它是:

 

尽管操作成功,但Firebug显示了这个错误:

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

Chrome Developer Tool会显示以下错误:

  • 未捕获错误:NOT_FOUND_ERR:DOMexception8(jquery.min.js第2行)

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

 document.body.className += ' js'; 

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

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

 $('body').wrapInner('
');

然后神秘的元素变得更加奇怪:

 

总之,我们可以看到上述实验中的三个问题:

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

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

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不再是身体的子元素而失败了。

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

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

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