Created
April 16, 2019 23:36
-
-
Save luisenriquecorona/043b7b4be4e3d271915ef42d0f4f4a4f to your computer and use it in GitHub Desktop.
Portable Document Traversal Fuctions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Return the nth ancestor of e, or null if there is no such ancestor | |
* or if that ancestor is not an Element (a Document or DocumentFragment e.g.). | |
* If n is 0 return e itself. If n is 1 (or | |
* omitted) return the parent. If n is 2, return the grandparent, etc. | |
*/ | |
function parent(e, n) { | |
if (n === undefined) n = 1; | |
while(n-- && e) e = e.parentNode; | |
if (!e || e.nodeType !== 1) return null; | |
return e; | |
} | |
/** | |
* Return the nth sibling element of Element e. | |
* If n is postive return the nth next sibling element. | |
* If n is negative, return the -nth previous sibling element. | |
* If n is zero, return e itself. | |
*/ | |
function sibling(e,n) { | |
while(e && n !== 0) { // If e is not defined we just return it | |
if (n > 0) { // Find next element sibling | |
if (e.nextElementSibling) e = e.nextElementSibling; | |
else { | |
for(e=e.nextSibling; e && e.nodeType !== 1; e=e.nextSibling) | |
/* empty loop */ ; | |
} | |
n--; | |
} | |
else { // Find the previous element sibling | |
if (e.previousElementSibing) e = e.previousElementSibling; | |
else { | |
for(e=e.previousSibling; e&&e.nodeType!==1; e=e.previousSibling) | |
/* empty loop */ ; | |
} | |
n++; | |
} | |
} | |
return e; | |
} | |
/** | |
* Return the nth element child of e, or null if it doesn't have one. | |
* Negative values of n count from the end. 0 means the first child, but | |
* -1 means the last child, -2 means the second to last, and so on. | |
*/ | |
function child(e, n) { | |
if (e.children) { // If children array exists | |
if (n < 0) n += e.children.length; // Convert negative n to array index | |
if (n < 0) return null; // If still negative, no child | |
return e.children[n]; // Return specified child | |
} | |
// If e does not have a children array, find the first child and count | |
// forward or find the last child and count backwards from there. | |
if (n >= 0) { // n is non-negative: count forward from the first child | |
// Find the first child element of e | |
if (e.firstElementChild) e = e.firstElementChild; | |
else { | |
for(e = e.firstChild; e && e.nodeType !== 1; e = e.nextSibling) | |
/* empty */; | |
} | |
return sibling(e, n); // Return the nth sibling of the first child | |
} | |
else { // n is negative, so count backwards from the end | |
if (e.lastElementChild) e = e.lastElementChild; | |
else { | |
for(e = e.lastChild; e && e.nodeType !== 1; e=e.previousSibling) | |
/* empty */; | |
} | |
return sibling(e, n+1); // +1 to convert child -1 to sib 0 of last | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment