when I add HTML to innerHTML, FireFox renders it as HTML, but IE shows it as plain text

  • Follow


This weekend I wanted to learn AJAX, so I set up a little toy page
where I could experiment. The idea of this page is that you click in
one of the boxes to get some controls, at which point you can add text,
images, or HTML to the box. This seems to work fine in FireFox, but not
in IE. You can see the problem here:

http://www.publicdomainsoftware.org/ajaxExperiment.htm

In FireFox, if you click in a box and then select "Add HTML" you could
type in this:

<h1>Hello!</h1>

and it shows up as the word "Hello!" done as a first level header. But
if you do the same in IE, what you get is the above as plain text, with
the HTML tags appearing on the screen. Why is that?

0
Reply lkrubner (905) 2/6/2006 2:35:31 AM

Jake Barnes wrote:
> This weekend I wanted to learn AJAX, so I set up a little toy page
> where I could experiment. The idea of this page is that you click in
> one of the boxes to get some controls, at which point you can add text,
> images, or HTML to the box. This seems to work fine in FireFox, but not
> in IE. You can see the problem here:
> 
> http://www.publicdomainsoftware.org/ajaxExperiment.htm
> 
> In FireFox, if you click in a box and then select "Add HTML" you could
> type in this:
> 
> <h1>Hello!</h1>
> 
> and it shows up as the word "Hello!" done as a first level header. But

No it doesn't, you are still using your flawed script to get the 
innerHTML of a textarea element instead of the value property in several 
places.  Forget about innerHTML, use DOM.


-- 
Rob
0
Reply RobG 2/6/2006 3:30:47 AM


RobG wrote:
> No it doesn't, you are still using your flawed script to get the
> innerHTML of a textarea element instead of the value property in several
> places.  Forget about innerHTML, use DOM.

Why do you keep saying that? I'm not clear where in my script I'm doing
what you say. I've reversed the code from the way it was before. I now
get the value of the textarea first. If that returns nothing, I then
get try to get the innerHTML of the textarea. I figure the first should
work in most browsers, and the second will work in IE.

Anyway, could you explain how that throws off what HTML shows up on te
page here? 

http://www.publicdomainsoftware.org/ajaxExperiment.htm

0
Reply Jake 2/6/2006 6:41:52 AM

Jake Barnes wrote:
> RobG wrote:
> 
>>No it doesn't, you are still using your flawed script to get the
>>innerHTML of a textarea element instead of the value property in several
>>places.  Forget about innerHTML, use DOM.
> 
> 
> Why do you keep saying that? I'm not clear where in my script I'm doing
> what you say. I've reversed the code from the way it was before. I now
> get the value of the textarea first. If that returns nothing, I then
> get try to get the innerHTML of the textarea. I figure the first should
> work in most browsers, and the second will work in IE.
> 
> Anyway, could you explain how that throws off what HTML shows up on te
> page here? 
> 
> http://www.publicdomainsoftware.org/ajaxExperiment.htm
> 

Here is the start of your askForInput function with added comments:

   function askForInput(introText, exampleText) {
     var divRef =  getRefToInputDiv();

divRef is a reference to the DIV element with id="inputDiv".


     var communicationBoxRef =
          document.getElementById("communicationBox");

communicationBoxRef is a reference to a div too.


     communicationBoxRef.style.display = "block";
     communicationBoxRef.appendChild(divRef);

For some reason you chose to move inputDiv to become a child of cBoxRef, 
it could be coded as a child in the first place but maybe there is a 
reason.  Then you only need to show/hide the outer cBoxRef.


     divRef.style.display = "block";
     var area = document.getElementsByTagName('TEXTAREA')[0];

You get a reference to the text area using getElementsByTagName, but 
you've given it an ID, so why not use that (as you do a couple of lines 
later)?  Also, it would be very easy to put the text area into a form, 
then pass this.form from the button.  Now you can reference the text 
area using the form's elements collection - simpler and easier than 
either getElementsByTagName or getElementById.

     area.value = exampleText;


This sets the value of the text area to exampleText, nothing further is 
required.

     var divRef =  document.getElementById("inputBox");


Now divRef is overwritten with a reference to the text area element with 
id="inputBox", the same element as that referenced by 'area'.  area and 
divRef refer to the same element, until someone inserts another textarea 
element before it.

     if (divRef.innerHTML == "" || divRef.innerHTML == undefined) {
       divRef.innerHTML = exampleText; 	
     }

Now you go looking at the innerHTML of the textarea.  You have already 
set the value when you did area.value=exampleText, why try to set it 
again?  Everything after area.value=... to here is redundant.

There are many other examples of replicated functionality and convoluted 
logic, this is just one.  For example, the very next line you change 
divRef back to being a reference to inputDiv.

Anyhow, keep plugging away, I'm sure it's all clear as mud right now. :-)


-- 
Rob
0
Reply RobG 2/6/2006 7:35:14 AM

Jake Barnes wrote:
> RobG wrote:
> 
>>No it doesn't, you are still using your flawed script to get the
>>innerHTML of a textarea element instead of the value property in several
>>places.  Forget about innerHTML, use DOM.
> 
> 
> Why do you keep saying that? I'm not clear where in my script I'm doing
> what you say. I've reversed the code from the way it was before. I now
> get the value of the textarea first. If that returns nothing, I then
> get try to get the innerHTML of the textarea. I figure the first should
> work in most browsers, and the second will work in IE.
> 
Why do you even attempt to use innerHTML?  If there is no value, there 
is no input.

By the way, you claim this page to be XHTML 1.0 Strict and it most 
definitely isn't.

-- 
Ian Collins.
0
Reply Ian 2/6/2006 8:09:00 AM

RobG wrote:
> Jake Barnes wrote:
> > Anyway, could you explain how that throws off what HTML shows up on te
> > page here?
> >
> > http://www.publicdomainsoftware.org/ajaxExperiment.htm
> >
>
> Here is the start of your askForInput function with added comments:
>
>    function askForInput(introText, exampleText) {
>      var divRef =  getRefToInputDiv();
>
> divRef is a reference to the DIV element with id="inputDiv".

Oh wow. Thanks so much. You went way above and beyond any kind of
response that I was expecting. I thought my question might be a simple
one, but I guess not.





>      var communicationBoxRef =
>           document.getElementById("communicationBox");
>
> communicationBoxRef is a reference to a div too.
>
>
>      communicationBoxRef.style.display = "block";
>      communicationBoxRef.appendChild(divRef);
>
> For some reason you chose to move inputDiv to become a child of cBoxRef,
> it could be coded as a child in the first place but maybe there is a
> reason.  Then you only need to show/hide the outer cBoxRef.

Right, sorry. I guess I should have done more to prepare the code
before I asked a question. The reason why we append this block is so
that we can append other blocks, too. I'm assuming that in the near
future I might have 12 different input boxes, each with a different
specialty, and which one gets set into the communication div will
depend on some variable that I'll set in the code. I'm sorry I didn't
explain that earlier.





>      divRef.style.display = "block";
>      var area = document.getElementsByTagName('TEXTAREA')[0];
>
> You get a reference to the text area using getElementsByTagName, but
> you've given it an ID, so why not use that (as you do a couple of lines
> later)?

Right, that is confusing. I guess I was thinking that I might
eventually have lots of different inputs, but the one I'd want here
would always be the first textarea, but you're right, I could probably
do it just as easily with by ID.



>      area.value = exampleText;
>
>
> This sets the value of the text area to exampleText, nothing further is
> required.

Oh, I didn't realize that. The above line works in all browsers? IE,
FireFox, Safari, etc?




>      if (divRef.innerHTML == "" || divRef.innerHTML == undefined) {
>        divRef.innerHTML = exampleText;
>      }
>
> Now you go looking at the innerHTML of the textarea.  You have already
> set the value when you did area.value=exampleText, why try to set it
> again?  Everything after area.value=... to here is redundant.

I see. I didn't realize that area would work in IE. I thought you had
to use innerHTML in IE. My bad.

0
Reply Jake 2/6/2006 7:41:55 PM

Ian Collins wrote:
> Jake Barnes wrote:
> > RobG wrote:
> >
> >>No it doesn't, you are still using your flawed script to get the
> >>innerHTML of a textarea element instead of the value property in several
> >>places.  Forget about innerHTML, use DOM.
> >
> >
> > Why do you keep saying that? I'm not clear where in my script I'm doing
> > what you say. I've reversed the code from the way it was before. I now
> > get the value of the textarea first. If that returns nothing, I then
> > get try to get the innerHTML of the textarea. I figure the first should
> > work in most browsers, and the second will work in IE.
> >
> Why do you even attempt to use innerHTML?  If there is no value, there
> is no input.

I should just always use the value of the textarea instead? I guess I
thought the DOM stuff only worked in non-IE browsers, and that I had to
use innerHTML to work in IE, which is why I try both.



> By the way, you claim this page to be XHTML 1.0 Strict and it most
> definitely isn't.

Thanks, I know. I hope to clean up the page by Tuesday or Wednesday,
but for now it's just a page for me to play around with AJAX stuff. I'm
making too many changes too fast for me to keep it valid.

0
Reply Jake 2/6/2006 7:44:49 PM

Just to follow up on this, I'm hoping this is a real simple question,
but if I want to dynamically add this line to a page, how do I do it?

<h1>You're the greatest!</h1>

Right now I'm assigning it to the innerHTML of the divs, and that
works, but I'm told I'm not suppose to use innerHTML. What would be the
DOM way to do this?




Jake Barnes wrote:
> This weekend I wanted to learn AJAX, so I set up a little toy page
> where I could experiment. The idea of this page is that you click in
> one of the boxes to get some controls, at which point you can add text,
> images, or HTML to the box. This seems to work fine in FireFox, but not
> in IE. You can see the problem here:
>
> http://www.publicdomainsoftware.org/ajaxExperiment.htm
>
> In FireFox, if you click in a box and then select "Add HTML" you could
> type in this:
>
> <h1>Hello!</h1>
>
> and it shows up as the word "Hello!" done as a first level header. But
> if you do the same in IE, what you get is the above as plain text, with
> the HTML tags appearing on the screen. Why is that?

0
Reply Jake 2/6/2006 7:48:37 PM

Jake Barnes wrote:
> RobG wrote:
[...]
>>
>>     communicationBoxRef.style.display = "block";
>>     communicationBoxRef.appendChild(divRef);
>>
>>For some reason you chose to move inputDiv to become a child of cBoxRef,
>>it could be coded as a child in the first place but maybe there is a
>>reason.  Then you only need to show/hide the outer cBoxRef.
> 
> 
> Right, sorry. I guess I should have done more to prepare the code
> before I asked a question. The reason why we append this block is so
> that we can append other blocks, too. I'm assuming that in the near
> future I might have 12 different input boxes, each with a different
> specialty, and which one gets set into the communication div will
> depend on some variable that I'll set in the code. I'm sorry I didn't
> explain that earlier.

Consider putting them all in there using HTML source and display:none, 
then just show the one(s) you want.  Much simpler than moving nodes 
around the DOM.

[...]

> 
>>     area.value = exampleText;
>>
>>
>>This sets the value of the text area to exampleText, nothing further is
>>required.
> 
> 
> Oh, I didn't realize that. The above line works in all browsers? IE,
> FireFox, Safari, etc?

I would be very surprised if any browser supported JavaScript but not 
such basic DOM properties.


[...]


-- 
Rob
0
Reply RobG 2/6/2006 10:46:39 PM

Jake Barnes wrote:
> Just to follow up on this, I'm hoping this is a real simple question,
> but if I want to dynamically add this line to a page, how do I do it?
> 
> <h1>You're the greatest!</h1>
> 
> Right now I'm assigning it to the innerHTML of the divs, and that
> works, but I'm told I'm not suppose to use innerHTML. What would be the
> DOM way to do this?

HTML:

<div id="divA"></div>


Script & W3C DOM:

    if (document.getElementById && document.createElement){
      var divA = document.getElementById('divA');
      var oH = document.createElement('h1');
      oH.appendChild(document.createTextNode('You\'re the greatest'));
      // Insert the heading as the first child of the element
      divA.insertBefore(oH, divA.firstChild);
    }


The same thing done with innerHTML would be something like:

    if (document.getElementById){
      var divA = document.getElementById('divA');
      var aHTML = divA.innerHTML;
      if ('string' == typeof aHTML){
        // Insert the heading at the start of the element
        divA.innerHTML =  aHTML + <h1>You\'re the greatest</h1>';
      }
    }


Some reasons not to use innerHTML:

1. There are differences between implementations (as you discovered), 
but there is no public standard so you can't say what is right or wrong 
behaviour.  Since it was invented by MS for IE, you could say that 
whatever IE does it right and anything else is wrong.

2.  Replacing the innerHTML means that the browser must re-parse and 
re-render everything, whereas with DOM the effort should be less - you 
are only adding/removing bits.

3.  innerHTML has to be put inside something, it's very hard to insert a 
new element between two others.  MS also invented insertAdjacentElement, 
insertAdjacentHTML and insertAdjacentText to do that.  The same 
functionality is provided W3C DOM methods appendChild and insertBefore 
(which are also supported by IE).

4.  It is harder to debug scripts that use innerHTML, it's kind of a 
black box since the JS engine squirts HTML at the rendering engine and 
generally any errors in the HTML are not reported back, so you don't 
really know if it works or not.

The bottom line is that DOM methods are more widely supported (i.e. more 
browsers support them) and generally use a simpler set of instructions 
to achieve the same goal (it's a bit like CISC vs RISC in that regard).

The best idea is to code using a Gecko browser (say Firefox or Mozilla), 
then test in others, particularly IE.  Some really like Opera, Safari is 
OK for development but I prefer Firefox (though I prefer to surf the web 
using Safari).


-- 
Rob
0
Reply RobG 2/6/2006 11:27:16 PM

9 Replies
2841 Views

(page loaded in 0.425 seconds)


Reply: