By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
432,462 Members | 799 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 432,462 IT Pros & Developers. It's quick & easy.

looping through <li>'s

P: n/a
Hopefully I 'm missing something silly, but I can't find an easy way to loop
all list items in a simple <ol>. I was hoping a for loop as shown below
would be enough, however clicking "alert all" in the following example gives
me all but the first <li> element. The alertfirst() function finds the first
<li> with no problem. There are multiple lists on the page, so
getElementsByTagName('li') is probably not the most elegant solution. Btw.
my Mozilla crashed when I tried this code, but this is for IE only.

<script type="text/javascript">
function alertfirst() {
var ol=document.getElementsByTagName('ol')[0];
alert( ol.firstChild.firstChild.nodeValue );
}
function alertall() {
var ol=document.getElementsByTagName('ol')[0];
for( var i=ol.firstChild; i=i.nextSibling; i!==null) {
alert( i.firstChild.nodeValue );
}
}
</script>
<ol>
<li>first</li>
<li>second</li>
<li>third</li>
</ol>
<a href="" onclick="alertfirst();return false">alert first</a>
<a href="" onclick="alertall();return false">alert all</a>

Thanks ia,
Mark
Jul 23 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a


Mark wrote:

var ol=document.getElementsByTagName('ol')[0];


You can and probably want to call getElementsByTagName on the ol element:
var listItems = ol.getElementsByTagName('li');
for (var i = 0; i < listItems.length; i++) {
...
}
--

Martin Honnen
http://JavaScript.FAQTs.com/
Jul 23 '05 #2

P: n/a
Mark wrote:
Hopefully I 'm missing something silly, but I can't find an easy way to loop


Yes!

Seeing as how you've discounted getElementsByTagName('li'), then I guess
we can start at the point where you have a reference to an OL element -
say getElementsByTagName('ol') or getElementById('someOLid').

Now you can just recurse (is there such a word?) down the tree and test
for LI nodes. Some code follows - it's cross browser, it'll work in
Mozilla, Safari and *gasp* IE too - and it will travel down all LIs,
even if you nest several lists (as in the example), but will not escape
the starting node.

The reason your code:

ol.firstChild.firstChild.nodeValue

fails in the zillas is because of the following:

ol.firstChild will grab the first child (a text node) which doesn't have
any children, so there is no ol.firstChild.firstChild and that's where
the script will (likely) end.

Firefox and other similar browsers (including Safari) add text nodes
after just about everything, including UL and OL nodes, so the
firstChild of an OL (or UL for that matter) is a text node type 3 with
zero children. Trying to get the child of a node with no children will
fail.

Did you try using Mozilla's inspector? (Firefox and Safari have
excellent DOM inspectors too).

IE doesn't add the useless text node, so that's likely why your code
works in IE. Without knowing it, your code is IE specific.

The code below travels down every single branch below the start point
and reports only LI nodes (you could add other if you wish). It also
reports the number of iterations required to get where it's up to (i).

To make it more robust, it should test for the text node below the LI to
make sure you get the right one, but I've just used your (somewhat
risky) guess that the first child of the LI is the text node you want.

If you just want the level directly below the starting OL, grab the
firstChild then use nextSibling to travel across the level.

Have fun - Fred.
<html><head><title>list LIs</title>
</head>

<body>
<ol id="anOL">
<li>item 1</li>
<li>item 2</li>
<li>item 3
<ol>
<li>item 3.1</li>
<li>item 3.2</li>
<li>item 3.3
<ol>
<li>item 3.3.1</li>
<li>item 3.3.2</li>
<li>item 3.3.3</li>
</ol>
</li>
<li>item 3.4</li>
</ol>
</li>
<li>item 4</li>
<li>item 5</li>
</ol>

<script type="text/javascript">
var msg = "LI list...";
function listLIs(n,x) {

if (n.nodeName == 'LI') {
msg += '\n LI ' + x + ' : '
+ n.nodeValue + ' : '
+ n.firstChild.nodeValue;
}
for (var i=0; i<n.childNodes.length; i++) {
listLIs(n.childNodes[i],x+'.'+i);
}
}

listLIs(document.getElementById("anOL"),'');
alert(msg);
</script>

</body></html>
Jul 23 '05 #3

P: n/a
I know I am late, but I can't let such nonsense go uncommented.

Fred Oz wrote:
[...]
Firefox and other similar browsers (including Safari) add text nodes
after just about everything, [...]
They don't.
IE doesn't add the useless text node, [...]


The text nodes are already there in the parse tree, as you can observe using
the W3C HTML Validator, for example. They have been created by indentation
and linebreaks in the source code. What IE 5+ really does is to disregard
the DOM Level 1+ HTML Specification in this regard although implementing
many of its methods and properties, removing some text nodes (usually those
after the start tag of block elements) from the parse tree or at least hide
them from DOM access while inconsistently preserve others (usually those
before the close tag of elements).

"Empty" text nodes (they are not really empty, but contain whitespace
characters) are not useless, they can be used to insert new text without
inserting a new element. *This* is how a shoe is done. [psf 4.6]
PointedEars
--
Error: Out of cheese, restock hamster wheel
Jul 23 '05 #4

P: n/a
Thomas 'PointedEars' Lahn wrote:
I know I am late, but I can't let such nonsense go uncommented.


The 'late' part is somewhat understated! :-)

The comment was somewhat flippant and the result of observing the
behaviour of various browsers without specific reference to the spec.

Thank you for the clarification - I can cop enlightenment quite
happily.

--
Fred
Jul 23 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.