Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 7 of 7
  1. #1
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,373
    Thanks
    11
    Thanked 592 Times in 572 Posts

    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?
    Last edited by rnd me; 11-18-2009 at 08:15 AM.
    my site (updated 13/9/26)
    BROWSER STATS [% share] (2014/9/03) IE7:0.1, IE8:4.6, IE11:9.1, IE9:3.1, IE10:3.0, FF:17.2, CH:46, SF:11.4, NON-MOUSE:38%

  • #2
    Senior Coder jmrker's Avatar
    Join Date
    Aug 2006
    Location
    FL
    Posts
    3,091
    Thanks
    38
    Thanked 498 Times in 492 Posts

    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!

  • #3
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,373
    Thanks
    11
    Thanked 592 Times in 572 Posts
    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.
    Last edited by rnd me; 12-17-2009 at 10:29 AM.
    my site (updated 13/9/26)
    BROWSER STATS [% share] (2014/9/03) IE7:0.1, IE8:4.6, IE11:9.1, IE9:3.1, IE10:3.0, FF:17.2, CH:46, SF:11.4, NON-MOUSE:38%

  • #4
    Regular Coder godofreality's Avatar
    Join Date
    Jan 2009
    Posts
    234
    Thanks
    1
    Thanked 15 Times in 15 Posts
    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

  • #5
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,373
    Thanks
    11
    Thanked 592 Times in 572 Posts
    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.
    Last edited by rnd me; 02-05-2010 at 03:59 PM.
    my site (updated 13/9/26)
    BROWSER STATS [% share] (2014/9/03) IE7:0.1, IE8:4.6, IE11:9.1, IE9:3.1, IE10:3.0, FF:17.2, CH:46, SF:11.4, NON-MOUSE:38%

  • #6
    Senior Coder gsnedders's Avatar
    Join Date
    Jan 2004
    Posts
    2,340
    Thanks
    1
    Thanked 7 Times in 7 Posts
    Will this not enter an infinite loop if you have a non-tree DOM in IE?

  • #7
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,373
    Thanks
    11
    Thanked 592 Times in 572 Posts
    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 13/9/26)
    BROWSER STATS [% share] (2014/9/03) IE7:0.1, IE8:4.6, IE11:9.1, IE9:3.1, IE10:3.0, FF:17.2, CH:46, SF:11.4, NON-MOUSE:38%


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •