Accessing named elements

  • Thread starter Christopher Benson-Manica
  • Start date
C

Christopher Benson-Manica

When are named elements written with script accessible to script?

<html><head><script type="text/javascript">
function ready() {
alert( document.getElementsByName("div").length );
}
</script></head>
<body onload="ready()">
<script type="text/javascript">
document.open();
document.writeln( "<div name=\"div\"><\/div>" );
document.close();
</script>
</body></html>

IOW, why are there 0 elements named div at the time the <body>
element's onload handler is invoked? When can I retrieve this named
div from the document hierarchy?

This exercise is necessary since code I have written using the DOM
(that works) has to run on God-forsaken browsers such as IE 5.1 for
Mac whose support for the DOM is spotty at best.
 
R

RobG

Christopher said:
When are named elements written with script accessible to script?

<html><head><script type="text/javascript">
function ready() {
alert( document.getElementsByName("div").length );
}
</script></head>
<body onload="ready()">
<script type="text/javascript">
document.open();
document.writeln( "<div name=\"div\"><\/div>" );
document.close();
</script>
</body></html>

IOW, why are there 0 elements named div at the time the <body>
element's onload handler is invoked? When can I retrieve this named
div from the document hierarchy?

Because "getElementsByName()" works on the name attribute, not the
tag name. I think you mean to call "getElementsByTagName()".

[...]
 
C

Christopher Benson-Manica

Because "getElementsByName()" works on the name attribute, not the
tag name. I think you mean to call "getElementsByTagName()".

As you can see, the element is named "div", so I would expect
getElementsByName() to retrieve it; in IE 6, at least, it does not.
 
M

Michael Winter

When are named elements written with script accessible to script?

I believe it varies. Closing the document stream with the close method
might flush the output and update the document tree, however a user
agent might wait until the it finishes executing the code in the
SCRIPT block. I should be asleep now, so any tests on my part will
have to wait until later today. :p

[snip]
document.writeln( "<div name=\"div\"><\/div>" );
[snip]

When can I retrieve this named div from the document hierarchy?

You shouldn't ever be able to, at least not by name. DIV elements
don't have name attributes. Why aren't you using the id attribute?

[snip]

Mike
 
R

RobG

Christopher said:
As you can see, the element is named "div", so I would expect
getElementsByName() to retrieve it; in IE 6, at least, it does not.

Sorry, missed that and canceled the message.

It's not a good idea to use attribute values that are the same as tag
names, it gets confusing. It is invalid to give a div a name, only
button, textarea, applet, select, form, frame, iframe, img, a,
input, object, map, param and meta elements are allowed a 'name'
attribute.

If the intention is to get a single element, getElementById should be
used (and the div given an id). To get collections, you can use
getElementsByTagName within a div to get all the child divs, or you
can write your own 'getElementsByClassName' to create an array of all
elements of a particular class.

For the record, your code 'works' in Firefox...
 
C

Christopher Benson-Manica

Michael Winter said:
I believe it varies. Closing the document stream with the close method
might flush the output and update the document tree, however a user
agent might wait until the it finishes executing the code in the
SCRIPT block. I should be asleep now, so any tests on my part will
have to wait until later today. :p

Well, in my case it should have completed executing the code in the
You shouldn't ever be able to, at least not by name. DIV elements
don't have name attributes. Why aren't you using the id attribute?

It was a poorly-chosen example for that very reason :| What I really
want to do is build a table with several columns, with the cells in
each column having the same name. As I alluded to in my original
post, what I want to do is very convenient using the DOM, but
unfortunately it isn't an option. I'm trying to find a way to get the
named cells into separate arrays for easy access later; maybe I'll
have to wait until I intend to use them before attempting to
getElementsByName().
 
C

Christopher Benson-Manica

RobG said:
It's not a good idea to use attribute values that are the same as tag
names, it gets confusing. It is invalid to give a div a name, only
button, textarea, applet, select, form, frame, iframe, img, a,
input, object, map, param and meta elements are allowed a 'name'
attribute.

Duly noted on both points - it was a somewhat frustrating Monday at
work. Do see my reply to Michael though - I didn't elucidate my
actual intentions very well to start with.
For the record, your code 'works' in Firefox...

If I had a dollar for every time I've written something that "works"
in one browser but not another I'd be independently wealthy by now :(i
 
R

RobG

Christopher Benson-Manica wrote:
[...]
It was a poorly-chosen example for that very reason :| What I really
want to do is build a table with several columns, with the cells in
each column having the same name. As I alluded to in my original
post, what I want to do is very convenient using the DOM, but
unfortunately it isn't an option. I'm trying to find a way to get the
named cells into separate arrays for easy access later; maybe I'll
have to wait until I intend to use them before attempting to
getElementsByName().

Except that TDs aren't allowed names either. I'm a bit confused: you
say DOM isn't an option, does this infer that you intend giving each
cell a unique id that includes a row & column reference? (see option
5 below)

I don't have access to IE 5.1 on Mac right now (I can get to a
Mac OS 9.2.2 machine, if that is appropriate, but it will take a few
hours...) but I can offer the following:

1. If you are building the table dynamically, add the table cells to
arrays as you go. I'm not sure this is a good idea, pages should
not be utterly dependent on JavaScript but if this is for a web
application on an intranet or special interest site, it may be OK.

2. You can access cells using the rows and cells collections (not
sure of IE 5.1 Mac support here) to get an effect similar to
arrays. To do something to every cell in column zero (from bottom
to top):

var j = 0; // column number
var i = table.rows.length;
while (i--){
// do something with tableRef.rows.cells[j];
}

3. Use the rows & cells collections to build arrays of references to
the cells in each column:

var col_0 = [];
for (var i=0, len=tableRef.rows.length; i<len; i++){
col_0.push(tableRef.rows.cells[0]);
}

will create an array of references to the cells in column zero
with the cell's array index equal to its row index.

4. Give the cells in each row a class of their column number, then
either write your own 'getElementsByClassName' or use the class
name as a selector when iterating through the cells.

Note that the class name does not have to be defined anywhere, and
elements can have multiple classes.

<table>
<tr class="pretty row1">
<td class="bland column-0"></td>
<td class="bland special column-1"></td>
<td class="bland column-2"></td>
</tr>
...

I think this method is very slow, why isn't there a native
version?

5. Give each cell a unique ID that includes a column number
identifier, e.g. the cells in row 0 could be:

<td id="row_0-col_0></td>
<td id="row_0-col_1></td>
<td id="row_0-col_2></td>

But this seems to be to be very close to addressing them by the
table rows & cells collections.

Your page layout may dictate which method is used. If you have TDs
spanning columns, you may not be able to use the rows & cells
collections.
 
C

Christopher Benson-Manica

RobG said:
Except that TDs aren't allowed names either. I'm a bit confused: you
say DOM isn't an option, does this infer that you intend giving each
cell a unique id that includes a row & column reference? (see option
5 below)

Considering that this is a stupid hack anyway, I'm willing to forgo
strict compliance for the sake of something resembling a clean
implementation :)

Why did W3C eliminate the name attribute for so many things? This
situation would seem to be a good argument for keeping it around...
I don't have access to IE 5.1 on Mac right now (I can get to a
Mac OS 9.2.2 machine, if that is appropriate, but it will take a few
hours...) but I can offer the following:

Take your time - I don't think I can afford your consulting fee! ;)
1. If you are building the table dynamically, add the table cells to
arrays as you go. I'm not sure this is a good idea, pages should
not be utterly dependent on JavaScript but if this is for a web
application on an intranet or special interest site, it may be OK.

Well, that's what I was doing with the DOM, but 5.1 Mac (apparently)
has some beef with setting the type of input elements produced by
document.createElement(). It also doesn't seem to like insertRow and
insertCell much either, making for a still more cluttered
implementation...
var j = 0; // column number
var i = table.rows.length;
while (i--){
// do something with tableRef.rows.cells[j];
}


Hm, this might be worth a shot. I'll try it when I get to work.
But this seems to be to be very close to addressing them by the
table rows & cells collections.

It may turn out to be more to 5.1 Mac's liking, though, so I'll keep
it in mind.
Your page layout may dictate which method is used. If you have TDs
spanning columns, you may not be able to use the rows & cells
collections.

I do have one <td> with colspan, so I'll be on the lookout for that.
Thanks for the suggestions - I'm sure one of them will work.
 
M

Michael Winter


I was going to suggest ideas along the lines that Rob explored, so I
suppose all that's left is this little bit...
Considering that this is a stupid hack anyway, I'm willing to forgo
strict compliance for the sake of something resembling a clean
implementation :)

Why did W3C eliminate the name attribute for so many things? This
situation would seem to be a good argument for keeping it around...

You're wishing for something that never existed in the first place.

The name attribute only existed on a select few elements. It was
/never/ used on DIVs, table cells, and the like. Moreover, the only
time one could use named elements as a group was with form controls
within a FORM element. For other elements, name acted exactly like the
id attribute does now, which is why id is the preferred way of
identifying elements. After all, what's the point of using two
different attributes to do the same thing when one of them was
specifically designed to accomplish that task on its own?

I will agree that there isn't much scope for grouping elements at
different nested levels (such as cells in table columns), but then
there never was. You'll just have to put up with grouping by class or
formatted id attributes.

[snip]

Mike
 
R

RobG

Christopher said:
Considering that this is a stupid hack anyway, I'm willing to forgo
strict compliance for the sake of something resembling a clean
implementation :)

Why did W3C eliminate the name attribute for so many things? This
situation would seem to be a good argument for keeping it around...

I guess there's an explaination somewhere.

I jumped on a machine with IE 5.0 (circa 2000) on Mac OS 9.1 - I was
quite surprised at the level of DOM support.

[...]
Well, that's what I was doing with the DOM, but 5.1 Mac (apparently)
has some beef with setting the type of input elements produced by
document.createElement(). It also doesn't seem to like insertRow and
insertCell much either, making for a still more cluttered
implementation...

But it quite happily adds rows and cells using createElement, insert
row/cell seemed to work OK too but if both createElement and insert
row/cell were used, funny results could be achieved.

IE will create text inputs with "createElement('input')", you are
right about it barfing on 'type', creating input buttons is
impossible and something like:

var oBtn = document.createElement('input');
if (oBtn.type) {
// change type
} else {
oBtn = document.createElement('button');
...

dies at "if (oBtn.type)" but you can create buttons using:

var oBtn = document.createElement('button');
oBtn.innerHTML = 'The button label';
oBtn.onclick = function() {alert('hi from the new button')};
tbl.appendChild(oBtn);


I could also create text areas and set attributes:

var oTA = document.createElement('textarea');
oTA.rows = 30;
oTA.cols = 50;
tbl.appendChild(oTA);


works fine. It even supports both getElementByTagName and
document.all.

var j = 0; // column number
var i = table.rows.length;
while (i--){
// do something with tableRef.rows.cells[j];
}



Hm, this might be worth a shot. I'll try it when I get to work.


Works fine in 5.0
It may turn out to be more to 5.1 Mac's liking, though, so I'll keep
it in mind.




I do have one <td> with colspan, so I'll be on the lookout for that.
Thanks for the suggestions - I'm sure one of them will work.

You can use multiple tbody elements to seperate the sections of a
table. With IE you have to add new elements to the tbody anyway, not
the table.


Time for sleep ...
 
C

Christopher Benson-Manica

RobG said:
IE will create text inputs with "createElement('input')", you are
right about it barfing on 'type', creating input buttons is
impossible and something like:

Creating checkboxes is also impossible - thankfully I don't need them
here.
Works fine in 5.0

Well, everything I had worked fine in 5.0, which is why I was
extremely dismayed to learn that Mac IE 5.1 could not handle it.
You can use multiple tbody elements to seperate the sections of a
table. With IE you have to add new elements to the tbody anyway, not
the table.

Right.
 
L

Lachlan Hunt

Christopher said:
When are named elements written with script accessible to script?

Immediately if they're added using proper object-oriented DOM methods,
and they don't even need a name to be accessible.
document.writeln( "<div name=\"div\"><\/div>" );

Why don't you use the proper DOM methods to manipulate the DOM, rather
than the silly document.write() and .writeln() functions; which, IMHO,
should be deprecated.

function init() {
var div = document.createElement("div");
document.getElementsByTagName("body").item(0).appendChild(div);
div.appendChild(document.createTextNode("Hello World!"));
}
window.onload = init;

That way, you already have a variable referring to the node (which you
can add to a collection of some kind if you need more than one), so
there's no need to find it again later with .getElementsByName(), or the
better .getElementById() functions.

You also seperate the structure and content (markup) from the behaviour
(script) by dynamically assigning the event handler, rather then using
the onload attribute, and not mixing crappy document.write() statements
throughout the document. It will work as an external script in a
seperate file, which means it can be more easily be added to multiple
documents.
 
L

Lachlan Hunt

RobG said:
oBtn.innerHTML = 'The button label';

The standardised createTextNode() method should be used here, rather
than the non-standard, proprietary innerHTML extension:

oBtn.appendChild(document.createTextNode("Button Label"));
 
C

Christopher Benson-Manica

Lachlan Hunt said:
Why don't you use the proper DOM methods to manipulate the DOM, rather
than the silly document.write() and .writeln() functions; which, IMHO,
should be deprecated.

As I said in my original post, I'd like to, but IE 5.1 Mac can't
handle it.
 
J

John W. Kennedy

Lachlan said:
Immediately if they're added using proper object-oriented DOM methods,
and they don't even need a name to be accessible.



Why don't you use the proper DOM methods to manipulate the DOM, rather
than the silly document.write() and .writeln() functions; which, IMHO,
should be deprecated.

Actually, they are. They don't exist in XHTML. Unfortunately, Microsoft
has brought progess in this area to a grinding halt by refusing to
support XHTML.

--
John W. Kennedy
"The bright critics assembled in this volume will doubtless show, in
their sophisticated and ingenious new ways, that, just as /Pooh/ is
suffused with humanism, our humanism itself, at this late date, has
become full of /Pooh./"
-- Frederick Crews. "Postmodern Pooh", Preface
 

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,763
Messages
2,569,563
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top