Closed Thread Icon

Topic awaiting preservation: DOM ECMAScript - Counting number of li in a ul, not including sub ul/li (Page 1 of 1) Pages that link to <a href="https://ozoneasylum.com/backlink?for=24223" title="Pages that link to Topic awaiting preservation: DOM ECMAScript - Counting number of li in a ul, not including sub ul/li (Page 1 of 1)" rel="nofollow" >Topic awaiting preservation: DOM ECMAScript - Counting number of li in a ul, not including sub ul/li <span class="small">(Page 1 of 1)</span>\

 
jjarman
Neurotic (0) Inmate
Newly admitted

From:
Insane since: Nov 2004

posted posted 11-29-2004 19:24

Anyone have any ideas how to count the number of child li in a ul without counting sub ul and their child li using WC3 DOM / ECMAScript? I need to know only the first level of children. Also, li can contain span and other elements etc. Thanks!

poi
Paranoid (IV) Inmate

From: France
Insane since: Jun 2002

posted posted 11-29-2004 19:42

jjarman: Hello and welcome in the Asylum. There's several ways to do that :

  • you could browse the children of your UL and increment a counter each time you meet a LI. In certain browser there may be some TEXT elements between the children.
  • or you can grab the LI in the document of your UL, then browse that collection and remove those whose parentNode is NOT your UL
  • there's certainly antoher method but right now I only see the 2 above





(Edited by poi on 11-29-2004 19:44)

Slime
Lunatic (VI) Mad Scientist

From: Massachusetts, USA
Insane since: Mar 2000

posted posted 11-29-2004 19:43

Well, I'd loop through the children (let's see if I remember the DOM properties right)...

ul = document.getElementById('mylist'); // get the ul however you want
var count = 0;
for (var a=0; a < ul.childNodes.length; ++a)
{
if (ul.childNodes[a].nodeName.toLowerCase() == 'li')
++count;
}


 

jjarman
Obsessive-Compulsive (I) Inmate

From:
Insane since: Nov 2004

posted posted 11-29-2004 20:41

Thank you poi and slime for the suggestions, I appreciate it!

I'll try them and post back what I discover.
In the meantime don't let that stop anybody else from offering alternative suggestions to those above.

I'm still new to the ozone forums, but have already had several hours dissapear reading posts.

Take care.

liorean
Bipolar (III) Inmate

From: Umeå, Sweden
Insane since: Sep 2004

posted posted 11-29-2004 21:02

Well, a somewhat faster version would be:

code:
var
coll=document.getElementById('mylist').childNodes,
elm,
i=0,
count=0;
while(elm=coll.item(i++))
if(/li/i.test(elm.tagName))
++count;



--
var Liorean = {
prototype: XMLGuru.prototype,
abode: "http://web-graphics.com/",
profile: "http://codingforums.com/member.php?u=5798"};

(Edited by liorean on 11-29-2004 21:02)

(Edited by liorean on 11-29-2004 21:05)

Iron Wallaby
Paranoid (IV) Inmate

From: USA
Insane since: May 2004

posted posted 11-29-2004 22:03

/!\ Off-topic, sorry if it is a problem! /!\

liorean: Out of random curiousity, what programming language are you native to? In looking at Slime's example, it is obvious that he hails from C or C++. Your code style looks much closer to Lisp or Scheme than anything else I am familiar with.

Also out of curiosity, are there any differences between

code:
/regexp/.test(string)

and

code:
string.match(/regexp/)

?

"Any sufficiently advanced technology is indistinguishable from magic." -- Arthur C. Clarke
"Any sufficiently arcane magic is indistinguishable from technology." -- P. David Lebling

(Edited by Iron Wallaby on 11-29-2004 22:04)

liorean
Bipolar (III) Inmate

From: Umeå, Sweden
Insane since: Sep 2004

posted posted 11-29-2004 22:57
quote:
Iron Wallaby said:
liorean: Out of random curiousity, what programming language are you native to? In looking at Slime's example, it is obvious that he hails from C or C++. Your code style looks much closer to Lisp or Scheme than anything else I am familiar with.

I started programming TP (Turbo Pascal) on my first computer, around 1991-1992. When that computer died, I took a quick venture into QuickBASIC, which I didn't like but which was the only language available to me for no cost then. Around the end of 1994, beginning of 1995 my parents got an internet connection, and I started with HTML. I've done JavaScript since nn2. I took some beginners courses in C/C++ in 1998, but I never really liked the environment, and soon tried Java instead. Which I found was about the worst language I've ever tried, by the way. Sometime 2001-2002 I started looking into dynamic languages. Of those I've tested so far, Ruby and Scheme were really good, but JavaScript remains my main language. Since Saturday, I'm working on a JavaScript-->Parrot compiler written in JavaScript. Hard work, since I don't have any particular experience in writing lexers/parsers/compilers - I've written an Unlambda interpreter in JavaScript, but that's about that.


quote:
Also out of curiosity, are there any differences between
/regexp/.test(string)
and
string.match(/regexp/)


Yes, there are.

RegExp.prototype.test returns a boolean, whether the string matches or not. It's a fixed length comparison, and is about as effective as the corresponding string comparisons would be.

String.prototype.match returns a RegExp array of the first match if the regexp is not global, a regular array with all the full match strings if it is global.

We also have some other RegExp handling functions:

RegExp.prototype.exec always returns a RegExp array of the first match.

String.prototype.search returns the character index of the start of the first match, or -1 if not present.

String.prototype.split is a bit peculiar, and inconsistently implemented across browsers. It should split a string into an array of string fragments, each element in the the array being the part from the last match (if any) to the next match (or alternatively end of line). This is done consistently by regex supporting engines. However, caught matches should be inserted into the array between the fragment that came before the match and the fragment that came after the match, and this is majorly screwed up in gen4 browsers as well as ie5.0, all platforms.


I've written an article about regex in JavaScript, if you want to read it. It's more of a reference, really. Regular Expressions in JavaScript

--
var Liorean = {
prototype: CSSGuru.prototype,
abode: "http://codingforums.com/",
profile: "http://codingforums.com/member.php?u=5798"};

Iron Wallaby
Paranoid (IV) Inmate

From: USA
Insane since: May 2004

posted posted 11-29-2004 23:20

Interesting! I've only been using Javascript for the last year or so -- it's an excellent language (quite nearly the ideal for me). I started with AppleScript (yay for HyperCard), then moved into BASIC, C++ (which is the only language I have learned formally), C, Perl, Python, ASM (x86 and LC86k), PHP, all sorts of shell scripts, Javascript, Java, and most recently Smalltalk, Ruby, and Lisp, which I am still learning. So my programming style has rather evolved over time, though it's mostly been pretty Perl-like in the last year or two, though it's been gravitating to a more functional style of programming lately (heck -- I use function pointers in C ).

quote:
Since Saturday, I'm working on a JavaScript-->Parrot compiler written in JavaScript. Hard work, since I don't have any particular experience in writing lexers/parsers/compilers - I've written an Unlambda interpreter in JavaScript, but that's about that.


That's awesome -- a great idea. Two questions: will it be fast enough for practical use, and what sort of interface are you looking at for it -- web, or command line? I'd love to see this progress, since I think it will open a lot of doors for Javascript to be perceived as something other than a "kiddie" language.

And thanks for the regex resource -- it should prove handy. *bookmarks*

"Any sufficiently advanced technology is indistinguishable from magic." -- Arthur C. Clarke
"Any sufficiently arcane magic is indistinguishable from technology." -- P. David Lebling

jjarman
Obsessive-Compulsive (I) Inmate

From:
Insane since: Nov 2004

posted posted 11-30-2004 00:18

Tested both the examples provided and they worked! Thanks!

Slime's code worked wonderfully as test implimented here:

code:
<ul id="TestUL">
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
<li>Five</li>
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
<li>E</li>
</ul>
</ul>
<script language="javascript" type="text/javascript">
//<![CDATA[
function CountUL(strListName)
{
var ul = document.getElementById(strListName);
var count = 0;
for (var a=0; a < ul.childNodes.length; ++a)
{
if (ul.childNodes[a].nodeName.toLowerCase() == 'li')
++count;
}
return count;
}
alert(CountUL("TestUL"));
//]]>
</script>



As did Liorean's code as test implimented here:

code:
<ul id="TestUL">
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
<li>Five</li>
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
<li>E</li>
</ul>
</ul>
<script language="javascript" type="text/javascript">
//<![CDATA[
function CountUL(strListName)
{
var
coll=document.getElementById(strListName).childNodes,
elm,
i=0,
count=0;
while(elm=coll.item(i++))
if(/li/i.test(elm.tagName))
++count;
return count;
}
alert(CountUL("TestUL"));
//]]>
</script>



I think that just about sums it up for this thread.
Many thanks to those that helped!

Cheers,
Josh

Edited Post:
========================================================
Profiled both examples to compare performance using venkman in firefox:
Slime's Code: - Total Calls: 40 (max recurse 0) Total Time: 70.1 (min/max/avg 10.01/10.02/1.75)
Liorean's Code: - Total Calls: 40 (max recurse 0) Total Time: 80.11 (min/max/avg 0/10.02/2)
(Disclaimer, not sure how good of profiler venkman is, nor if a 40 pass test is really useful for a real life example, not really sure of anything really! )
========================================================

(Edited by jjarman on 11-30-2004 01:41)

jjarman
Obsessive-Compulsive (I) Inmate

From:
Insane since: Nov 2004

posted posted 11-30-2004 00:36

One more question on this subject while I have yoru attention

Is there a standards checker similar to the WC3 CSS & XHTML validators that can check JavaScript code to make sure it conforms to ECMAScript & WC3 DOM standards?

The project I am currently working on needs to be 100% standards compliant.
I need to make sure I'm not using any "features" leftover from the "browser wars" ;-)
(Meaning browser specific code, extensions to javascript, dom references, etc.)

Also is there a reference(s) to where these standards start to break as you move backwards in browser history/versions?

Okay, that was more then one, but once I get started I can't seem to stop.

Thanks again!

liorean
Bipolar (III) Inmate

From: Umeå, Sweden
Insane since: Sep 2004

posted posted 11-30-2004 01:05
quote:
Iron Wallaby said:
Two questions: will it be fast enoughfor practical use,

To quote the parrot developers:
"The four c's: compile, correct, complete, compete - in that order."

The speed of the lexer/parser (ECMAScript has the unfortunate situation that the lexical grammar is reliant on the syntactic grammar, so they must be simultaneous) isn't really important.

First of all, I need to be able to build an ECMAScript AST (Abstract Syntax Tree).

Then I need to, from that AST, compile into one of four different languages: PAST (Parrot AST), PIR (Parrot Intermediate Representation), PASM (Parrot Assembly) or PBC (Parrot Bytecode). I'll most probably chose PIR when that time comes - that allows me to take maximum advantage of the Parrot optimiser.

Together with the PIR compiler, I need to create the PMCs (Parrot Magic Cookies, a universal object type that can be used to implement that object model of whichever language you're representing) that represents the ECMAScript types, that implements the prototype based delegation scheme (as well as the ECMAScript4 class-instance system that the prototype delegation system coexists with).

Finally, I need to actually compile the compiler using the compiler. Since this is written in JavaScript, I need a JavaScript interpreter to do that. I'll probably use SpiderMonkey.

That will give me PIR source for the compiler. From here, I can compile to PBC, which is the executable format for Parrot. (It is fully capable of JITting, though, so it can work from the PIR source directly.)

And, when I finally have the compiler compiled to PIR or PBC, I can in the future compile the compiler using my own implementation.

And it's not until at that point I start worrying about speed. Maybe I'll have to drop the JavaScript implementation for a PIR one to increase performance, but when I've come that far, I already have an idea of how the lexing/parsing to ECMAScript AST and the compiling to PIR from there should be done, so that will be easier. It's the start that is the hardest part, since I don't have any formal knowledge about the lexing/parsing/compiling phases.

Also, it's possible to improve performance of the PMCs without affecting their interface, thus not needing to make any PIR changes, so there are many separate areas where optimisation may take place.

Oh, and just as a footnote, Parrot has continuations and supports CPS (Continuation Passing Style), so I'll get some Scheme goodies essentially for free, such as native first class continuations. I'll also get the benefit of having the Perl6 regex engine at hands.

(Which are sufficiently advanced that they are no longer called regular expressions (they have been far beyond formal regular expressions for a long time), they're called "rules".)
It should be technically possible to implement an entire lexer/parser/compiler system in a single rule.

quote:
and what sort of interface are you looking at for it-- web, or command line? I'd love to see this progress, since I thinkit will open a lot of doors for Javascript to be perceived as somethingother than a "kiddie" language.

I'm going to use Parrot. It'll be applicable in any environment that supports Parrot. It should be entirely possible to use an API, command line, a browser, or any other embedding of Parrot.

But that's far away. I'm currently trying to write together a lexer/parser that can handle the entirety of ECMAScript3 and the Netscape JavaScript1.5 extensions, as well as being modular enought to be able to by simple flags suport ECMAScript4, JavaScript2.0 and the ECMAScript for XML extension, as well as drop the support level down to ECMA-290.



quote:
And thanks for the regex resource -- it should prove handy. *bookmarks*

It covers about the same things as the DevEdge and MSDN documentations on regex in Netscape JavaScript and Microsoft JScript, respectively. It's definitely handy. (Note that the browser support notes are a little unspecific - that's because I didn't have that many browsers to test it in at the time, so I had to rely on memory.)

--
var Liorean = {
prototype: XHTMLGuru.prototype,
abode: "http://codingforums.com/",
profile: "http://codingforums.com/member.php?u=5798"};

(Edited by liorean on 11-30-2004 01:09)

liorean
Bipolar (III) Inmate

From: Umeå, Sweden
Insane since: Sep 2004

posted posted 11-30-2004 01:46
quote:
jjarman said:

One more question on this subject while I have yoru attention Is there a standards checker similar to the WC3 CSS & XHTMLvalidators that can check JavaScript code to make sure it conforms toECMAScript &amp; WC3 DOM standards?

I'm tempted to say yes there is: it's called Mozilla. However, that's not very helpful so instead I'll direct you to jslint. It's not quite what you want, but it's close as it gets.

quote:
The project I am currently working on needs to be 100% standards compliant. I need to make sure I'm not using any "features" leftover from the "browser wars" ;-) (Meaning browser specific code, extensions to javascript, dom references, etc.)Also is there a reference(s) to where these standards start to break as you move backwards in browser history/versions?

A short, incomplete list:

ECMAScript/JavaScript:
- Regular Expressions are crippled in nn4, ie5m, ie5.0w.
- Many Array methods are unsupported in the same browsers.
- Some String methods are unsupported in nn4, ie5m, ie5.0w. JavaScript1.3 level is what you can rely on for all of these.
- try..catch is unsupported in nn4.

W3C DOM:
- Nn4 has DOM0 level support only.
- Ie5.0w has spotty DOM1Core support.
- Ie5.5w, ie6w, ie5m, saf1.0, op7 have about DOM2Core, DOM2HTML, (very) spotty DOM2StyleSheets.
- Msn/osx, saf1.2, ow5, op7.5, moz, ff have good DOM2Core, DOM2HTML, good DOM2StyleSheets, good DOM2Events, and frequently also DOM3 additions.
- In certain areas moz, ff have far better support than any other browser. DOM2TR is an example.
- In other areas Op7.6 goes strong. DOM3LS is an example.

CSS:
- Op7.5, moz, ff, saf1.2 are all about the same level. CSS1 is almost complete, CSS2.1 is close, some CSS3 support exists. They differ in the CSS3 area, mostly.
- Op7, saf1.0, msn/osx are about the same level, CSS1 pretty good but CSS2 spotty. Msn/osx is affected by some obscure bugs that are also in ie5m.
- Ie6 in standard mode isn't really that bad. It's buggy, but those are small bugs compared to ie5m. The bad part is the selectors support and the deficiency at generated content.
- Ie5m is special. CSS1 is okay, CSS2 is sometimes better than ie6w, sometimes worse. Beware of floats, overflows, clips and fixed positioning, they have severe bugs.
- Ie5.5w and ie6w in quirks mode have the old box model, but are otherwise about at the same level as ie6w in standards mode.
- Ie5.0w is somewhat behind ie5.5. Test, test, test. CSS1 is the roof.
- Nn4 CSS support is very, very quirky.

HTML/XHTML/XML:
- Moz, ff, op7.5, saf1.2, msn/osx have excellent XHTML support.
- Op7, saf1.0, ow5 have spotty XHTML support.
- Ie5m, all iew, nn4 have no XHTML support whatsoever.
- Moz, ff, saf1.2, op7.5, ow5 have excellent XML support
- Iew has very partial XML support.
- Ie5m has syntax listing support for XML only.
- Msn/osx, nn4 have no XML support whatsoever.

XSLT:
- Ie5.5w, ie6w have fair XSLT support.
- Moz has a bit worse XSLT support.
- Op, saf, ow, msn/osx, iem lacks XSLT support.

--
var Liorean = {
prototype: XMLGuru.prototype,
abode: "http://liorean.web-graphics.com/",
profile: "http://codingforums.com/member.php?u=5798"};

poi
Paranoid (IV) Inmate

From: France
Insane since: Jun 2002

posted posted 11-30-2004 01:55

jjarman: What does Venkman say about :

code:
function CountUL( strListName )
{
var currentNode = document.getElementById( strListName ).firstChild
var count = 0
while( currentNode )
{
if( currentNode.nodeName=="LI" )
count++
currentNode = currentNode.nextSibling
}
return count
}

Sorry I've never used Venkman and am too lazy, no surprise at ~2pm, to benchmark the 3 methods myself



(Edited by poi on 11-30-2004 02:34)

Slime
Lunatic (VI) Mad Scientist

From: Massachusetts, USA
Insane since: Mar 2000

posted posted 11-30-2004 02:46
quote:
lexer/parser (ECMAScript has the unfortunate situation that the lexical grammar is reliant on the syntactic grammar, so they must be simultaneous)



Out of curiosity, could you elaborate? Why is that the case?


 

liorean
Bipolar (III) Inmate

From: Umeå, Sweden
Insane since: Sep 2004

posted posted 11-30-2004 03:44
quote:
Slime said:
Out of curiosity, could you elaborate? Why is that the case?


Because the lexer doesn't know by itself whether the context allows for division, divisionassignment or regex. The parser is needed to tell the lexer whether the solidus ('/') can be a division or division assignment token; or whether it is the opening or closing delimiter for the regex pattern. This is the reason why so many syntax aware code editors have problems with getting regex handling right in JavaScript - they essentially need to parse the JavaScript to be sure. Either that or do lookaheads. E4X extends this dependency by adding two other special contexts for the lexer, XMLTag and XMLContent contexts. The reason for this is, of course, that it's necessary for overloading the '<', '>', '{' and '}' characters for using XML syntax in JavaScript source.

All in all JavaScript is more of a PITA to parse than most languages, because you can't just feed a stock lexer generator or parser generator with the lexical and syntactical grammar, respectively.



An example from the Netscape ECMAScript4 proposal:

code:
for (var x = a in foo && "</x>" || mot ? z:/x:3;x<5;y</g/i) {xyz(x++);}
for (var x = a in foo && "</x>" || mot ? z/x:3;x<5;y</g/i) {xyz(x++);}



--
var Liorean = {
prototype: HTMLGuru.prototype,
abode: "http://liorean.web-graphics.com/",
profile: "http://codingforums.com/member.php?u=5798"};

(Edited by liorean on 11-30-2004 03:56)

Iron Wallaby
Paranoid (IV) Inmate

From: USA
Insane since: May 2004

posted posted 11-30-2004 04:05

In reference to speed/interface, I was referring to the JS->Parrot bytecode converter itself, not the Parrot bytecode created thereafter (I assume, if it is to be capable of running Perl in a speedy manner, it should be able to handle JS without too much chugging) -- I would tend to think that speed would matter, after all, you wouldn't want the interpreter to take 5 hours to convert a program into bytecode, would you? (Except, of course, as you noted -- it's important to make it work first.)

Though, you mentioned you would use SpiderMonkey, so that answers my questions, I think.

It does seem you have your work cut out for you. Best of luck; I'd love to hear about this more as it progresses, since you can only get so far in three days. In the meantime, I'll get back to my cubic solver for InI. ;p

"Any sufficiently advanced technology is indistinguishable from magic." -- Arthur C. Clarke
"Any sufficiently arcane magic is indistinguishable from technology." -- P. David Lebling

liorean
Bipolar (III) Inmate

From: Umeå, Sweden
Insane since: Sep 2004

posted posted 11-30-2004 05:28
quote:
Iron Wallaby said:
It does seem you have your work cut out for you.

I would believe so, yeah.

quote:
I'd love to hear about this more as it progresses, since you can only get so far in three days.

Actually, when you're new to this you don't get much actual coding done in three days. You look through the ECMAScript, JavaScript, E4X, ECMA-290 specs, you look at whatever documentation you can find for writing -->Parrot compilers (that's not that very much), you spend hours on reading through source code for other JavaScript engines.
Then you build an image in your head of how it all fits together, and if you're lucky you don't have to adapt it too much. Currently I have about 140 lines of code, many of them being bodyless declarations of constructors for the objects that I know I'll need.

--
var Liorean = {
prototype: XHTMLGuru.prototype,
abode: "http://web-graphics.com/",
profile: "http://codingforums.com/member.php?u=5798"};

jjarman
Obsessive-Compulsive (I) Inmate

From:
Insane since: Nov 2004

posted posted 11-30-2004 06:59

Big thanks to liorean for all the information!
I truly appreciate it!

poi offers the following alternative code implimented in the test below:

code:
<ul id="TestUL">
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
<li>Five</li>
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
<li>E</li>
</ul>
</ul>
<script language="javascript" type="text/javascript">
function CountUL( strListName )
{
var currentNode = document.getElementById( strListName ).firstChild;
var count = 0;
while( currentNode )
{
if( currentNode.nodeName=="LI" )
count++;
currentNode = currentNode.nextSibling;
}
return count;
}
</script>



This code profiles using venkman in firefox as:
Total Calls: 40 (max recurse 0) Total Time: 70.06 (min/max/avg 0/10.02/1)

Thanks to poi for yet another alternative.

That being said I'm starting to question venkman's profiling abilities...and don't want to fork out the money for tito's profiler.

Anyone know anything about JavaScript Profilers or Profiling.
Maybe I'll start a new thread to discuss this, since this thread is pretty much complete.

Thanks!

« BackwardsOnwards »

Show Forum Drop Down Menu