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

J

Jake Barnes

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?
 
R

RobG

Jake said:
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.
 
J

Jake Barnes

RobG said:
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
 
R

RobG

Jake said:
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. :)
 
J

Jake Barnes

RobG said:
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.
 
J

Jake Barnes

Ian said:
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.
 
J

Jake Barnes

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?
 
R

RobG

Jake said:
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.

[...]
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.


[...]
 
R

RobG

Jake said:
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).
 
D

dave cutts

function addEvent()
{
var ni = document.getElementById('myDiv');
var numi = document.getElementById('theValue');
var num = (document.getElementById("theValue").value -1)+ 2;
numi.value = num;
var divIdName = "my"+num+"Div";
var newdiv = document.createElement('div');
newdiv.setAttribute("id",divIdName);
newdiv.innerHTML = "<input type=\"text\" name=\"name["+num+"]\"> <a
href=\"javascript:;\"
onclick=\"removeEvent1(\'"+divIdName+"\')\">Remove</a>";
ni.appendChild(newdiv);
}

function removeEvent1(divNum)
{
var d = document.getElementById('myDiv');
var olddiv = document.getElementById(divNum);
d.removeChild(olddiv);
}

so why doesnt this add the input name in internet explorer but it inputs
it no probs in firefox?

how would i write this in dom?

Dave
 

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,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top