Go Back   CodingForums.com > :: Client side development > JavaScript programming > Post a JavaScript

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 11-18-2009, 05:33 AM   PM User | #1
rnd me
Senior Coder

 
rnd me's Avatar
 
Join Date: Jun 2007
Location: Urbana
Posts: 3,455
Thanks: 9
Thanked 466 Times in 450 Posts
rnd me is a jewel in the roughrnd me is a jewel in the roughrnd me is a jewel in the rough
Handy Node Getter

there are some node queries that are hard to code in jQuery.
grabbing all comment nodes for example.
dom libraries are also big, sometimes you just need a tiny node fetcher.

with some simple or clever searches (many examples below),
you can grab all sorts of different node collections with this simple function:

function
Code:
//public domain
function getNodes(prop, val, meth, nd, useSelf ){
 var r=[], any= getNodes[val]===true;
 nd=nd||document.documentElement;
 if(nd.constructor===Array){nd={childNodes:nd};}
  for(var cn=nd.childNodes, i=0, mx=cn.length;i<mx;i++){
    var it=cn[i];
    if(it.childNodes.length && !useSelf){r=r.concat(getNodes(prop,val,meth,it,useSelf ));}
	if( any ? it[prop] : (it[prop]!==undefined && (meth ? ""[meth] && 
		String(it[prop])[meth](val) : it[prop]==val))){
		  r[r.length]=it; 
	}
  }//nxt
 
return r;
};getNodes[null]=true; getNodes[undefined]=true;




usage:
Accepts 1-3 arguments.
prop: javascript property of a node (ex: className not class)
val: optional. a value that prop must match to be included in the results
meth: a method of a given node's prop value to invoke before comparison (very useful for "".match()ing)





examples:
Code:
//basic
 getNodes("data") 		//finds all text/comment nodes
 getNodes("tagName")		//finds all elements
 getNodes("form")		//finds all form-related elements
 getNodes("onmouseover") 	//find all elements with mouseover events
 getNodes("value")		//finds all inputs with some value

//filtered
 getNodes("value", "")		//finds all inputs without value
 getNodes("nodeType", 8) 	//finds all comment nodes
 getNodes("target", "_blank")	//finds links that open in a new window/tab
 getNodes("tagName", "A") 	//finds all anchor tags


//advanced
 getNodes("src", "\\.js", "match")	//finds all external scripts
 getNodes("className","page") 		//finds all tags with class exactly == to "page"
 getNodes("className","page", "match")	//finds all tags with class attrib containing "page"
 getNodes("className","\\bpage\\b", "match")	//finds all tags with a class of "page"
 getNodes("data","Coder","match" ) 		//finds all text nodes containing string "Coder"
 getNodes("tagName", /input|button/i, "match") //finds all inputs and buttons
 getNodes("textContent","Coder","match" ) 	//finds all nodes containing string "Coder" (kinda slow)
 getNodes("type", "application/rss+xml")	//finds "offered" RSS feed links
 getNodes("tabIndex","^[0-9]+" ,"match") 	//finds all elments that can be focused via the tab key
 getNodes("tagName", "INPUT|SELECT|BUTTON|TEXTAREA", "match") //finds all form elements by tagName
 getNodes("href", location.href.split(".")[0].split(/\W+/)[1], "match")//finds all internal anchor links

so, in one small package, you have a getElementsByTagName, attribute selectors, a getElementsByClassName feature, and a mockup of jQuery's great "contains" feature; not bad for a small package.

with a few wrappers, it could be the basis of a great 1kb dom library...

packs to ~400 bytes:
Code:
function getNodes(a,b,c,d,e){var r=[],any=getNodes[b]===true;d=d||document.documentElement;
 if(d.constructor===Array){d={childNodes:d}}for(var f=d.childNodes,i=0,mx=f.length;i<mx;i++){
 var g=f[i];if(g.childNodes.length&&!e){r=r.concat(getNodes(a,b,c,g,e))}if(any?g[a]:
 (g[a]!==undefined&&(c?""[c]&&String(g[a])[c](b):g[a]==b))){r[r.length]=g}}return r};
 getNodes[null]=true;getNodes[undefined]=true;
any uses i missed, or expansion ideas?
__________________
my site (updated 5/13)
STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.6% IE9:9.8% IE10:10%

Last edited by rnd me; 11-18-2009 at 08:15 AM..
rnd me is offline   Reply With Quote
Old 12-16-2009, 04:46 PM   PM User | #2
jmrker
Senior Coder

 
jmrker's Avatar
 
Join Date: Aug 2006
Location: FL
Posts: 2,764
Thanks: 29
Thanked 453 Times in 447 Posts
jmrker will become famous soon enough
Question

Question:

In the examples, do the references to "tagName" and "className":

1. mean to use those labels as is (ie; "tagName" and "className")
OR
2. mean to use the scripts' assigned value in the element, like <... name="Some_tagName" ...>

Same question for other examples applies.

Thanks for the information
... it appears to be a very useful script if I can just figure out how to use it!
jmrker is offline   Reply With Quote
Old 12-17-2009, 04:18 AM   PM User | #3
rnd me
Senior Coder

 
rnd me's Avatar
 
Join Date: Jun 2007
Location: Urbana
Posts: 3,455
Thanks: 9
Thanked 466 Times in 450 Posts
rnd me is a jewel in the roughrnd me is a jewel in the roughrnd me is a jewel in the rough
Quote:
Originally Posted by jmrker View Post
In the examples, do the references to "tagName" and "className":

1. mean to use those labels as is (ie; "tagName" and "className")
OR
2. mean to use the scripts' assigned value in the element, like <... name="Some_tagName" ...>
sorry for the confusion, examples don't adequately explain what's going on and how it works.

Here's what it does:
getNodes looks at all the tag in the document, and creates a selection of those; a sub-set. it returns an array of elements that meet the conditions.

what conditions?
getNodes looks at the properties of each tag/element to determine if it should "be on the list" and get added to the return.

these properties are often the same as attribs.
for example,
Code:
<a id="a1"  class="anc" href="http://google.com">Google</a>
has a couple properties:

1. like all elemenent, it has a .tagName property.
the link's .tagName is "A".

2. it also has an href attrib. Most standard attribs have a corresponding DOM property name as well. in the case of href, the property name (element.href) is the same as the attrib ("href"). This mean that to read the href attrib/property of the <A>, we can examine element.href.

caveats:

3. some attribs don't have 1:1 matching property names, and some property names don't have corresponding attribs at all. .tagName has no attrib equivalent to name one. Other common attribs compete with javascript reserved words, like "class". In those case, javascript/DOM provides a closely-named replacement for that property. for class it's elmenent.className. Some attribs have the same dom property, id for example.

view the above anchor tag's href attrib via:
Code:
alert ( document.getElementById('a1').href );//=="http://google.com"
view the above anchor tag's id via:
Code:
alert ( document.getElementById('a1').id);//=="a1"
view the above anchor tag's class via:
Code:
alert ( document.getElementById('a1').className);//=="anc"
though some of the examples are handy, it's important to be aware of the dom properties to make getNodes() work for your own use.

Once you have the dom binding memorized (or handily-listed), you can start to create expressions for getNodes().

One final consideration is that although i've only mentioned tags, getNodes() looks att all nodes, not just full Elements.
This means that getNodes() can find comments, text nodes, xml PIs, unlike the common css selectors utilities.


at it's most basic, passing one dom property name to getNodes() will return any node that has the property defined.
thus:
Code:
getNodes("id");//get any tag with an id attrib
getNodes("className");//get any tag with a class attrib
getNodes("data");//get any text node (only text nodes have a .data property)
getNodes("nodeType");//since all nodes have a nodeType, this gets any tag, any comment, and all text nodes (everything!)

to illustrate the above examples, imagine that you rounded up every node and subnode in the page or document into a list (array).

then, one-by-one, you went though the list and decided which ones you really wanted, and which ones shouldn't be on the list after all.

to determine if one of the nodes should be on the list you check it for a single property; a "smoking gun" that only the nodes you want will have.

this illustration basucally describes getNodes() using one argument, though getNodes() checks before adding it to the lst of "good" nodes, so there never is a "compete" node list to audit...


but just knowing that something has a property is ofter not enough.
usually, you also need to know the value of that property while comparing it to the value you want.

for example, if i'm looking for a content wrapper (<div id="content">), i need to look at all tags that have an id, and return the one(s) whose id attrib matches the one i specified in the second argument. since getNodes always gives out a list of nodes, i simply add [0] after the call to grab the first/only match:

Code:
getNodes("id", "content")[0] === document.getElementById("content")
i don't think id is that useful of a dom property to search since document.getElementById already does that.

but, here's where getNodes() breaks away from the usual dom methods; it's as easy to collect based on any property as it is an id.

---
i need sleep for today.
given the interest, i am reviewing features and performance, and will keep this page updated.
more soon.
__________________
my site (updated 5/13)
STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.6% IE9:9.8% IE10:10%

Last edited by rnd me; 12-17-2009 at 10:29 AM..
rnd me is offline   Reply With Quote
Old 12-17-2009, 06:35 AM   PM User | #4
godofreality
Regular Coder

 
godofreality's Avatar
 
Join Date: Jan 2009
Posts: 230
Thanks: 1
Thanked 15 Times in 15 Posts
godofreality can only hope to improve
i must admit this is one handy scriptet as i have dubbed them not sure where or how i would go about using sumthing like this at this time but knowing that u have done this and thrown it all into one simple package does open up tons of doors for programming ideas
__________________
woot found the avatar options...i swear they didn't exist b4
godofreality is offline   Reply With Quote
Old 02-05-2010, 03:56 PM   PM User | #5
rnd me
Senior Coder

 
rnd me's Avatar
 
Join Date: Jun 2007
Location: Urbana
Posts: 3,455
Thanks: 9
Thanked 466 Times in 450 Posts
rnd me is a jewel in the roughrnd me is a jewel in the roughrnd me is a jewel in the rough
rewritten for clarity:

Code:
function getNodes(prop, needle, blnMatch, node){
 	var results=[], any=(needle==null); 
	  node=node||document.documentElement;
 	  if(node.splice){ node={childNodes:node}; }
  	for(var it, i=0, kids=node.childNodes;it=kids[i];i++){
   		if(it.childNodes.length){
			results=results.concat(getNodes(prop, needle, blnMatch, it));
		}
		switch(true){
			case 	any && it[prop]:
			case 	it[prop]===needle:  
			case blnMatch && !!String(it[prop]).match(needle):
		     results[results.length]=it; 
		}
	}
   return results;
}//end getNodes()

//usage example: get all comments from the body
getNodes("nodeType", 8, false, document.body)
prop: a property of each node to examine
needle: a value to compare the node's property to
blnMatch: if true, uses a string.match instead of an equality compare (===)
node: the root node containing all the nodes to be searched

all arguments except prop are optional.
if you don't pass a val, anything that has the property set to something besides 0, false or null will hit.
__________________
my site (updated 5/13)
STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.6% IE9:9.8% IE10:10%

Last edited by rnd me; 02-05-2010 at 03:59 PM..
rnd me is offline   Reply With Quote
Old 02-05-2010, 04:06 PM   PM User | #6
gsnedders
Senior Coder

 
gsnedders's Avatar
 
Join Date: Jan 2004
Posts: 2,340
Thanks: 1
Thanked 7 Times in 7 Posts
gsnedders will become famous soon enough
Will this not enter an infinite loop if you have a non-tree DOM in IE?
__________________
Geoffrey Sneddon
gsnedders is offline   Reply With Quote
Old 02-05-2010, 04:45 PM   PM User | #7
rnd me
Senior Coder

 
rnd me's Avatar
 
Join Date: Jun 2007
Location: Urbana
Posts: 3,455
Thanks: 9
Thanked 466 Times in 450 Posts
rnd me is a jewel in the roughrnd me is a jewel in the roughrnd me is a jewel in the rough
Quote:
Originally Posted by gsnedders View Post
Will this not enter an infinite loop if you have a non-tree DOM in IE?
i've not had any problems with it.
then again, i'm not sure i understand what you mean by "non-tree dom", can you give an example?
__________________
my site (updated 5/13)
STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.6% IE9:9.8% IE10:10%
rnd me 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 Off
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 12:42 PM.


Advertisement
Log in to turn off these ads.