Side navigation
#12066 closed bug (duplicate)
Opened July 12, 2012 08:07AM UTC
Closed July 12, 2012 12:50PM UTC
Last modified July 12, 2012 01:18PM UTC
body.removeChild( container ); is unreliable and can cause an error
Reported by: | Ian Yang <ian.html@gmail.com> | Owned by: | |
---|---|---|---|
Priority: | undecided | Milestone: | None |
Component: | unfiled | Version: | 1.7.2 |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description
An answer of a question on stackoverflow shows that when jQuery has been loaded, it performs some background tests by adding an elements (the outmost one is container
) into the body
.
The following code on line 1537 of jQuery un-minified version shows the addition of the container
:
// Run tests that need a body at doc ready jQuery(function() { var container, outer, inner, table, td, offsetSupport, ...
And at line 1654 jQuery wants to remove the container
with:
body.removeChild( container );
However, by using the DOMNodeInserted
event, all contents of body
(including the container
added by jQuery) are always able to be wrapped inside another element before jQuery can remove the container
, causing body.removeChild( container );
to fail because the container
isn't a child element of body
anymore.
Not only the execution of the DOMNodeInserted
event is faster than the removal of the container
, but the following approach which utilizes both the CSS3 animation and the Javascript animationstart
event to achieve DOM manipulation can sometimes make the same jQuery error occurs.
<!DOCTYPE html> <html lang="en"> <head> <style> @-webkit-keyframes nodeInserted { 50% { opacity: 0.99 } } @-moz-keyframes nodeInserted { 50% { opacity: 0.99 } } @-ms-keyframes nodeInserted { 50% { opacity: 0.99 } } @-o-keyframes nodeInserted { 50% { opacity: 0.99 } } @keyframes nodeInserted { 50% { opacity: 0.99 } } body { -webkit-animation-duration: 1ms; -moz-animation-duration: 1ms; -ms-animation-duration: 1ms; -o-animation-duration: 1ms; animation-duration: 1ms; -webkit-animation-name: nodeInserted; -moz-animation-name: nodeInserted; -ms-animation-name: nodeInserted; -o-animation-name: nodeInserted; animation-name: nodeInserted; } </style> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script> function insertListener(event) { if (event.animationName == 'nodeInserted') { // DOM manipulation start document.body.innerHTML = '<div class="wrapper">' + document.body.innerHTML + '</div>'; // DOM manipulation end } } document.addEventListener('webkitAnimationStart', insertListener); document.addEventListener( 'MSAnimationStart', insertListener); document.addEventListener( 'OAnimationStart', insertListener); document.addEventListener( 'animationstart', insertListener); </script> </head> <body> <p>Lorem ipsum dolor sit amet.</p> </body> </html>
As of this time (2012-07-12), Firefox 13 has 33% chance to be faster than the removal of the container
to have this error occurs. And other browsers' performance might be improved in the future and then they might have the same error occurs on them.
The above mentioned two experiments indicate that the use of body.removeChild( container );
is unreliable and can cause an error. It will be safer to change the code into the following one or something better.
jQuery( container ).remove();
Attachments (0)
Change History (4)
Changed July 12, 2012 12:50PM UTC by comment:1
resolution: | → duplicate |
---|---|
status: | new → closed |
Changed July 12, 2012 01:17PM UTC by comment:3
Replying to [comment:2 dmethvin]:
Duplicate of #12047.
Is it because I mentioned the DOMNodeInserted
event which was mentioned in another ticket that you thought this ticket is duplicate and should be closed?
In this ticket, I also mentioned a new thing: the use of CSS3 animation and the Javascript animationstart
event which can result in the same error. And you didn't advise on it. Could you please advise?