table.rows vs. table.getElementsByTagName (+ a regex question)

E

eBob.com

I am so frustrated. I've been working all weekend on what I thought would
be a simple script. I never find it easy to look at someone else's code,
but if someone can help with this I would be very grateful. The script is
....

<script type="text/javascript">
var parentwin = external.menuArguments;
var doc = parentwin.document;
var x = doc.getElementsByTagName("table")
alert(x.length + " table things")
var re = /class='class_18'>(\w+)<\/td>/

for (iv in x)
{
var tablerows = x[iv].rows
//alert(tablerows.length + " rows") // results in "'tablerows.length' is
// null or not an object ???????

//var tablerows2 = x[iv].getElementsByTagName("tr") // results in "Object
doesn't
// support this
property or method ??????

for (triv in tablerows)
{
alert("triv is \""+ triv + "\"; outerHTML:" +
tablerows[triv].outerHTML)

var marray = re.exec(tablerows[triv].outerHTML)
//var marray = re.exec("<td align='center' class='class_18'>Name</td>")
alert("marray is " + marray)
if (marray != null)
{ alert("match[0] " + marray[0])
alert("match[1] " + marray[1])
}
} // end of for (triv in tablerows)
} // end of for (iv in x)
</script>

And the HTML I am running it against is ...

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<table cellpadding='0' cellspacing='0' border='0' align='center'>
<tr>
<td align='center' class='class_18'>Name</td>
<td align='center' class='prl5 class_10'> | </td>
<td align='center' class='class_19'>4328-5352</td>
</tr>
</table>
</html>

1) Why can't I get the length of tablerows after the var tablerows =
x[iv].rows statement? I'm only interested in a one-row table, so I could
save some processing if I could get the length.

2) Why doesn't x[iv].getElementsByTagName("tr") work?

3) Why do I go through the loop for (triv in tablerows) twice when there
is only one row in the table? AND when I go through the loop the first time
the value of triv is "length" and the value of the outerHTML is "undefined"?

4) Why doesn't the regular expression work when fed the outerHTML but does
when fed the text contained in the HTML?

It was a frustrating weekend and I will appreciate any help anyone can
offer. Thanks, Bob
 
M

Martin Honnen

eBob.com said:
I am so frustrated. I've been working all weekend on what I thought would
be a simple script. I never find it easy to look at someone else's code,
but if someone can help with this I would be very grateful. The script is
...

<script type="text/javascript">
var parentwin = external.menuArguments;
var doc = parentwin.document;
var x = doc.getElementsByTagName("table")
alert(x.length + " table things")
var re = /class='class_18'>(\w+)<\/td>/

for (iv in x)

x is a DOM node list, don't use for..in with that, use a for loop
for (var i = 0, l = x.length; i < l; i++)
{
var table = x;
}

for..in enumerates enumerable properties of an object and that is
usually not the right way to iterate over DOM collections.
 
E

eBob.com

eBob.com said:
I am so frustrated. I've been working all weekend on what I thought would
be a simple script. I never find it easy to look at someone else's code,
but if someone can help with this I would be very grateful. The script is
...

<script type="text/javascript">
var parentwin = external.menuArguments;
var doc = parentwin.document;
var x = doc.getElementsByTagName("table")
alert(x.length + " table things")
var re = /class='class_18'>(\w+)<\/td>/

for (iv in x)
{
var tablerows = x[iv].rows
//alert(tablerows.length + " rows") // results in "'tablerows.length'
is
// null or not an object ???????

//var tablerows2 = x[iv].getElementsByTagName("tr") // results in
"Object doesn't
// support this
property or method ??????

for (triv in tablerows)
{
alert("triv is \""+ triv + "\"; outerHTML:" +
tablerows[triv].outerHTML)

var marray = re.exec(tablerows[triv].outerHTML)
//var marray = re.exec("<td align='center'
class='class_18'>Name</td>")
alert("marray is " + marray)
if (marray != null)
{ alert("match[0] " + marray[0])
alert("match[1] " + marray[1])
}
} // end of for (triv in tablerows)
} // end of for (iv in x)
</script>

And the HTML I am running it against is ...

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<table cellpadding='0' cellspacing='0' border='0' align='center'>
<tr>
<td align='center' class='class_18'>Name</td>
<td align='center' class='prl5 class_10'> | </td>
<td align='center' class='class_19'>4328-5352</td>
</tr>
</table>
</html>

1) Why can't I get the length of tablerows after the var tablerows =
x[iv].rows statement? I'm only interested in a one-row table, so I could
save some processing if I could get the length.

2) Why doesn't x[iv].getElementsByTagName("tr") work?

3) Why do I go through the loop for (triv in tablerows) twice when
there is only one row in the table? AND when I go through the loop the
first time the value of triv is "length" and the value of the outerHTML is
"undefined"?

4) Why doesn't the regular expression work when fed the outerHTML but does
when fed the text contained in the HTML?

It was a frustrating weekend and I will appreciate any help anyone can
offer. Thanks, Bob

Sorry, I forgot to specify that I run the script under IE 6.0.
 
T

Thomas 'PointedEars' Lahn

[trimmed attribution novel]

eBob.com said:
eBob.com said:
var parentwin = external.menuArguments;
[...] for (iv in x)
{
var tablerows = x[iv].rows
//alert(tablerows.length + " rows") // results in "'tablerows.length'
is
//var tablerows2 = x[iv].getElementsByTagName("tr") // results in
"Object doesn't
// support this
property or method ??????

As you can see by now at last, pre-commenting is much better than
post-commenting. Your Question Mark key is borken, BTW.
for (triv in tablerows)
{
alert("triv is \""+ triv + "\"; outerHTML:" +
tablerows[triv].outerHTML)

This can be written less error-prone and easier legible:

window.alert('triv is "' + triv + '";'
+ ' outerHTML: ' + tablerows[triv].outerHTML);
var marray = re.exec(tablerows[triv].outerHTML)

Why not String.prototype.match() instead?
//var marray = re.exec("<td align='center'
class='class_18'>Name</td>")
[...]

Sorry, I forgot to specify that I run the script under IE 6.0.

I suppose one can guess that from your using the `external' property.

However, Martin's correct explanation still stands. Iteration over the
enumerable properties of a NodeList object for which the reference is
returned by document.getElementsByTagName("table") yields the `length'
property as well in IE 6. And a number value if implicitly converted
into a Number object does not have a getElementsByTagName() method.

Same with the NodeList object reference that tableRows evaluates to.
tableRows["length"] yields a number, and the Number object it is being
converted to does not have an outerHTML property. The result of the
expression therefore is `undefined', and literally "undefined" when
implicitly converted to string by RegExp.prototype.exec(). So your
Regular Expression can't find a match.

Please trim your quotes as recommended e.g. in the FAQ Notes.


PointedEars
 
E

eBob.com

Thank you very, VERY much Thomas and Martin! I would have struggled with
this problem for a long, long time without your help.

One loose end ... I have done some more research and learned about
Enumerators. I tried an Enumerator to step through the table rows and it
seems to work. Is there any practical difference between ...

for (var triv = 0, l = tablerows.length; triv < l; triv++)

and ...

var enumTableRows = new Enumerator(tablerows)
for (;!enumTableRows.atEnd();enumTableRows.moveNext())

?

Also, I discovered the problem with my regular expression. After an eyeball
tuneup I saw that document does quite a bit of massaging of the HTML. So my
regular expression, based on the original HTML, didn't have a chance of
working.

Thanks again for your very prompt and thorough help. Bob
 
M

Martin Honnen

eBob.com said:
One loose end ... I have done some more research and learned about
Enumerators. I tried an Enumerator to step through the table rows and it
seems to work. Is there any practical difference between ...

for (var triv = 0, l = tablerows.length; triv < l; triv++)

and ...

var enumTableRows = new Enumerator(tablerows)
for (;!enumTableRows.atEnd();enumTableRows.moveNext())

?

Enumerator is specific to Microsoft JScript, don't expect that to work
with other browsers or script engines.
 

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,997
Messages
2,570,241
Members
46,831
Latest member
RusselWill

Latest Threads

Top