Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #8357 > unrolled thread

David Mark's Javascript Daily - Volume #3 - Tip #6 - How to Get and Set HTML

Started byDavid Mark <dmark.cinsoft@gmail.com>
First post2011-11-15 11:47 -0800
Last post2011-11-16 18:51 +0000
Articles 7 — 6 participants

Back to article view | Back to comp.lang.javascript


Contents

  David Mark's Javascript Daily - Volume #3 - Tip #6 - How to Get and Set HTML David Mark <dmark.cinsoft@gmail.com> - 2011-11-15 11:47 -0800
    Re: David Mark's Javascript Daily - Volume #3 - Tip #6 - How to Get and Set HTML Andreas Bergmaier <andber93@web.de> - 2011-11-15 22:26 +0100
      Re: David Mark's Javascript Daily - Volume #3 - Tip #6 - How to Get and Set HTML Gregor Kofler <usenet@gregorkofler.com> - 2011-11-15 22:57 +0100
      Re: David Mark's Javascript Daily - Volume #3 - Tip #6 - How to Get and Set HTML "J.R." <groups_jr-1@yahoo.com.br> - 2011-11-15 21:16 -0200
      Re: David Mark's Javascript Daily - Volume #3 - Tip #6 - How to Get and Set HTML Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2011-11-16 01:11 +0100
        Re: David Mark's Javascript Daily - Volume #3 - Tip #6 - How to Get and Set HTML Andreas Bergmaier <andber93@web.de> - 2011-11-16 02:29 +0100
    Re: David Mark's Javascript Daily - Volume #3 - Tip #6 - How to Get and Set HTML Dr J R Stockton <reply1146@merlyn.demon.co.uk> - 2011-11-16 18:51 +0000

#8357 — David Mark's Javascript Daily - Volume #3 - Tip #6 - How to Get and Set HTML

FromDavid Mark <dmark.cinsoft@gmail.com>
Date2011-11-15 11:47 -0800
SubjectDavid Mark's Javascript Daily - Volume #3 - Tip #6 - How to Get and Set HTML
Message-ID<b8aaaf65-2095-4145-8992-651aae0e9a69@p9g2000vbb.googlegroups.com>
How to Get and Set HTML

Setting the inner HTML of an element is often useful. When making
complicated changes to the document tree, allowing the parser to do
most of the work is often the most efficient solution.  The question
of whether to deal with a string or object representation of a DOM
structure comes up often in applications that update portions of a
document with XHR results.

Despite there being no standard behind the innerHTML property and the
somewhat awkward feel of dealing with serialized DOM structures, I
virtually always choose the string over the (XML) document object.
It's much simpler, faster, requires less code, less function calls
and, having debuted in IE 4, has enough successful history behind it
to be trusted.

You've probably heard there are bugs galore with this property, but
most implementation differences can hardly be considered bugs.  This
is another Microsoft invention that has been copied by every other
browser vendor.  Microsoft explicitly disallowed modifying table
structures with this property.  For example, you can replace entire
TABLE elements, but you can't replace a row, column group, etc.  There
are existing (and standard) objects to modify table structures:-

http://msdn.microsoft.com/en-us/library/ms537484(v=vs.85).aspx

Follow the link at the bottom to the DOM 1 recommendation to find all
of the information you need to modify table structures without
stooping to setting inner HTML.

Same goes for SELECT elements, which also have specialized objects to
modify their structure (e.g. add and remove options).  As with most
form controls, they are very easy to manipulate with standard code
that works in virtually every script-enabled browser ever made (even
NN 4!)  See the same DOM recommendation.

Keeping these facts in mind during design can save a world of time.
I've found that most designs can do just fine sticking to the
innerHTML properties of DIV elements (and perhaps the occasional TD or
TR, which won't change the structure of containing tables).

The simplest rendition of the setter with simplified feature
detection*:-

// NOTE: Don't use this rendition with anything but DIV's

// Degrades in IE 3 :)

if (document.documentElement && 'string' == typeof
document.documentElement.innerHTML) {
  var setHTML = function(el, html) {
    el.innerHTML = html;
  };
}

Trying to move a complicated project with lots of developers over to
this way of setting HTML?  During development, you may want to add
something like:-

if (el.tagName.toLowerCase() != 'div') {
  throw new Error('Please only set inner HTML of DIV elements!');
}

...at the outset (and remove on deployment of course).  All of the
trouble-making code will become apparent.  Eventually, even the
developers who don't read documentation will get the message about not
modifying anything other than DIV's with the setHTML function.

Why would you even bother to wrap that functionality?  For one,
because you need the feature detection.  Never mind that virtually
every browser made to date has this property.  Your applications
should degrade gracefully in those (past or future) browsers that are
the exceptions.  Why even try to memorize which host objects and
properties are omnipresent at the moment the function is written?
Just include appropriate feature detection/testing in all function
renditions.

if (setHTML) {
  // Put HTML setting application here
}

Also, however unlikely in this case, you might want to replace setHTML
with a more complicated rendition in some future application.  You
might consider the debug version with the argument validation to be an
alternate rendition.  I prefer to think of it as a debug version of
the same rendition.

But a better question is why you would want to try to modify table
structures by setting inner HTML.  Sure, it can be be done in a
roundabout way.  Ultimately it comes down to doing what you were
trying to avoid in the first place (i.e. manually appending nodes one
at a time).  My Library (and the rest) all go through a lot of
rigamorale to try to make such operations "work" (as best they can)
with varied results.  This is what GP libraries do.  They don't help
developers avoid costly mistakes.  They hide the costly mistakes
behind a "concise" API.  If you could only see the mess that goes on
behind the scenes of these things, you'd be in a much better position
to make sound design decisions.  Furthermore, you wouldn't be left
with code that can only be reasonably expected to "work" in five or
six of the latest versions of the "core" browsers in their default
configurations *today*.

Every time I hear "don't reinvent the wheel", I think of how many old
versions of jQuery, Dojo, Prototype, Mootools, etc. there are broken
down and rusting on the side of the highway.  Also have to wonder what
the average Web developer wants with the "perfect" innerHTML wrapper.
Sure lots of library authors (typically excited and ambitious
beginners) are keen to provide such a thing (as best they can).  But
who in their right mind would be in the market for it, particularly
when it is likely a clunky multi-browser facade as opposed to a clean
cross-browser solution?  Which strategy do you think will save time in
the long run?  Which strategy will the monolithic libraries/framework
always eschew for not having enough mass appeal?

See the problem with such libraries?  They constantly strive to
overreach both practicality and the collective ability of their
authors because they are all in some sort of ridiculous competition to
be the most popular library.  Does being the most popular lead to
better solutions?  Of course not; jQuery is a prime example of a
script getting (much) worse as it grows more popular.  It's not hard
to understand why: too many cooks with too many contexts, too many
suggestions, etc.  You end up with one fuzzily-defined context (e.g.
works for me here, dude!) for hundreds of functions.  Changing any one
function can alter the context in which the collection is expected to
work; it's impossible to pin such things down and no wonder that most
libraries provide little more than a set of shiny browser icons to
indicate their "supported" environments.

In contrast to setting, serializing (getting) HTML from DOM structures
is mostly useless and trying to normalize markup on the client side is
generally a waste of time.  An example of an application that does
need to serialize HTML is an editor.  But generally, HTML editors
don't *need* to normalize the resulting markup.  That's a task for a
server side process.  It's the same case as with form validation,
except that providing a client side first defense is a much more
complicated proposition.  You have to write the server side validation
anyway.

* Use isHostObjectProperty to detect documentElement

http://www.cinsoft.net/
http://www.twitter.com/cinsoft
http://jsperf.com/browse/david-mark

[toc] | [next] | [standalone]


#8358

FromAndreas Bergmaier <andber93@web.de>
Date2011-11-15 22:26 +0100
Message-ID<j9ulej$141$1@news.albasani.net>
In reply to#8357
David Mark schrieb:
> Despite there being no standard behind the innerHTML property and the
> somewhat awkward feel of dealing with serialized DOM structures, I
> virtually always choose the string over the (XML) document object.
> It's much simpler, faster, requires less code, less function calls
> and, having debuted in IE 4, has enough successful history behind it
> to be trusted.

Why is that faster? Only because the native html parser is faster than 
the javascript interpreter?
I could understand the use of innerHTML when it's for large static 
elements delivered as plain text per ajax - where the server can 
serialize the structure into HTML. But when it comes to elements with 
event listeners, I absolutely prefer DOM building methods.
Using a "library" function that takes the element name, attributes, 
child nodes and event listeners as attributes, I can build dom 
structures much easier than (hand)writing serialized html strings.
Also I can't believe that it would be faster to serialize the structure 
to a string, process this with the innerHTML parser, and then dig in the 
dom tree again to set the listeners (Thats what I really hate jQuery for).
Using plain dom methods (document.createElement, 
document.createTextNode, el.appendChild, el.addEventListener) I've never 
experienced problems with tables or select elements, and I'm not limited 
to divs.
Or does that only work in recent browsers?

  Bergi

[toc] | [prev] | [next] | [standalone]


#8359

FromGregor Kofler <usenet@gregorkofler.com>
Date2011-11-15 22:57 +0100
Message-ID<j9un8v$m3e$1@dont-email.me>
In reply to#8358
Am 2011-11-15 22:26, Andreas Bergmaier meinte:
> David Mark schrieb:
>> Despite there being no standard behind the innerHTML property and the
>> somewhat awkward feel of dealing with serialized DOM structures, I
>> virtually always choose the string over the (XML) document object.
>> It's much simpler, faster, requires less code, less function calls
>> and, having debuted in IE 4, has enough successful history behind it
>> to be trusted.
> 
> Why is that faster? Only because the native html parser is faster than
> the javascript interpreter?
> I could understand the use of innerHTML when it's for large static
> elements delivered as plain text per ajax - where the server can
> serialize the structure into HTML. But when it comes to elements with
> event listeners, I absolutely prefer DOM building methods.
> Using a "library" function that takes the element name, attributes,
> child nodes and event listeners as attributes, I can build dom
> structures much easier than (hand)writing serialized html strings.
> Also I can't believe that it would be faster to serialize the structure
> to a string, process this with the innerHTML parser, and then dig in the
> dom tree again to set the listeners (Thats what I really hate jQuery for).
> Using plain dom methods (document.createElement,
> document.createTextNode, el.appendChild, el.addEventListener) I've never
> experienced problems with tables or select elements, and I'm not limited
> to divs.
> Or does that only work in recent browsers?

I only resort to innerHTML with "dumb" (and unproblematic) blobs of
markup. Whenever I need references to single elements within the
generated markup, I prefer the approach you outlined.

Gregor

-- 
http://vxweb.net

[toc] | [prev] | [next] | [standalone]


#8361

From"J.R." <groups_jr-1@yahoo.com.br>
Date2011-11-15 21:16 -0200
Message-ID<j9urrl$vqn$1@speranza.aioe.org>
In reply to#8358
On 15/11/2011 19:26, Andreas Bergmaier wrote:
> David Mark schrieb:
>> Despite there being no standard behind the innerHTML property and the
>> somewhat awkward feel of dealing with serialized DOM structures, I
>> virtually always choose the string over the (XML) document object.
>> It's much simpler, faster, requires less code, less function calls
>> and, having debuted in IE 4, has enough successful history behind it
>> to be trusted.
>
> Why is that faster? Only because the native html parser is faster than
> the javascript interpreter?
> I could understand the use of innerHTML when it's for large static
> elements delivered as plain text per ajax - where the server can
> serialize the structure into HTML. But when it comes to elements with
> event listeners, I absolutely prefer DOM building methods.
> Using a "library" function that takes the element name, attributes,
> child nodes and event listeners as attributes, I can build dom
> structures much easier than (hand)writing serialized html strings.
> Also I can't believe that it would be faster to serialize the structure
> to a string, process this with the innerHTML parser, and then dig in the
> dom tree again to set the listeners (Thats what I really hate jQuery for).
> Using plain dom methods (document.createElement,
> document.createTextNode, el.appendChild, el.addEventListener) I've never
> experienced problems with tables or select elements, and I'm not limited
> to divs.
> Or does that only work in recent browsers?

Searching the Internet, we can find some performance tests proving that 
innerHTML really seems to be faster than the W3C DOM methods. Of course 
results may differ significantly from browser to browser and from 
version to version. E.g. <http://www.quirksmode.org/dom/innerhtml.html>

However, take a look at this article from Mozilla: 
<https://developer.mozilla.org/En/DOM/Element.innerHTML>

Also: innerHTML in HTML 5 
<http://www.w3.org/TR/2008/WD-html5-20080610/dom.html#innerhtml0>

-- 
Joao Rodrigues (J.R.)

[toc] | [prev] | [next] | [standalone]


#8362

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2011-11-16 01:11 +0100
Message-ID<2724045.nNXnhXx0nj@PointedEars.de>
In reply to#8358
Andreas Bergmaier wrote:

> David Mark schrieb:
>> Despite there being no standard behind the innerHTML property and the
>> somewhat awkward feel of dealing with serialized DOM structures, I
>> virtually always choose the string over the (XML) document object.
>> It's much simpler, faster, requires less code, less function calls
>> and, having debuted in IE 4, has enough successful history behind it
>> to be trusted.
> 
> Why is that faster?

Possibility: An assignment to `innerHTML' would trigger once a markup parser 
written entirely in the host environment's native programming language, such 
as C++, thereby probably being executed as machine code.  Whereas with 
several DOM method calls each would trigger the native implementation, 
switching to and back from native code in the process.  The stack operations 
involved in the latter, and the fact that the ECMAScript implementation 
would be single-threaded, could contribute to its being slower than the 
former.

> Only because the native html parser is faster than the javascript
> interpreter?

There is no "javascript", and you have a common misconception of how code 
written in an ECMAScript implementation is being executed by a Web browser.

> I could understand the use of innerHTML when it's for large static
> elements delivered as plain text per ajax - where the server can
> serialize the structure into HTML.

What you are writing may read sophisticated and even meaningful to the 
uninitiated, but it actually makes no sense at all.  I strongly suggest you 
familiarize yourself with the workings of Web server and browser – and 
perhaps English – before making further (English-language) statements on 
this topic.  For example, the Web *server* does not (need to) serialize 
anything if you use XHR to request HTML markup in the response message.


PointedEars
-- 
Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not
the best source of advice on designing systems that use javascript.
  -- Richard Cornford, cljs, <f806at$ail$1$8300dec7@news.demon.co.uk>

[toc] | [prev] | [next] | [standalone]


#8363

FromAndreas Bergmaier <andber93@web.de>
Date2011-11-16 02:29 +0100
Message-ID<j9v3l8$472$1@news.albasani.net>
In reply to#8362
Thomas 'PointedEars' Lahn schrieb:
> Andreas Bergmaier wrote:
>
>> Only because the native html parser is faster than the javascript
>> interpreter?
>
> There is no "javascript"

I know I should spell it "JavaScript", but when I'm writing English my 
shift key often stucks - sorry. You don't have to remind me of that, but 
thanks.

> and you have a common misconception of how code
> written in an ECMAScript implementation is being executed by a Web browser.

I hope not, but isn't "interpreting code" a short form for "interpreting 
syntax, building a (implementation specific) native structure, and 
execute it when requested"?

>> I could understand the use of innerHTML when it's for large static
>> elements delivered as plain text per ajax - where the server can
>> serialize the structure into HTML.
>
> What you are writing may read sophisticated and even meaningful to the
> uninitiated, but it actually makes no sense at all.  I strongly suggest you
> familiarize yourself with the workings of Web server and browser – and
> perhaps English – before making further (English-language) statements on
> this topic.  For example, the Web *server* does not (need to) serialize
> anything if you use XHR to request HTML markup in the response message.

No, you understood me right. A server has same structured data, for 
example in a database, which should be displayed on the client's screen. 
So either the server generates HTML markup, or it sends the data as some 
other type - e.g. json -, which could decrease the file size 
significantly. In the first case the script engine would use innerHTML, 
in the second it could either build the table with dom methods or 
serialize the data to a markup string and use innerHTML again. So which 
of the three ways is faster?

  Bergi

[toc] | [prev] | [next] | [standalone]


#8378

FromDr J R Stockton <reply1146@merlyn.demon.co.uk>
Date2011-11-16 18:51 +0000
Message-ID<6hYxxkMeYAxOFwPE@invalid.uk.co.demon.merlyn.invalid>
In reply to#8357
In comp.lang.javascript message <b8aaaf65-2095-4145-8992-651aae0e9a69@p9
g2000vbb.googlegroups.com>, Tue, 15 Nov 2011 11:47:08, David Mark
<dmark.cinsoft@gmail.com> posted:

>Keeping these facts in mind during design can save a world of time.
>I've found that most designs can do just fine sticking to the
>innerHTML properties of DIV elements (and perhaps the occasional TD or
>TR, which won't change the structure of containing tables).
>
>The simplest rendition of the setter with simplified feature
>detection*:-
>
>// NOTE: Don't use this rendition with anything but DIV's


Were you intending to imply that it is not safe with SPAN elements?

-- 
 (c) John Stockton, nr London UK. ?@merlyn.demon.co.uk  BP7, Delphi 3 & 2006.
   <http://www.merlyn.demon.co.uk/> TP/BP/Delphi/&c., FAQqy topics & links;
   <http://www.bancoems.com/CompLangPascalDelphiMisc-MiniFAQ.htm> clpdmFAQ;
   NOT <http://support.codegear.com/newsgroups/>: news:borland.* Guidelines

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.javascript


csiph-web