32103

DOMNodeInserted behaves weird when performing DOM manipulation on body

Question:

The following code uses DOMNodeInserted to perform DOM manipulation on the body element once it is inserted into the DOM. I know $(document).ready(function { }); is enough to do the job, but I want to test the DOMNodeInserted event.

<!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>

Lorem ipsum dolor sit amet.

</body> </html>

<br /> As you can see, the DOM manipulation is to wrap all innerHTML of body into <div class="wrapper"></div>.

It does work. However, a weird thing happened. If you use Firebug or Chrome Developer Tool to inspect the manipulated body, you can find that there was a mysterious element being added. It is:

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

And despite the success of the manipulation, Firebug shows this error:

<ul><li>Node was not found (jquery.min.js line 2)</li> </ul>

And Chrome Developer Tool shows this error:

<ul><li>Uncaught Error: NOT_FOUND_ERR: DOM Exception 8 (jquery.min.js line 2)</li> </ul>

But if the manipulation is just adding className, there is no error:

document.body.className += ' js';

<br /> The most weird thing is, if you remove the jQuery reference, the event won't work. Does that mean the native DOMNodeInserted event sometimes needs jQuery to work?

<br /> By the way, if the DOM manipulation is using jQuery syntax:

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

Then the mysterious element becomes more weird:

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

To sum up, we can see three issues from the above experiment:

<ul><li>weird element(s) being added</li> <li>an error occurred despite the success of the DOM manipulation</li> <li>DOMNodeInserted sometimes seems to need jQuery to work</li> </ul>

Any explanation would be appreciated. Thanks.

Answer1:

jQuery starts some tests when it has been loaded (line 1537 in the un-minified version)

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

For this it adds a div element with some stylings. That is your mysterious element you've found.

Because of your event handler, this element gets wrapped within another div. At line 1654 jQuery wants to remove their test element with

body.removeChild( container );

which failes because the container isn't a child element of body anymore.

<strong>Edit</strong><br /> In your example you're not adding an element to the DOM so the event can't fire ;)

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

Why it "works" with jQuery? Because jQuery adds an element to the DOM (the mysterious test element) :)

Recommend

  • Fade in/out and pause on mouse over with jQuery
  • How to focus on a particular portion of an another html page when click on a button or link
  • urllib2 returns a different page the browser does?
  • JavaScript Creating array in object and push data to the array
  • jQuery not recognizing Symfony JSON?
  • How to cache images only in disk using Kingfisher?
  • Why do native C++ projects have a TargetFrameworkVersion?
  • How to make Java compiler generate line numbers in compiled code
  • Vim ctags behaves strangely
  • Java, will (low + high) >>> 1 overflow?
  • How to Configure Log4Net Custom Object Renderer for Generic Objects?
  • getElementsByClassName and AJAX
  • Android libgdx prefs getting lost
  • How to fallback to entirely different index page if user has javascript disable?
  • reduce/reduce conflicts using ocamlyacc
  • Best HTML5 structure for a layout where the title/header is outside the article tag
  • Table striping rows in CSS Grid
  • How to make SASS put relative paths in its output
  • How to remove gaps in flexbox?
  • ZipList with Scalaz
  • Click on button in another program - FindWindow, C#
  • get iframe content as string
  • VSCode change debug shell to bash on windows
  • abstracting over a collection
  • Does Apple allow the usage of sysctl.h within iOS applications?
  • ASP.NET MVC 2 Preview 2 - display directory list rather than home/index
  • Is playing sound in Javascript performance heavy?
  • How can I sort a a table with VBA with given text condition?
  • Moving mysql files across servers
  • Chrome doesn't support silverlight anymore? How to solve this?
  • Asynchronous UI Testing in Xcode With Swift
  • If I include Java 8 in my Android app does that affect which devices it will work on?
  • Why is an OPTIONS request sent to the server?
  • Ajax jQuery multiple calls at the same time - long wait for answer and not able to cancel
  • Javascript convert timezone issue
  • R: gsub and capture
  • jqPlot EnhancedLegendRenderer plugin does not toggle series for Pie charts
  • Comma separated Values
  • XCode 8, some methods disappeared ? ex: layoutAttributesClass() -> AnyClass
  • How to load view controller without button in storyboard?