/ Published in: JavaScript
Expand |
Embed | Plain Text
//nodeType "constants" if(!document.ELEMENT_NODE) { document.ELEMENT_NODE = 1; document.ATTRIBUTE_NODE = 2; document.TEXT_NODE = 3; document.CDATA_NODE = 4; document.ENTITY_REFERENCE_NODE = 5; document.ENTITY_NODE = 6; document.PROCESSING_INSTRUCTION_NODE = 7; document.COMMENT_NODE = 8; document.DOCUMENT_NODE = 9; document.DOCUMENT_TYPE_NODE = 10; document.DOCUMENT_FRAGMENT_NODE = 11; document.NOTATION_NODE = 12; } //get an element by its ID //returns null if not found function $id(id) { var elem = document.getElementById(id); if(elem && elem.id == id) return elem; //in IE, getElementById() returns the first element with *either* a matching id or a matching name else if(elem) //it returned an element without a matching id { var nodes = document.getElementsByTagName("*"); for(var i=0; i<nodes.length; i++) { if(nodes[i].id == id) return nodes[i]; //first element with a matching id } } return null; } //get elements by tag name function $tag(tag) { var nodes = document.getElementsByTagName(tag); //if tag=="*", IE returns comment nodes as well (including DOCTYPE) //`nodes` is now a NodeList or HTMLCollection object; this function converts it to an array var elems = []; for(var i=0; i<nodes.length; i++) { if(nodes[i].nodeType == document.ELEMENT_NODE) elems.push(nodes[i]); //add the element to the array } return elems; } //*******************************************************************// //***** to deal with empty text/CDATA nodes (i.e., ignore them) *****// //*******************************************************************// function getPreviousSibling(obj) { var prevNode = obj.previousSibling; while(prevNode && (prevNode.nodeType == document.TEXT_NODE || prevNode.nodeType == document.CDATA_NODE) && prevNode.nodeValue.match(/^\s*$/)) //it's an empty text node { prevNode = prevNode.previousSibling; } return prevNode; } function getNextSibling(obj) { var nextNode = obj.nextSibling; while(nextNode && (nextNode.nodeType == document.TEXT_NODE || nextNode.nodeType == document.CDATA_NODE) && nextNode.nodeValue.match(/^\s*$/)) //it's an empty text node { nextNode = nextNode.nextSibling; } return nextNode; } function getChildNodes(obj) { var children = obj.childNodes; var nodes = []; for(var i=0; i<children.length; i++) { if((children[i].nodeType == document.TEXT_NODE || children[i].nodeType == document.CDATA_NODE) && children[i].nodeValue.match(/^\s*$/)) continue; //it's an empty text node nodes.push(children[i]); } return nodes; } //**********************************// //***** get element nodes only *****// //**********************************// function getPreviousElement(obj) { var prevNode = obj.previousSibling; while(prevNode && prevNode.nodeType != document.ELEMENT_NODE) //it's not an element node { prevNode = prevNode.previousSibling; } return prevNode; } function getNextElement(obj) { var nextNode = obj.nextSibling; while(nextNode && nextNode.nodeType != document.ELEMENT_NODE) //it's not an element node { nextNode = nextNode.nextSibling; } return nextNode; } function getChildElements(obj) { var children = obj.childNodes; var elems = []; if(children) { for(var i=0; i<children.length; i++) { if(children[i].nodeType == document.ELEMENT_NODE) //it's an element node { elems.push(children[i]); } } } return elems; } //get descendant elements of obj function getDescendantElements(obj, childrenOnly) { var elems = getChildElements(obj); var results = []; for(var i=0; i<elems.length; i++) { results.push(elems[i]); if(!childrenOnly) { results = results.concat(getDescendantElements(elems[i])); } } return results; } //get ancestral elements of obj (nearest first) function getAncestralElements(obj) { var results = []; while(obj.parentNode) { obj = obj.parentNode; results.push(obj); } return results; } //get elements of type tagName that are descendants of obj function getDescendantsByTagName(obj, tagName, childrenOnly) { var results = []; if(!tagName) return results; tagName = tagName.toLowerCase(); var elems = getChildElements(obj); for(var i=0; i<elems.length; i++) { if(elems[i].nodeName.toLowerCase() == tagName) results.push(elems[i]); if(!childrenOnly) { results = results.concat(getDescendantsByTagName(elems[i], tagName)); } } return results; } //get elements of type tagName that are ancestors of obj (nearest first) function getAncestorsByTagName(obj, tagName, nearestOnly) { var results = []; if(!tagName) return results; tagName = tagName.toLowerCase(); while(obj.parentNode) { obj = obj.parentNode; if(obj.nodeName.toLowerCase() == tagName) { results.push(obj); if(nearestOnly) break; } } return results; } //get elements with class(es) className that are descendants of obj function getDescendantsByClassName(obj, className, childrenOnly) { var results = []; if(!className) return results; var elems = getChildElements(obj); var classes = className.match(/(^|\s)\S+(\s|$)/ig); var rexp; var j; for(var i=0; i<elems.length; i++) { for(j=0; j<classes.length; j++) { classes[j] = classes[j].replace(/\s?(\S+)\s?/, "$1"); rexp = new RegExp("(^|\\s)"+classes[j]+"(\\s|$)"); if(!rexp.test(elems[i].className)) break; //one of the classes was not found } if(j == classes.length) results.push(elems[i]); //if elems[i].className includes all the classes, add elems[i] if(!childrenOnly) { results = results.concat(getDescendantsByClassName(elems[i], className)); } } return results; } //get elements with class(es) className that are ancestors of obj (nearest first) function getAncestorsByClassName(obj, className, nearestOnly) { var results = []; if(!className) return results; var classes = className.match(/(^|\s)\S+(\s|$)/ig); var rexp; var j; while(obj.parentNode) { obj = obj.parentNode; for(j=0; j<classes.length; j++) { classes[j] = classes[j].replace(/\s?(\S+)\s?/, "$1"); rexp = new RegExp("(^|\\s)"+classes[j]+"(\\s|$)"); if(!rexp.test(obj.className)) break; //one of the classes was not found } if(j == classes.length) //if obj.className includes all the classes { results.push(obj); if(nearestOnly) break; } } return results; } //get elements with a path such as "div.class1 span.class2a.class2b * .class3" function getDescendantsByPath(obj, path) { var results = []; if(!path) return results; var node = path.split(" ")[0]; path = path.slice(node.length+1); var attrs = node.split("."); if(!attrs) return results; var elems = getChildElements(obj); var rexp; var j; for(var i=0; i<elems.length; i++) { if(attrs[0] && attrs[0] != "*" && elems[i].nodeName.toLowerCase() != attrs[0]) continue; //if a tag name was specified but it doesn't match for(j=1; j<attrs.length; j++) { if(!attrs[j]) continue; rexp = new RegExp("(^|\\s)"+attrs[j]+"(\\s|$)"); if(!rexp.test(elems[i].className)) break; //one of the classes was not found } if(j == attrs.length) //if elems[i].className includes all the classes { if(path) //if there is more to the path results = results.concat(getDescendantsByPath(elems[i], path)); else results.push(elems[i]); } } return results; }
Comments
Subscribe to comments
You need to login to post a comment.

Replaced $() with $id(), and added $tag()