innerHTML doesn't work on IE?

B

beegee

Since appending a documentFragment to another node only appends the
childnodes of the fragment. With another type of parentnode one has to
iterate through the childnodes and append it one by one to the new
parentnode.

Right, I understand what documentFragments do but my point is that
their very existence goes to indicating that the DOM is rendered as
it's created. Jorge's point about FPS rates going up when you're
creating a DOM tree under a display:none element also goes to point to
the same thing. However, as valid as I believe my point is,
documentFragments and display:none trees are both excellent ways to
get around the table re-render problem.

So thanks. I use both innerHTML and DOM methods where I think it
appropriate. I'm sorry but your point about speed:
And all the
speed gain is lost, when you have to address nodes in the freshly
created fragment


is almost lost on me. Unless you're keeping nodes around in your own
copy of the DOM, the only way to access DOM is getElementById(") no
matter how the DOM tree is created. In my experience looping through
DOM heirarchies to access nodes is unreadable and unmaintainable. It
is reason XPATHs were invented for XML (or if it isn't, it should have
been). If you're talking about accessing the nodes immediately after
you create them, then sure, but in most cases you can configure table
nodes as or more easily using html

Bob
 
J

Jorge

Right, I understand what documentFragments do but my point is that
their very existence goes to indicating that the DOM is rendered as
it's created.

Define "render"... ?
Jorge's point about FPS rates going up when you're
creating a DOM tree under a display:none element also goes to point to
the same thing.

No. Just the opposite. It's not rendered when display: is "none".

I've added a visibility: toggle button. The table is refreshed faster
with display:"none" than with visibility:"hidden": <http://
jorgechamorro.com/cljs/014/>
 
B

beegee

Define "render"... ?

render = drawn. Either onscreen or in an offscreen buffer.
No. Just the opposite. It's not rendered when display: is "none".

I've added a visibility: toggle button. The table is refreshed faster
with display:"none" than with visibility:"hidden": <http://
jorgechamorro.com/cljs/014/>


Yes, yes. I got it. I really do. My point is that, great, you've
pointed out a work-around to the problem. And my point that *unless*
you do specify display:none to the containing element, subsequent
inserts and appends *will* be rendered, whether they are attached to
the body or not. They will not be shown as the DOM does not know
where to put them yet but they will be rendered in the context of the
table.

Your example does not disprove this.

Bob
 
J

Jorge

Yes, yes.  I got it.  I really do. My point is that, great, you've
pointed out a work-around to the problem.  And my point that *unless*
you do specify display:none to the containing element, subsequent
inserts and appends *will* be rendered, whether they are attached to
the body or not.  They will not be shown as the DOM does not know
where to put them yet but they will be rendered in the context of the
table.

Your example does not disprove this.

Now it does :)

(press the 3rd button)

<http://jorgechamorro.com/cljs/014/>
 
G

Gregor Kofler

beegee meinte:
On Jan 11, 4:08 am, Gregor Kofler <[email protected]> wrote:
So thanks. I use both innerHTML and DOM methods where I think it
appropriate. I'm sorry but your point about speed:



is almost lost on me. Unless you're keeping nodes around in your own
copy of the DOM, the only way to access DOM is getElementById(") no
matter how the DOM tree is created. In my experience looping through
DOM heirarchies to access nodes is unreadable and unmaintainable.

getElementsByTagName(), getElementsByName() and in some browsers
getElementsByClassName() natively exist. And since "looping through
DOM heirarchies to access nodes is unreadable and unmaintainable" (and
inefficient) it is much smarter to store element references upon creation.

Anyway, for an example see my XHR-Tree here
http://dev.gregorkofler.com/index.php?page=tree

I permamently have to append and or remove nodes, and I permanently have
to access nodes in the tree, and except from one instance (a gEBCN())
all the node references are stored and directly accessed. The tree is
created with DOM methods and at the same time the later required
references are stored. As for speed: The tree gets created once - which
might give some speed advantage. Alas, I suppose it gets much more often
opened and closed and without element references the overall speed loss
is much worse.

Gregor
 
G

Gregor Kofler

beegee meinte:
And my point that *unless*
you do specify display:none to the containing element, subsequent
inserts and appends *will* be rendered, whether they are attached to
the body or not. They will not be shown as the DOM does not know
where to put them yet but they will be rendered in the context of the
table.

Where does this insight stem from? Since I can't imagine what a browser
should render if something is not not attached to the body.

Gregor
 
R

RobG

I think that assumption is completely unsupported. The purpose of a
document fragment is to provide a generic element to attach a bundle
of nodes to. It means you don't have to worry about adding TRs to a
table section, or TDs to a TR and so on, you just build the bit of
tree that you want and attach it to an appropriate location in the
DOM.
render = drawn.  Either onscreen or in an offscreen buffer.

Jorge's example only shows that it is faster if you don't render the
table at all. It also shows browsers are clever enough not to bother
trying to render elements with display:none.


I don't think the actual creation time is affected at all. It's
reasonable to assume that the *total* time will be faster if the table
is never displayed. If you create the table with display:none, then
change to display:'' and add it to the document, it takes about the
same time as if you'd created it with display:'' from the start. That
indicates to me that it is only rendering the table once, at the end,
regardless of what the display property is set to during construction
of the table.


I don't follow. If display is none, then the table isn't rendered so
of course it's faster, the browser didn't have to render it at all.
How can the browser render a table that isn't part of the DOM yet? It
might be set to position absolute, or placed anywhere in the DOM, or
various other elements added, and so on. The browser would be simply
wasting time to attempt any kind of rendering until the table is
actually added to the DOM.


Of course, because with visibility:hidden, the browser must still make
room for the invisible table, even though it doesn't have to draw it.
If you want to test whether *building the table* takes more or less
time, measure the time it takes to build the table with display:''
*before* adding it to the document.
Yes, yes.  I got it.  I really do. My point is that, great, you've
pointed out a work-around to the problem.  And my point that *unless*
you do specify display:none to the containing element, subsequent
inserts and appends *will* be rendered, whether they are attached to
the body or not.

No, it proves nothing of the sort. How does the browser know that the
"containing element" is until the table is added to the DOM?
 They will not be shown as the DOM does not know
where to put them yet but they will be rendered in the context of the
table.

That makes no sense to me. If you set the table to display:none, it
isn't rendered at all. If you don't set it to display:none, the table
is built (probably in exactly the same time) and at the end, when you
attach it to the document, it is rendered. Clearly that will take
longer than if you don't render it at all.
Your example does not disprove this.

Stay away from double negatives, they are quite confusing. It clearly
shows that if the table has display:none, it isn't rendered at all.
It doesn't prove that it is rendered anew after each append.
 
B

beegee

No, it proves nothing of the sort. How does the browser know that the
"containing element" is until the table is added to the DOM?

Uh, document.createElement() ? After this call, the element is now
part of the DOM.

That makes no sense to me. If you set the table to display:none, it
isn't rendered at all. If you don't set it to display:none, the table
is built (probably in exactly the same time) and at the end, when you
attach it to the document, it is rendered. Clearly that will take
longer than if you don't render it at all.


Okay. Look, Jorge, Gregor, and you have gotten far away from my
original assertion.
Here is a sample, proving the basic assertion that innerHTML is much
(as in twice as fast) faster than using DOM creation methods for large
tables if you create the table from the outside-in. The table in the
sample is actually pretty small (I deal with 10000 row tables in my
job). Step through it and you will see that pointers and arrays are
filled in as the elements are created and more importantly, each
element's parent's elements are adjusted. I cannot determine whether
relative rectangles are being filled in.

http://www.elavatar.com/tableinsert.html
(tested in FF 3.0.5 macintosh)

Stay away from double negatives, they are quite confusing. It clearly
shows that if the table has display:none, it isn't rendered at all.
It doesn't prove that it is rendered anew after each append.

My sentence is not a double negative. I'm not sure how it could have
been more clear. Suggestions?


Bob
 
T

Thomas 'PointedEars' Lahn

beegee said:
Uh, document.createElement() ? After this call, the element is now
part of the DOM.

Strictly speaking, `document' (as an implementation of the
HTML:
Document
interface of W3C DOM Level 2+ Core/2 HTML) and `document.createElement' (as
an implementation of [HTML]Document::createElement()) are part of the DOM
API.  The element object created with this method is _not_ part of the
*document tree* until it is added to a parent node as child node.

So, loosely speaking, you are mistaken.
[QUOTE]
My sentence is not a double negative.  I'm not sure how it could have
been more clear.  Suggestions?[/QUOTE]

You could have made a non-fallacious argument in the first place.  *You*
must prove that you are *right*; others do _not_ need to prove that you are
wrong.


PointedEars
 
G

Gregor Kofler

beegee meinte:
Okay. Look, Jorge, Gregor, and you have gotten far away from my
original assertion.
Here is a sample, proving the basic assertion that innerHTML is much
(as in twice as fast) faster than using DOM creation methods for large
tables if you create the table from the outside-in. The table in the
sample is actually pretty small (I deal with 10000 row tables in my
job). Step through it and you will see that pointers and arrays are
filled in as the elements are created and more importantly, each
element's parent's elements are adjusted. I cannot determine whether
relative rectangles are being filled in.

http://www.elavatar.com/tableinsert.html
(tested in FF 3.0.5 macintosh)

Erm (first figure is always innerHTML)...
FF 3.0.5 (Linux 64bit)
144 vs. 167, 132 vs. 156. 120 vs. 160. 105 vs. 141. Impressive.

But wait:
Midori/WebKit
45 vs. 41. 44 vs. 44. 39 vs. 43. 54 vs. 48... Do I need to go on?

As I mentioned somewhere up the thread: innerHTML might be slightly
faster. Once you have to get references to some table cells, any
advantage is most likely lost.

Gregor
 
J

Jorge

Okay.  Look, Jorge, Gregor, and you have gotten far away from my
original assertion.
Here is a sample, proving the basic assertion that innerHTML is much
(as in twice as fast) faster than using DOM creation methods for large
tables if you create the table from the outside-in.  The table in the
sample is actually pretty small (I deal with 10000 row tables in my
job).  Step through it and you will see that pointers and arrays are
filled in as the elements are created and more importantly, each
element's parent's elements are adjusted. I cannot determine whether
relative rectangles are being filled in.

http://www.elavatar.com/tableinsert.html
(tested in FF 3.0.5 macintosh)

Hi Bob. Yes, you're right. In most browsers using innerHTML to buid
the table is *much* faster than using DOM methods such as
createElement, appendChild, etc.

Look at this: <http://jorgechamorro.com/cljs/031/> (it uses your
code). Up to 4 times faster in some (usually older) browsers !. But in
the latest, newer ones, though, there isn't such a big difference. But
this has nothing to do with rendering !
 
G

Gregor Kofler

Jorge meinte:
Look at this: <http://jorgechamorro.com/cljs/031/> (it uses your
code). Up to 4 times faster in some (usually older) browsers !. But in
the latest, newer ones, though, there isn't such a big difference. But
this has nothing to do with rendering !

Well, with WebKit on my Midori Browser (identified as Safari 528.5+):
The Benchmark without rendering gives 48/39/39 Ops per sec.
However, with rendering
innerHTML needs 41ms, DOM1 33ms, DOM2 35ms. Repeatedly. Now all three
methods seem to be equally fast, with innerHTML interestingly the
(slightly) slowest variant.

Gregor
 
J

Jorge

As you (apparently) don't have access to IE (versions) you probably
won't be aware that the failure to include a TBODY and the use of -
textContent - in createWithDOM1 and createWithDOM2  prevent both of
those functions from working properly in IE. That invalidates you page
as a comparison for IE, and given that IE 6 is easily the worst
performing of the desktop browsers currently in common use it would be
useful for everyone to be able to make the comparison in that
environment.

Yes.
But I've got no way to test it in IE6/7, and it's not going to be easy
for me to fix it either (I'm not exactly a big fan of IE). If you
wish, could you do it ?

Thanks,
 
B

beegee

beegee wrote:
Uh, document.createElement() ? After this call, the element is now
part of the DOM.

Strictly speaking, `document' (as an implementation of the
HTML:
Document
interface of W3C DOM Level 2+ Core/2 HTML) and `document.createElement' (as
an implementation of [HTML]Document::createElement()) are part of the DOM
API.  The element object created with this method is _not_ part of the
*document tree* until it is added to a parent node as child node.

So, loosely speaking, you are mistaken.[/QUOTE]

Loosely speaking?  I don't believe we were speaking loosely.  In fact,
since you often promote technical 'tightness' in this forum, I'm
surprised.  document.createElement() adds a node to the DOM.  It is
unclear that because it hasn't yet been added to the body tree that
the browser does not know how to render it relative to either itself
or a parent container.  If you believe it is neccessary for an element
to be attached to the DOM tree to be rendered then please show me
proof.


[QUOTE]
You could have made a non-fallacious argument in the first place.  *You*
must prove that you are *right*; others do _not_ need to prove that you are
wrong.[/QUOTE]


see above.

Bob
 
T

Thomas 'PointedEars' Lahn

beegee said:
Thomas said:
beegee said:
Uh, document.createElement() ? After this call, the element is now
part of the DOM.

Strictly speaking, `document' (as an implementation of the
HTML:
Document
interface of W3C DOM Level 2+ Core/2 HTML) and `document.createElement'
(as an implementation of [HTML]Document::createElement()) are part of the
DOM API.  The element object created with this method is _not_ part of
the *document tree* until it is added to a parent node as child node.

So, loosely speaking, you are mistaken.[/QUOTE]

Loosely speaking?  I don't believe we were speaking loosely.[/QUOTE]

You were talking about an "element that is part of the DOM".  That is a
contradiction in itself, not to mention your mistaking a returned object
reference for being part of anything.
[QUOTE]
In fact, since you often promote technical 'tightness' in this forum, I'm
surprised.[/QUOTE]

You shouldn't be, trust me.
[QUOTE]
document.createElement() adds a node to the DOM.[/QUOTE]

No, it creates a DOM element object and returns a reference to it.  Nothing
more, nothing less (unless you attempt to create unsupported element
objects, then it may throw an exception instead).

It is the appendChild() method and other DOM mutator methods that modify the
document tree so that the object is being referred to.  Without that, the
object is likely to be almost immediately garbage-collected as it is no
longer being referred to.
[QUOTE]
It is unclear that because it hasn't yet been added to the body tree[/QUOTE]

Talking about "technical 'tightness'" -- "body tree"?
[QUOTE]
that the browser does not know how to render it [...][/QUOTE]

"The browser" does not even "know" that it is there.
[QUOTE]
If you believe it is neccessary for an element to be attached to the DOM
tree to be rendered then please show me proof.[/QUOTE]

That much is self-evident: Something that cannot be known to exist cannot be
rendered.


PointedEars
 
B

beegee

beegee meinte:
Erm (first figure is always innerHTML)...
FF 3.0.5 (Linux 64bit)
144 vs. 167, 132 vs. 156. 120 vs. 160. 105 vs. 141. Impressive.

But wait:
Midori/WebKit
45 vs. 41. 44 vs. 44. 39 vs. 43. 54 vs. 48... Do I need to go on?

As I mentioned somewhere up the thread: innerHTML might be slightly
faster. Once you have to get references to some table cells, any
advantage is most likely lost.

Well, my intent was for everyone to run this example through Firebug
and watch the members of parents get filled in. Instead its turned
into a speed test. Ok, I fully admit it really doesn't matter whether
one uses innerHTML vs DOM methods to construct a table with current
browsers. By the way, the figures for Mac FF 3.0.5 were more like 90
vs. 183, consistently. So Linux FF seems to be missing some
optimizations (or a 64 bit processor actually slows some operations
down!)

Bob
 
T

Thomas 'PointedEars' Lahn

Thomas said:
No, it creates a DOM element object and returns a reference to it.
Nothing more, nothing less (unless you attempt to create unsupported
element objects, then it may throw an exception instead).

It is the appendChild() method and other DOM mutator methods that modify
the document tree so that the object is being referred to. Without that,
the object is likely to be almost immediately garbage-collected as it is
no longer being referred to.

In addition, assigning the returned object reference to a variable or
another property would also prevent the object from being
garbage-collected. But what matters here is that the object is not in any
way part of the document tree until the variable or property is used in a
DOM mutator call or assignment.


PointedEars
 
G

Gregor Kofler

beegee meinte:
So Linux FF seems to be missing some
optimizations (or a 64 bit processor actually slows some operations
down!)

Could be, though I've quite a few add-ons active. However, FF/Linux 64
becomes unstable/extremely slow with large tables (didn't encounter that
on Win32). No problems with the WebKit alternative or Opera.

Gregor
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,608
Members
45,241
Latest member
Lisa1997

Latest Threads

Top