innerHTML += onload : how do I do it the right way ?

P

pamelafluente

Hi

It's 2 days I am struggling with 1 stupid line of code.
I have the following function which works if I do not do the dynamic
code insert:

document.body.innerHTML += "<form name='form1'
method='GET'><input type='hidden' name='actionCodes'
id='actionCodesField' /></form>"

But if I add the above, the handlers are no more attached. I cannot
understand what is my error? Am I doing it the wrong way? Perhaps it's
wrong to do this onload ? Can anybody help and show me the right way to
add code to the body onload ?

-Pam


---------- function

window.onload = addHandlers;

function addHandlers() {

var DivInstanceID = document.getElementById("InstanceID");
if ( DivInstanceID != null ) {
InstanceID = DivInstanceID.getAttribute("InstanceID");
}

window.status = "Attaching Drill down / Roll up handlers...";

var aDivs = document.getElementsByTagName("div");
var divElement;
for ( var i = 0; i < aDivs.length; i++ ) {

divElement = aDivs;

if ( divElement.getAttribute(EnabledActionsAttribute) != null )
{
divElement.onclick = function(event) { doOnclick(event,
this) };
divElement.onmouseover = function() { doOnmouseover(this)
};
divElement.onmouseout = function() { doOnmouseout(this) };

}
}


document.body.innerHTML += "<form name='form1'
method='GET'><input type='hidden' name='actionCodes'
id='actionCodesField' /></form>"

window.status = "handlers attached";
}
 
M

Martin Honnen

It's 2 days I am struggling with 1 stupid line of code.
I have the following function which works if I do not do the dynamic
code insert:

document.body.innerHTML += "<form name='form1'
method='GET'><input type='hidden' name='actionCodes'
id='actionCodesField' /></form>"

Well as you yourself have choosen the call that line stupid I can only
agree, the approach is wrong.
someElement.innerHTML += someMarkup
is the same as
someElement.innerHTML = someElement.innerHTML + someMarkup
which means you are forcing the browser to serialize the contents of the
element to a string of HTML (in your case the complete contents of the
body), then to concatenate that string with someMarkup and finally to
parse the whole string again as HTML into new child nodes to be inserted
into the element. If you want to append content to an element then don't
use innerHTML +=, simply create the contents to be appended with the DOM
methods (e.g. createElement, createTextNode) and appendChild that new
contents to the element. That way the browser does not have to reparse
anything that has already been parsed. And the flaws (like event
handlers going lost) that approach might have will disappear.

Even if you don't want to use createElement/createTextNode but prefer to
use a snippet of HTML markup then parse it in a way (e.g. with
insertAdjacentHTML or emulations of that) that only the new markup has
to be parsed, but not the existing contents has to be serialized and
parsed again for no gain at all.
 
P

pamelafluente

Martin Honnen ha scritto:

Well as you yourself have choosen the call that line stupid I can only
agree, the approach is wrong.

Thanks Martin, actually now that you explained the mechanism, it
seems quite ridiculous to do that in such a way. I was not realizing
the implication of doing innerHTML += with the body.

Do you have a simple practical example from which I can see the
way to do it? Besides the above line, I have a few other lines I want
to add,
and I can do by myself if I get the general mechanism.

Thanks again,

-Pam
 
M

Martin Honnen

Do you have a simple practical example from which I can see the
way to do it? Besides the above line, I have a few other lines I want
to add,
and I can do by myself if I get the general mechanism.

var form = document.createElement('form');
form.action = 'whatever.aspx';
form.method = 'GET';
var input = document.createElement('input');
input.type = 'hidden';
input.name = 'actionCodes';
input.id = 'actionCodesField';
form.appendChild(input);
document.body.appendChild(form);
 
P

pamelafluente

I am trying to apply what you just tought me to the following simple
case:


<div id="menuActions" style="position:absolute; display:none">
<table >
<tr>
<td bgcolor="#eeaa66" style="width: 15px"> </td>
<td id="menuItemContainer"></td>
</tr>
</table>
</div>


So, imitating you, I come up with:

var Menu = document.createElement('div');
Menu.id = "menuActions" ;
Menu.style="position:absolute; display:none" ;

var MyTable = document.createElement('table');
var Mytr = document.createElement('tr');
var Mytd = document.createElement('td');
Mytd.bgcolor="#eeaa66";
Mytd.style="width: 15px";
Mytd.id="menuItemContainer";

Mytr.appendChild(Mytd);
MyTable.appendChild(Mytr);
Menu.appendChild(MyTable);
document.body.appendChild(Menu);


mmm ... but the menu is not coming up anymore,
do you see what I am missing here ?


Also a question. For the form you did for me, I created a public
variable to access it outside the function.
Is there a what to get it without declaring a public variable
(like we have getElementById or similar) ?


-Pam
 
R

RobG

I am trying to apply what you just tought me to the following simple
case:


<div id="menuActions" style="position:absolute; display:none">
<table >
<tr>
<td bgcolor="#eeaa66" style="width: 15px"> </td>
<td id="menuItemContainer"></td>
</tr>
</table>
</div>


So, imitating you, I come up with:

var Menu = document.createElement('div');
Menu.id = "menuActions" ;
Menu.style="position:absolute; display:none" ;

You can't set the style properties that way, use:

Menu.style.position = 'absolute';
Menu.style.display = 'none';

But if you use CSS to do that, you don't need to script it:

<style type="text/css">
#menuActions {position:absolute; display:none;}
var MyTable = document.createElement('table');

For IE, you need to create and append a tbody element before appending
rows. Other browsers will do it automatically as happens in HTML, IE
requires you to do it manually when creating a table using DOM Core
methods. Alternatively, use the DOM HTML shortcuts (see below).
var Mytr = document.createElement('tr');
var Mytd = document.createElement('td');

You can to that more simply as:

var MyTable = document.createElement('table');
var Mytr = MyTable.insertRow(-1);
var Mytd = Mytr.insertCell(-1);

Mytd.bgcolor="#eeaa66";

The bgcolor attribute is deprecated, use the CSS background-color
property:

Mytd.style.backgroundColor = "#eeaa66";

Mytd.style="width: 15px";

Mytd.style.width = "15px";

Mytd.id="menuItemContainer";

Mytr.appendChild(Mytd);
MyTable.appendChild(Mytr);

If you use insetRow/Cell, those elements are already appended and you
don't need the above two lines of code (or to create and add a tbody).
 
P

pamelafluente

RobG ha scritto:

If you use insetRow/Cell, those elements are already appended and you
don't need the above two lines of code (or to create and add a tbody).

Thanks Rob,

finally this is the result:



// MENU CONTAINER

Menu = document.createElement('div');
Menu.style.position = 'absolute';
Menu.style.display = 'none';

var MyTable = document.createElement('table');
var Mytr = MyTable.insertRow(-1);
var Mytd0 = Mytr.insertCell(-1);
Mytd0.style.backgroundColor = "#eeaa66";
Mytd0.style.width = '15px';

var Mytd1 = Mytr.insertCell(-1);
Mytd1.id = 'menuItemContainer';

Menu.appendChild(MyTable);
document.body.appendChild(Menu);



Thanks! It works beautifully both with IE and FF.



You guys here are better than the best book! :)
 
D

dd

You know that once you've created the div and
appended it to the body, you're then free to
add the form and table as a string using the
innerHTML property of the div.

So instead of:

-code to create div element-
-code to create table-
-append table to div-
-append div to body-

You could do this:

-code to create div element-
-append div to body-
-set innerHTML of div with "<table><tr><td>" etc

This may or may not be preferrable. It's certainly
less code. No need to insertRow or insertCell etc.

Just throwing it out there as an alternative.
 
P

pamelafluente

dd ha scritto:
You know that once you've created the div and
appended it to the body, you're then free to
add the form and table as a string using the
innerHTML property of the div.

So instead of:

-code to create div element-
-code to create table-
-append table to div-
-append div to body-

You could do this:

-code to create div element-
-append div to body-
-set innerHTML of div with "<table><tr><td>" etc

wow. Thanks dd. This actually seems a good idea.
I have no idea whether it's technically "better", but it is perhaps
more "readable" (?).

-Pam
 

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,996
Messages
2,570,238
Members
46,826
Latest member
robinsontor

Latest Threads

Top