Go Back   CodingForums.com > :: Client side development > JavaScript programming > DOM and JSON scripting

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 03-23-2003, 01:28 AM   PM User | #1
brothercake
Senior Coder


 
Join Date: Jun 2002
Location: near Oswestry
Posts: 4,508
Thanks: 0
Thanked 0 Times in 0 Posts
brothercake is an unknown quantity at this point
identyfing heirarchy groups within getElementsByTagName

I've got a complex <ul> structure and I want to return a collection of only those <li> nodes which are direct children of the root node.

How can I do that? getElementsByTagName returns all of them, without any way of identifying the location of each of its members in the heirarchy.
brothercake is offline   Reply With Quote
Old 03-23-2003, 02:22 AM   PM User | #2
liorean
The thread killer


 
Join Date: Feb 2003
Location: Umeå, Sweden
Posts: 5,575
Thanks: 0
Thanked 84 Times in 75 Posts
liorean will become famous soon enoughliorean will become famous soon enough
Code:
var lisWithSameParent=[];
for(var i in liCollection)
  liCollection[i].parentNode==[object parentNode]&&lisWithSameParent.push(liCollection[i]);
Or you could use NodeIterator or TreeWalker from DOM2 TR or have a look at DOM3 XPath
__________________
liorean <[lio@wg]>
Articles: RegEx evolt wsabstract , Named Arguments
Useful Threads: JavaScript Docs & Refs, FAQ - HTML & CSS Docs, FAQ - XML Doc & Refs
Moz: JavaScript DOM Interfaces MSDN: JScript DHTML KDE: KJS KHTML Opera: Standards
liorean is offline   Reply With Quote
Old 03-23-2003, 03:04 AM   PM User | #3
brothercake
Senior Coder


 
Join Date: Jun 2002
Location: near Oswestry
Posts: 4,508
Thanks: 0
Thanked 0 Times in 0 Posts
brothercake is an unknown quantity at this point
Cool thanks
brothercake is offline   Reply With Quote
Old 03-23-2003, 04:22 AM   PM User | #4
jkd
Senior Coder

 
jkd's Avatar
 
Join Date: May 2002
Location: metro DC
Posts: 3,163
Thanks: 1
Thanked 18 Times in 18 Posts
jkd will become famous soon enough
Quote:
Originally posted by liorean
Code:
var lisWithSameParent=[];
for(var i in liCollection)
  liCollection[i].parentNode==[object parentNode]&&lisWithSameParent.push(liCollection[i]);
Or you could use NodeIterator or TreeWalker from DOM2 TR or have a look at DOM3 XPath
I think DOM2 Traversal is overkill, and DOM3 XPath certainly is.

But your code... why purposely obfusticate just to save a few lines of Javascript? I consider it important to write clear, concise code, especially when dealing with the DOM:

Code:
var lis = [];
for (var i = 0; i < myUl.childNodes.length; i++) {
  if (myUl.childNodes.item(i).nodeName == "LI") {
    lis.push(myUl.childNodes.item(i));
  }
}
Certainly a little more obvious than doing a getElementsByTagName("LI"), then iterating through that NodeList and relying on short-circuit validation to push a proper <li> into the vector,

Arguably, depending on how getElementsByTagName is implemented, more efficient too. Seems to me that iterating through one level of nodes may take less time than what getElementsByTagName may have to do behind the scenes (recurse through all childnodes?).

Anyhoo, that's a debate on coding style. For kicks and giggles, here is a TreeWalker that'll do the same thing:

Code:
var lis = [];
var walker = document.createTreeWalker(myUl, NodeFilter.SHOW_ELEMENT,
	{ acceptNode: function (node) { return (node.nodeName == "LI"  && node.parentNode == myUl) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT } },
	false);
while (walker.nextNode()) lis.push(walker.currentNode);
__________________
jasonkarldavis.com

Last edited by jkd; 03-23-2003 at 04:25 AM..
jkd is offline   Reply With Quote
Old 03-23-2003, 04:25 AM   PM User | #5
brothercake
Senior Coder


 
Join Date: Jun 2002
Location: near Oswestry
Posts: 4,508
Thanks: 0
Thanked 0 Times in 0 Posts
brothercake is an unknown quantity at this point
My God!! Is that Luke TreeWalker or Anekin? Looks liks it's verging on the dark side either way

I like your first solution - childNodes is more efficient, and I could use the improvement (but you wouldn't really query a length property in a loop, now would you )

Last edited by brothercake; 03-23-2003 at 04:29 AM..
brothercake is offline   Reply With Quote
Old 03-23-2003, 04:36 AM   PM User | #6
jkd
Senior Coder

 
jkd's Avatar
 
Join Date: May 2002
Location: metro DC
Posts: 3,163
Thanks: 1
Thanked 18 Times in 18 Posts
jkd will become famous soon enough
Quote:
Originally posted by brothercake
My God!! Is that Luke TreeWalker or Anekin? Looks liks it's verging on the dark side either way

I like your first solution - childNodes is more efficient, and I could use the improvement (but you wouldn't really query a length property in a loop, now would you )
Heh, TreeWalker's can be scary... but they are soooo awesome too! They allow you effectively strip out anything you don't want to look at via the NodeFilter argument. NodeIterators too, but nothing supports those yet .

Anyway, as for querying the length property, I'm sure you seen me tell beetle I'm a theory guy?
In theory, the length property is a property with no cost, but of course it is a rather elaborate getter function I don't want to even think about.
But I don't care about that - since this isn't code I'm actually going to use. You know well enough to store the length somewhere because you can assert that it will be static throughout this operation, so you can have all the "fun" and deal with implementation.
__________________
jasonkarldavis.com
jkd is offline   Reply With Quote
Old 03-23-2003, 04:42 AM   PM User | #7
brothercake
Senior Coder


 
Join Date: Jun 2002
Location: near Oswestry
Posts: 4,508
Thanks: 0
Thanked 0 Times in 0 Posts
brothercake is an unknown quantity at this point
Quote:
Originally posted by jkd
so you can have all the "fun" and deal with implementation.
Dang students ...
brothercake is offline   Reply With Quote
Old 03-23-2003, 04:47 AM   PM User | #8
jkd
Senior Coder

 
jkd's Avatar
 
Join Date: May 2002
Location: metro DC
Posts: 3,163
Thanks: 1
Thanked 18 Times in 18 Posts
jkd will become famous soon enough
Just because liorean mentioned it, DOM3 XPath coming at you!

Code:
var lis = [], temp;
var result = document.evaluate("li", myUl, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null);
while (temp = result.iterateNext()) lis.push(temp);
Or you could iterate through the snapshotItem() list.
__________________
jasonkarldavis.com
jkd is offline   Reply With Quote
Old 03-24-2003, 07:56 PM   PM User | #9
beetle
Senior Coder

 
Join Date: Aug 2002
Posts: 3,467
Thanks: 0
Thanked 0 Times in 0 Posts
beetle has a little shameless behaviour in the past
Or skip the length property altogether
Code:
var lis = [];
for ( var itm, i = 0; ( itm = myUl.childNodes.item(i) ); i++ )
{
    if ( itm.nodeName == "LI" )
    {
        lis.push( itm );
    }
}
__________________
My Site | fValidate | My Brainbench | MSDN | Gecko | xBrowser DOM | PHP | Ars | PVP
“Minds are like parachutes. They don't work unless they are open”
“Maturity is simply knowing when to not be immature”
beetle is offline   Reply With Quote
Old 03-24-2003, 08:29 PM   PM User | #10
liorean
The thread killer


 
Join Date: Feb 2003
Location: Umeå, Sweden
Posts: 5,575
Thanks: 0
Thanked 84 Times in 75 Posts
liorean will become famous soon enoughliorean will become famous soon enough
Doesn't that produce a warning using mozilla's strict warnings? I hate when scripts clog up my jsconsole by doing that.
__________________
liorean <[lio@wg]>
Articles: RegEx evolt wsabstract , Named Arguments
Useful Threads: JavaScript Docs & Refs, FAQ - HTML & CSS Docs, FAQ - XML Doc & Refs
Moz: JavaScript DOM Interfaces MSDN: JScript DHTML KDE: KJS KHTML Opera: Standards
liorean is offline   Reply With Quote
Old 03-24-2003, 10:28 PM   PM User | #11
beetle
Senior Coder

 
Join Date: Aug 2002
Posts: 3,467
Thanks: 0
Thanked 0 Times in 0 Posts
beetle has a little shameless behaviour in the past
Not that I know of. And, according to some tests I just did, if a reference to itm is needed, then my above example is the fastest of the for-loop methods in IE and Opera. In Mozilla, all tests were virtually the same.

In IE and Opera the while loop was consistently the fastest (I ran the test 10 times each) with the for loop I show above consistently being 2nd fastest.

I've read about IE being loop-optimized. The results I see here show that, with IE consistently being 2-3 times faster than Opera or Mozilla (Please, I'm not trying to start some sort of IE vs the world thing here, just fact-finding)
__________________
My Site | fValidate | My Brainbench | MSDN | Gecko | xBrowser DOM | PHP | Ars | PVP
“Minds are like parachutes. They don't work unless they are open”
“Maturity is simply knowing when to not be immature”
beetle is offline   Reply With Quote
Old 03-24-2003, 10:55 PM   PM User | #12
liorean
The thread killer


 
Join Date: Feb 2003
Location: Umeå, Sweden
Posts: 5,575
Thanks: 0
Thanked 84 Times in 75 Posts
liorean will become famous soon enoughliorean will become famous soon enough
Beetle: Yep, ie is VERY loop optimised. Moz on the other hand is object optimised. Opera is getting better at both, but is far from either except in special cases.

I just found out the reason this doesn't produce a warning, by the way: [index] with a too large index returns undefined, .item(index) with a too large index returns null. Undefined as rhe produces a warning.
__________________
liorean <[lio@wg]>
Articles: RegEx evolt wsabstract , Named Arguments
Useful Threads: JavaScript Docs & Refs, FAQ - HTML & CSS Docs, FAQ - XML Doc & Refs
Moz: JavaScript DOM Interfaces MSDN: JScript DHTML KDE: KJS KHTML Opera: Standards
liorean is offline   Reply With Quote
Old 03-24-2003, 11:12 PM   PM User | #13
brothercake
Senior Coder


 
Join Date: Jun 2002
Location: near Oswestry
Posts: 4,508
Thanks: 0
Thanked 0 Times in 0 Posts
brothercake is an unknown quantity at this point
Quote:
Originally posted by liorean
Beetle: Yep, ie is VERY loop optimised. Moz on the other hand is object optimised. Opera is getting better at both, but is far from either except in special cases.
Hey now that explains a lot ... I had no idea browsers could be optimised for a particular kind of process; obvious now you think about it.

Now that could give rise to a particularly interesting (or twisted, depending on how you look at it) kind of browsers sniffing; like

if(you_like_it_like_this)
{
do it like this
}

kind of thing ..? I like the optimisation potential there, if the implementation might be a bit confusing ...

.. dang; and I was only just getting round the concept of DOM-model sniffing

But thanks guys anyway for all the input on this; eventually what I'm doing is building like an XML parser for navigational data stored as a <ul> tree; so it can be parsed into dropdown menus, or expanding folder thingies; all manner of what have you; and its core data is completely accessible to any user-agent that understands HTML
__________________
"Why bother with accessibility? ... Because deep down you know that the web is attractive to people who aren't exactly like you." - Joe Clark

Last edited by brothercake; 03-24-2003 at 11:26 PM..
brothercake is offline   Reply With Quote
Old 03-24-2003, 11:45 PM   PM User | #14
liorean
The thread killer


 
Join Date: Feb 2003
Location: Umeå, Sweden
Posts: 5,575
Thanks: 0
Thanked 84 Times in 75 Posts
liorean will become famous soon enoughliorean will become famous soon enough
Heh, there's more!

Try timing these:
Code:
/* First testcase */
var
  i=50,
  j=0,
  a=0,
  t=1e3;
while(i-->0)// Oh, the beauty!
  for(j=0;j<t;j++)
    a++;

/* Second testcase */
var
  i=50,
  j=0,
  a=0,
  t=1e3;
while(i-->0){
  j=0;
  while(j++<t)
    a++;
}

/* Third testcase, using something known as "Duff's Device" */
var
  i=50,
  a=0,
  n,
  m,
  t=1e3;
while(i-->0){
  n=t/11;
  m=t%11;
  while(n-->0){
    switch(m){
      case 0: a++;
      case 10: a++;
      case 9: a++;
      case 8: a++;
      case 7: a++;
      case 6: a++;
      case 5: a++;
      case 4: a++;
      case 3: a++;
      case 2: a++;
      case 1: a++;
    }
    m=0;
  }
}

/* Fourth example, a version of Duff's Device optimised for JavaScript*/
var
  i=50,
  a=0,
  n,
  t=1e3;
while(i-->0){
  n=t%11;
  while(n--)
    a++;
  n=parseInt(t/11);
  while(n--){
    a++;
    a++;
    a++;
    a++;
    a++;
    a++;
    a++;
    a++;
    a++;
    a++;
    a++;
  }
}
My results here say that if you do looping in unorthodox ways, you can get moz to be as fast as or faster than ie.
__________________
liorean <[lio@wg]>
Articles: RegEx evolt wsabstract , Named Arguments
Useful Threads: JavaScript Docs & Refs, FAQ - HTML & CSS Docs, FAQ - XML Doc & Refs
Moz: JavaScript DOM Interfaces MSDN: JScript DHTML KDE: KJS KHTML Opera: Standards
liorean is offline   Reply With Quote
Old 03-25-2003, 12:26 AM   PM User | #15
beetle
Senior Coder

 
Join Date: Aug 2002
Posts: 3,467
Thanks: 0
Thanked 0 Times in 0 Posts
beetle has a little shameless behaviour in the past
Ah ya, I've already seen Duff's Device. I may test it later
__________________
My Site | fValidate | My Brainbench | MSDN | Gecko | xBrowser DOM | PHP | Ars | PVP
“Minds are like parachutes. They don't work unless they are open”
“Maturity is simply knowing when to not be immature”
beetle is offline   Reply With Quote
Reply

Bookmarks

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 05:10 AM.


Advertisement
Log in to turn off these ads.