standards-compliant equivalent of innerHTML

A

Andy Fish

Hi,

I have an application which uses Javascript ro replace an element's
innerHTML with a string of HTML retrieved from an Ajax call. In some
circumstances I get an "unknown runtime error" from IE which seems to
be a bug (if you google for innerHTML "unknown runtime error" you'll
see what I mean), and I have also had problems with Chrome too.

The crux of the issue seems to come down to the fact that innerHTML is
not part of the W3C DOM Specification, so I am looking for a standards-
compliant way to achieve the same thing.

In my application, both the main HTML document and the HTML fragment
I'm trying to insert are user-supplied content so I am not in control
of them - I need my application to work with any valid HTML content.

The HTML is not necessarily valid XHTML, so I cannot use responseXML
in the ajax call.

at the moment I can only see 3 options, none of which appeal:

1. keep trying to work around problems with individual browsers
(fiddly and no guarantee of success)

2. somehow convert the HTML to XHTML on the server, then I can use
responseXML

3. parse the returned HTML fragment into a DOM tree in javascript
(presumably using js string slicing)

any other thoughts would be gratefully appreciated

Andy
 
T

Thomas 'PointedEars' Lahn

Andy said:
I have an application which uses Javascript ro replace an element's
innerHTML with a string of HTML retrieved from an Ajax call. In some
circumstances I get an "unknown runtime error" from IE which seems to
be a bug (if you google for innerHTML "unknown runtime error" you'll
see what I mean),

You must be kidding, expecting anyone to guess what you mean from a Google
result yet to be retrieved, while obviously haven't done any considerable
research yourself.

and I have also had problems with Chrome too.

Which indicates that the problem is located on OSI Layer 8 instead.
The crux of the issue seems to come down to the fact that innerHTML is
not part of the W3C DOM Specification,

Or that the resulting markup would be not Valid?
so I am looking for a standards-compliant way to achieve the same thing.

In my application, both the main HTML document and the HTML fragment
I'm trying to insert are user-supplied content so I am not in control
of them - I need my application to work with any valid HTML content.

User-supplied content can be made Valid before it is submitted.
The HTML is not necessarily valid XHTML, so I cannot use responseXML
in the ajax call.

There is no "ajax call".
at the moment I can only see 3 options, none of which appeal:

1. keep trying to work around problems with individual browsers
(fiddly and no guarantee of success)

The problem is your inappropriate methodology, if any. To solve a problem
it needs to be properly analyzed first.
2. somehow convert the HTML to XHTML on the server, then I can use
responseXML

With rare exceptions, you cannot simply convert HTML to XHTML. You can,
however, use XHTML in the first place.
3. parse the returned HTML fragment into a DOM tree in javascript
(presumably using js string slicing)

any other thoughts would be gratefully appreciated

You could respond with JSON and the like, and use client-side scripting to
build the subtree with standards-compliant methods. That approach is
probably the most promising next to understanding why `innerHTML' fails on
occasion.

However, it is next to impossible to automatically structure what is stored
without proper structure, so you need to fix the flaw in your application
design in any case first.


PointedEars
 
D

David Mark

Hi,

I have an application which uses Javascript ro replace an element's
innerHTML with a string of HTML retrieved from an Ajax call. In some
circumstances I get an "unknown runtime error" from IE which seems to
be a bug (if you google for innerHTML "unknown runtime error" you'll
see what I mean), and I have also had problems with Chrome too.

It may not be a bug in IE. MS invented innerHTML, so they make the
rules. But certainly browsers reserve the right to veto innerHTML
substitutions, especially ones that would result in an invalid DOM.

Other browsers have copied this proprietary property with varying
degrees of adherence to the MS version. So it can be dicey.
The crux of the issue seems to come down to the fact that innerHTML is
not part of the W3C DOM Specification, so I am looking for a standards-
compliant way to achieve the same thing.

Standards compliant doesn't necessarily mean cross-browser.
In my application, both the main HTML document and the HTML fragment
I'm trying to insert are user-supplied content so I am not in control
of them - I need my application to work with any valid HTML content.

The HTML is not necessarily valid XHTML, so I cannot use responseXML
in the ajax call.

I assume you mean it is not _served_ as XHTML (i.e. with an XML MIME
type). And you certainly can use responseXML. It's your only viable
option other than innerHTML. Unfortunately, it's not a great one.
at the moment I can only see 3 options, none of which appeal:

1. keep trying to work around problems with individual browsers
(fiddly and no guarantee of success)
Bad.


2. somehow convert the HTML to XHTML on the server, then I can use
responseXML

You mean server it as XHTML and that's out of the question on the
Web. IE simple won't handle it or will treat it as HTML, depending on
circumstances and configuration.
3. parse the returned HTML fragment into a DOM tree in javascript
(presumably using js string slicing)

That would certainly be a non-trivial task for random markup. :)

So, you are left with walking the returned XML and building a like
HTML fragment to inject into your HTML document. This is also a non-
trivial task due to differences in XML DOM representations. but far
easier than parsing markup.
 
S

Stevo

Andy said:
Hi,

I have an application which uses Javascript ro replace an element's
innerHTML with a string of HTML retrieved from an Ajax call. In some
circumstances I get an "unknown runtime error" from IE which seems to
be a bug (if you google for innerHTML "unknown runtime error" you'll
see what I mean), and I have also had problems with Chrome too.

The crux of the issue seems to come down to the fact that innerHTML is
not part of the W3C DOM Specification, so I am looking for a standards-
compliant way to achieve the same thing.

That's a bizarre conclusion. What has a W3C DOM specification got to do
with whether IE only fails "in some circumstances". Either IE supports
innerHTML or it doesn't. It does. So if there are some circumstances
where it fails then you need to figure out what those are and why
they're failing, not leap to an incorrect conclusion about a specification.

One reason it might be failing is if you're trying to write to innerHTML
too early. See also the thread "Re: Can script determine if
window.onload has already fired?" which is also related to this. If you
try writing to the innerHTML of some elements too early, you'll get an
error. Previously you'd have gotten an operation aborted error, but in
IE8 they changed it to a catchable error.

If you delay your code until after document.readyState=="complete" then
you might avoid that error.
 
D

David Mark

[...]
You mean server it as XHTML and that's out of the question on the
Web.  IE simple won't handle it or will treat it as HTML, depending on
circumstances and configuration.

To clarify, the page doing the receiving cannot be XHTML in IE. The
snippets sent by XHR can and must be XHTML if you are to receive an
XML DOM in the response (see the My Library test page).
 
D

David Mark

[...]
If you delay your code until after document.readyState=="complete" then
you might avoid that error.

Well put. And if you use a load listener, you _will_ avoid that error.
 
A

Andy Fish

You must be kidding, expecting anyone to guess what you mean from a Google
result yet to be retrieved, while obviously haven't done any considerable
research yourself.



Which indicates that the problem is located on OSI Layer 8 instead.


Or that the resulting markup would be not Valid?



User-supplied content can be made Valid before it is submitted.


There is no "ajax call".



The problem is your inappropriate methodology, if any.  To solve a problem
it needs to be properly analyzed first.


With rare exceptions, you cannot simply convert HTML to XHTML.  You can,
however, use XHTML in the first place.



You could respond with JSON and the like, and use client-side scripting to
build the subtree with standards-compliant methods.  That approach is
probably the most promising next to understanding why `innerHTML' fails on
occasion.

However, it is next to impossible to automatically structure what is stored
without proper structure, so you need to fix the flaw in your application
design in any case first.

PointedEars
--
    realism:    HTML 4.01 Strict
    evangelism: XHTML 1.0 Strict
    madness:    XHTML 1.1 as application/xhtml+xml
                                                    -- Bjoern Hoehrmann

OK I tried to explain as fully as I can without being too long winded
or pedantic. I'll try to clarify it a bit more.

if you read this post: http://www.webdeveloper.com/forum/showthread.php?t=22946
or others similar to it, it should be clear that there are occasions
when innerHTML does not work in IE when one might reasonably expect it
to. Since innerHTML is not part of the w3c standard, there is no
garantee it will work the same in all browsers and it is generally a
bad idea for me to rely on it so I am looking for an alternative.

The original HTML, the fragment I am trying to add, and the resulting
document, are all valid HTML

the obvious idea is to use responseXML to parse the data returned from
the ajax call, which will build it into a DOM tree which I can then
import into the document. However, the HTML that is being returned is
not XML compliant and I cannot force it to be, since it is user-
supplied data and not something I have generated myself.

as far as my processing am concerned, the user data is just an opaque
string (though I know it to be valid HTML). I really don't want to get
involved with looking inside it at all
 
A

Andy Fish

That's a bizarre conclusion. What has a W3C DOM specification got to do
with whether IE only fails "in some circumstances". Either IE supports
innerHTML or it doesn't. It does. So if there are some circumstances
where it fails then you need to figure out what those are and why
they're failing, not leap to an incorrect conclusion about a specification.

One reason it might be failing is if you're trying to write to innerHTML
too early. See also the thread "Re: Can script determine if
window.onload has already fired?" which is also related to this. If you
try writing to the innerHTML of some elements too early, you'll get an
error. Previously you'd have gotten an operation aborted error, but in
IE8 they changed it to a catchable error.

If you delay your code until after document.readyState=="complete" then
you might avoid that error.

Thanks for the hint, but it is definitely not down to this. I have hit
this problem before so I am aware of it. it's definitely data related
rather than timing related
 
A

Andy Fish

It may not be a bug in IE.  MS invented innerHTML, so they make the
rules.  But certainly browsers reserve the right to veto innerHTML
substitutions, especially ones that would result in an invalid DOM.

Other browsers have copied this proprietary property with varying
degrees of adherence to the MS version.  So it can be dicey.




Standards compliant doesn't necessarily mean cross-browser.





I assume you mean it is not _served_ as XHTML (i.e. with an XML MIME
type).  And you certainly can use responseXML.  It's your only viable
option other than innerHTML.  Unfortunately, it's not a great one.





You mean server it as XHTML and that's out of the question on the
Web.  IE simple won't handle it or will treat it as HTML, depending on
circumstances and configuration.




That would certainly be a non-trivial task for random markup.  :)

So, you are left with walking the returned XML and building a like
HTML fragment to inject into your HTML document.  This is also a non-
trivial task due to differences in XML DOM representations. but far
easier than parsing markup.

thanks for your ideas. Unfortunately as you can see from an earlier
reply, the HTML I am trying to insert is just opaque user data as far
as I am concerned. It will be valid HTML but is not XHTML and so can't
be parsed as such
 
R

Richard Cornford

On Nov 25, 2:14 pm, Andy Fish wrote:
if you read this post:
http://www.webdeveloper.com/forum/showthread.php?t=22946
or others similar to it, it should be clear that there are
occasions when innerHTML does not work in IE when one might
reasonably expect it to.

That is not what I read. I read a procession of reports from
individuals who have no idea of how to analyse a problem and a certain
amount of speculation. The nearest anyone gets to identifying a cause
and effect relationship is the suggestion that nesting A elements is
implicated in the situation, which is a failure situation that might
be reasonably expected as A elements cannot contain A elements in HTML
(much has FORM elements cannot contain FORM elements in HTML). There a
no test cases demonstrating issue provoking code, which would be
reasonable starting point when attempting to show a genuine issue with
IE.
Since innerHTML is not part of the w3c standard, there is no
garantee it will work the same in all browsers

That doesn't become guaranteed even if it does become a standard
(witness the way the W3C botched the - add - and - remove - method
definition in the HTMLSelectElement interface, where not defining it
to conform with pre-existing implementations (or using an alternative
name) made implementing it to the W3C spec problematic for at least
one manufacturer).
and it is generally a bad idea for me to rely on it so I am
looking for an alternative.

The original HTML, the fragment I am trying to add, and the
resulting document, are all valid HTML

That has questionable meaning. Being valid HTML is a characteristic of
a full document. Any fragment of a valid HTML document cannot be
inserted into any arbitrary location in another HTML document and be
guaranteed to result in a valid HTML document.
the obvious idea is to use responseXML to parse the data returned
from the ajax call, which will build it into a DOM tree which
I can then import into the document.

Depends a lot on the browser.
However, the HTML that is being returned is
not XML compliant and I cannot force it to be, since it is user-
supplied data and not something I have generated myself.

as far as my processing am concerned, the user data is just
an opaque string (though I know it to be valid HTML).

Again, that should be questioned. If it is not a full document how
can it be validated, and if it is a full document inserting it into
another certainly will result in invalid mark-up. You know something
about these fragments, but so far you have not said exactly what it is
that you know about them.
I really don't want to get
involved with looking inside it at all

Seems reasonable, but whether you can get away with not looking might
depend the outcome of identifying the cause and effect relationship
that is making innerHTML problematic.

Richard.
 
T

Thomas 'PointedEars' Lahn

Andy said:
OK I tried to explain as fully as I can without being too long winded
or pedantic.

Too late. Your mindless full-quote already managed to blew it.

I'll try to clarify it a bit more.

if you read this post:
http://www.webdeveloper.com/forum/showthread.php?t=22946

404-compliant. Besides, you don't expect me to do your homework, do you?
or others similar to it, it should be clear that there are occasions when
innerHTML does not work in IE

That much is known.
when one might reasonably expect it to.

Such as?
Since innerHTML is not part of the w3c standard,

Not yet anyway.
there is no garantee it will work the same in all browsers and it is
generally a bad idea for me to rely on it so I am looking for an
alternative.
True.

The original HTML, the fragment I am trying to add, and the resulting
document, are all valid HTML

Then it is possible to parse it.
the obvious idea is to use responseXML to parse the data returned from
the ajax call,

I already told you that there is no "ajax call". Can't you read?

And no, that is not the proper approach.
which will build it into a DOM tree which I can then import into the
document.

If you have a node that you can import, you don't need to parse it.
However, the HTML that is being returned is not XML compliant and I cannot
force it to be, since it is user-supplied data and not something I have
generated myself.

Therefore, as an alternative to HTML parsing, you need to fix the design
flaw in your application first, so that no non-XML-compliant markup reaches
the server in the first place (this should be done client-side to provide
the user with immediate feedback). Then, in the XHR, you can either serve
XML-compliant markup declared with an XML MIME media type and get a node
that you can import, or you can respond with JSON or a similar script-
related format that a client-side script can operate on. Told you, and if
you had cared to quote properly, you would probably have noticed that.
as far as my processing am concerned, the user data is just an opaque
string (though I know it to be valid HTML). I really don't want to get
involved with looking inside it at all

Your specifications are contradictory.

<http://www.catb.org/~esr/faqs/smart-questions.html>


PointedEars
 
T

Thomas 'PointedEars' Lahn

Richard said:
That doesn't become guaranteed even if it does become a standard
(witness the way the W3C botched the - add - and - remove - method
definition in the HTMLSelectElement interface, where not defining it
to conform with pre-existing implementations (or using an alternative
name) made implementing it to the W3C spec problematic for at least
one manufacturer).

That one manufacturer would be Microsoft, right? It is far too easy to
blaim "the W3C" for everything while ignoring the relationship Microsoft and
other "manufacturers" have with the W3C (most are, and have been, members to
begin with, see <http://www.w3.org/Consortium/Member/List>):

,-<http://www.w3.org/TR/REC-DOM-Level-1/>
|
| Editors
| Vidur Apparao, Netscape
| Steve Byrne, Sun
| Mike Champion, ArborText
| Scott Isaacs, Microsoft
^^^^^^^^^^^^^^^^^^^^^^^
| Ian Jacobs, W3C
| Arnaud Le Hors, W3C
| Gavin Nicol, Inso EPS
| Jonathan Robie, Texcel Research
| Robert Sutor, IBM
| Chris Wilson, Microsoft
^^^^^^^^^^^^^^^^^^^^^^^
| Lauren Wood, SoftQuad, Inc.
|
| Principal Contributors
| Vidur Apparao, Netscape
| Steve Byrne, Sun (until November 1997)
| Mike Champion, ArborText, Inc.
| Scott Isaacs, Microsoft (until January, 1998)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| Arnaud Le Hors, W3C
| Gavin Nicol, Inso EPS
| Jonathan Robie, Texcel Research
| Peter Sharpe, SoftQuad, Inc.
| Bill Smith, Sun (after November 1997)
| Jared Sorensen, Novell
| Robert Sutor, IBM
| Ray Whitmer, iMall
| Chris Wilson, Microsoft (after January, 1998)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

So, they (Microsoft) were involved in the process of creating the
Specification (probably more than we know, given the few DOM implementations
at the time), yet they did not manage to find that flaw. And from what I
can see, they even blew the chance to correct it until including 5 years
later, by not participating anymore despite their ongoing membership:

,-<http://www.w3.org/TR/DOM-Level-2-HTML/>
|
| Editors:
| Johnny Stenback, Netscape
| Philippe Le Hégaret, W3C
| Arnaud Le Hors, W3C and IBM (until November 2000)

Neither did they change their API (as they did on other occasions) to fit
the Specification, and if you say "at least one" that implies others were
stupid enough to copy that mistake. IOW: Microsoft could have easily done
something about it if they wanted, but did not, so they apparently did not
want. Now, who's to blame?


PointedEars
 
A

Andy Fish

That is not what I read. I read a procession of reports from
individuals who have no idea of how to analyse a problem and a certain
amount of speculation.

ok, I'll go back and have a closer look. from what I could see, the
examples (or at least some of them) in those posts should definitely
have worked
Again, that should be questioned.  If it is not a full document how
can it be validated, and if it is a full document inserting it into
another certainly will result in invalid mark-up. You know something
about these fragments, but so far you have not said exactly what it is
that you know about them.

ok although i accept the argument that a fragment of HTML cannot be
said to be valid HTML in isolation, i thought I made it clear when I
said that the resultant document was valid HTML. in other words, if
you simply did a text substitution to replace the fragment, the result
would be a valid HTML document
 
A

Andy Fish

Then it is possible to parse it.

thank you - the whole point of my question is to try and figure out
the best way to parse it
Therefore, as an alternative to HTML parsing, you need to fix the design
flaw in your application first, so that no non-XML-compliant markup reaches
the server in the first place

This is not a design flaw in my application. my application is
specifically designed to process non-XML-compliant mark-up.
 
T

Thomas 'PointedEars' Lahn

Andy said:
thank you - the whole point of my question is to try and figure out
the best way to parse it

Suppose you are looking for an ECMAScript-compliant solutions, as anything
else would be off-topic here, you should use a DPDA implementation that uses
Regular Expressions, i.e.

var m, rx = /.../, s = "...";
while ((m = rx.exec(s)))
{
...
}

Of course, SGML markup parsers exist for the server side (cf. W3C Markup
Validator), so you do not need to reinvent the wheel here.


PointedEars
 
D

Dr J R Stockton

In comp.lang.javascript message <324320a0-934f-449d-8f07-6a8f8ea57e76@g2
7g2000yqn.googlegroups.com>, Wed, 25 Nov 2009 05:02:00, Andy Fish
I have an application which uses Javascript ro replace an element's
innerHTML with a string of HTML retrieved from an Ajax call. In some
circumstances I get an "unknown runtime error" from IE which seems to
be a bug (if you google for innerHTML "unknown runtime error" you'll
see what I mean), and I have also had problems with Chrome too.


As I think you know, FAQ section 8.7 is relevant though not sufficient.



"8.7 How do I modify the content of the current page?" - that must
include addition and removal, as well as substitution.

The first example should show a function (and its use) :
function Wryt(ID, S) { document.getElementById(ID).innerHTML = S }

The second example, I think, will fail for plain insertion, and does not
address removal.

Including something like
while (Stk.hasChildNodes()) Stk.removeChild(Stk.lastChild)
will help those who have more already attached to Stk. NOTE : it is
only necessary to explain removal and addition in order to provide
substitution as well. The "clean slate" approach is simpler; and only
rarely will speed of execution be important.


The answer to your question should go in the FAQ, whether it is "do it
like this" or "it cannot be done reliably".


You say "in some circumstances". Could those include the "local
environment" of the target element? If so, might it be possible to
create a benignly-situated temporary target that would reliably allow
innerHTML to be set to ANY string? Then you could thus set your string
there and then transfer it to the desired region by uprooting and
replanting its sub-tree with DOM methods.
 
R

RobG

ok, I'll go back and have a closer look. from what I could see, the
examples (or at least some of them) in those posts should definitely
have worked

What is required is a definite statement of the issue and a minimal
example that demonstrates it.

From reading posts on the web and my limited testing, IE seems to have
an issue if updating the innerHTML property of an element results in
invalid markup. Here is a simple test case:

<div>
<p id="p0"></p>
<input type="button" value="Update inneHTML" onclick="
var p0 = document.getElementById('p0');
p0.innerHTML = '<li>I am an li</li>';
">
</div>

If the above is placed in a valid HTML document, clicking the button
will result in the innerHTML of the p element being set to invalid
markup. Firefox inserts an li element and displays the text, IE throws
an "Unknown runtime error".

ok although i accept the argument that a fragment of HTML cannot be
said to be valid HTML in isolation, i thought I made it clear when I
said that the resultant document was valid HTML. in other words, if
you simply did a text substitution to replace the fragment, the result
would be a valid HTML document

If you can demonstrate that, then post sample code or link.

You seem to want to be able to insert any HTML fragment into your
document and have the browser deal with it. That seems like an
unreasonable expectation.

If you want to insert HTML fragments into documents then you must
either:

1. Impose a restriction that fragments must result in a valid document
when inserted into, say, a div element (e.g. a fragment can't start
with an li tag)

or

2. You must inspect the first tag of the fragment and, depending on
the element that will become its parent, wrap the fragment in a
suitable element so that when it is inserted in the document the
result is valid markup

As for XML or XHTML, if you aren't going to use HTML you might as well
use JSON.
 
A

Andy Fish

ok thanks to everyone for all your help on this. It's clear there is
no magic bullet.

However, I was obviously a bit quick to assume that examples I found
on other forums were due to a bug or bugs in IE whereas it appears
they may have been down to malformed HTML documents, so I'll go back
and check this.

If innerHTML is reliable on all the browsers I want to support when
the HTML is valid, I am happy to continue using it.
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top