On 2010-07-12 04:13 PM, David Mark wrote:
On 2010-07-06 02:00 PM, khinester wrote:
On 06/07/10 21:23, khinester wrote:
[...]
I've had the problem happen in my own code a long time ago and I when I
wrote that position function, I vaguely remembered it and addressed the
issue by using insertBefore.
Why didn't you just wait until the document was "ready" (i.e. loaded
if you want cross-browser compatibility) before doing your tests.
Problem solved.
Waiting for onload to fire might result in a less desirable U/X. The
consequences might be increased perceived load time, or unresponsiveness
of components, depending on the page, how many images it has, whether or
not there are delegating event handlers and what those handlers do.
Of course, when the context demands it, there are sane methods of
running code before the load event fires (as we've been over a million
times). The typical hacks found in JS libraries do not qualify as
such and predictably cause sporadic Operation Aborted errors. In the
case of Dojo, where every document takes ten years to load, they
decided to keep the Operation Aborted errors rather than eliminating
the cause of the problem or using a sane alternative.
[...]
If Microsoft's explanation can be believed then insertBefore isn't any
better than appendChild.
"What caused the operation aborted error?
The operation aborted dialog in Internet Explorer 7 is triggered by an
HTML parsing exception that occurs when all the following specific
conditions are met:
* The HTML file is being parsed
Script is executing
* The executing script attempts to add, or remove an element from an
unclosed ancestor in the markup tree (not including the script block's
immediate parent element)."
An unclosed ancestor, is that what it says?
Can you read?
Yes, that's what it says.
Is an unclosed parent an unclosed ancestor? Nope.
Who are you arguing with?
MSDN never states that appending to an unclosed *parent* triggers
operation aborted. In fact, it indicates that doing does not trigger
operation aborted.
Again.
And so from this, it can be concluded that operation aborted can be
simply avoided by doing none other than replacing:
par.appendChild(n);
- with -
par.insertBefore(n, par.firstChild);
None of what you just said makes any sense at all. Whether you use
appendChild or insertBefore does not change the element you are
mutating.
The example I posted demonstrates that the theory holds true.
If all you have to justify a pattern are your observations of success
in a handful of browsers, then you have no justification at all.
The explanation should not be difficult to understand.
I don't need you to explain Operation Aborted. I asserted that I
didn't think you grasped the root of the problem, based on your
proposed workaround. That assertion stands.
Any time, under any condition? Ah, no, not any time. The specific
condition was as MS explains it. Aapparently you didn't read it
carefully (or read your own...)
What is wrong with you? Again, whether you use appendChild or
insertBefore, you are *adding* to the same element. As the bit I
pasted indicates (and as you should know anyway), there are other
conditions, but they have nothing to do with the appendChild vs.
insertBefore "argument". Perhaps you are just throwing up gorilla
dust at this point?
You are making statements about me that reflect you.
LOL. I'm not the one with the well-known reading comprehension
problem. Your "I know you are but what am I" retort notwithstanding.
I'm the one that you endlessly irritate with your reading
comprehension problem, especially when you bury simple explanations in
tons of unrelated rubbish due to your inability to grasp what has been
said.
The theory was demonstrated by the example. The theory was based on post
hoc observations of the demonstration itself.
I already explained what causes the error to you. Microsoft already did,
too.
Do you really believe this BS? As stated, I never asked (or needed)
any explanation about Operation Aborted from you or MS.
This is not a post hoc "it worked" derived principle. The theory that
replacing `par.appendChild(newNode)` with `par.insertBefore(newNode,
par.firstChild)` was based on the analysis of the problem.
Nonsense. The "par" element is the same in either case. And if it is
still being parsed...
you have for writing a line of code is that it appears
I see no emprical evidence that using insertBefore as I've proposed
triggers "operation aborted."
Oh God. Show me where it fails?! And on something known to be
sporadic to boot.
Based on the explanation by Microsoft, it shouldn't.
I don't see where you get that, other than your trust that the lack of
insertBefore in their example indicates that it is okay to use.
My example shows
that it does not and given no reason to believe the contrary, the onus
is on you to show that it does.
I'm not the one that is confused. As mentioned, I've never had a
problem as I simply avoid it and therefore have no need to speculate
about it, post test pages, etc.
The reason for using insertBefore over appendChild is to avoid Operation
Aborted.
But that's just your opinion based on empirical observations. You
have no proof at all. Better to understand the underlying
abstraction. Again, don't mutate the DOM before it is ready, period.
That is a serious issue for a web page.
Not mine.
Avoiding that issue
does not say anyting about other issues that may arise regarding
appending while the document is loading.
If you would just take my advice, you could stop worrying about all of
those issues (as well as the test pages).
Does that look like a standard doctype to you?
What you do is irrelevant.
You'd do well to pay attention to what I do.
That is neither funny nor relevant.
It gave me a laugh when I saw it.
Interpreting Microsoft's use of the term "add" to as meaning "uses
appendChild" would not make much sense since they mention innerHTML and
document.write as being causes, would it?
That's my line. You seem to think that it excludes "insertBefore".
That doesn't make much sense, does it?
The explanation provided by
Microsoft ezplains that Operation aborted happens with an unclosed
ancestor and that it does not happen with an unclosed *parent*.
You keep repeating the same thing over and over, which is simply a
regurgitation of the bit I pasted from the MSDN site. Odd as it sheds
no light at all on the subject at hand (appendChild vs. insertBefore).
The Operation aborted dialog is an HTML parser error that is propagated
up to browser UI.
Yes.
The problem and how to avoid it is explained by Microsoft.
A broken record.
If the parser
has parsed up to:
| <body>
| <div> some text <em>blah...
and the script appends to BODY, then the error will occur.
Yes. The BODY is not closed yet. Get it?
The parser is
in a state where it has BODY with an unclosed DIV.
Now I see that you are focusing on scripts that are children of the
body. Of course, that doesn't represent all scripts, nor are they the
norm. For such scripts, the solution is easy: make them the last
element in the body. So whittle down your subset again. If you have
scripts in the body that are not the last element of the body and they
need to add children directly to the body then insertBefore should
help. That's hardly a general rule.
All a waste of time if you ask me. You could simply understand the
general rule that mutating the DOM before it is ready is a bad idea.
And if you must fake DOMContentLoaded for IE, put a SCRIPT at the very
end of the body that then calls functions in other scripts that are
also children of the body. Then you can use appendChild all you like
and not have to wait for the load event.
Now, what if you want to put all of the scripts in the HEAD? For
example, when I tried to explain to the Dojo developers that they
could eliminate their well-known and longstanding Operation Aborted
woes with similar adjustments, one of them asserted that it was "bad"
to put any script in the body and would drive the "progressive
enhancement people" nuts. I don't think I've ever met those people,
but they must have an alternate definition for progressive
enhancement.
You still have to put your "trigger" script (the one that calls your
DOM ready listener) at the very bottom of the body, but use a timeout
if any of the scripts in the head will be mutating the DOM, so as to
let the body finish parsing (just the closing tag is left after the
last script). You should do this because the scripts in the head are
obviously not children of the body, so are not immune to Operation
Aborted. Regardless of whether that is an iron-clad solution or not
(I would recommend the previous one instead where applicable), using
insertBefore in lieu of appendChild wouldn't help any.