Reputation: 2457
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>
<p>Lorem ipsum dolor sit amet.</p>
</body>
</html>
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:
And Chrome Developer Tool shows this error:
But if the manipulation is just adding className, there is no error:
document.body.className += ' js';
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?
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:
DOMNodeInserted
sometimes seems to need jQuery to workAny explanation would be appreciated. Thanks.
Upvotes: 0
Views: 1338
Reputation: 21881
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.
Edit
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) :)
Upvotes: 2