I'm just a painter who studied computer science.
DOM Traversing
DOM Traversing "Atravesando el DOM"
DOM es un árbol de elementos, con el nodo raíz, que apunta al nodo html, que a su vez apunta a la cabeza y el cuerpo de sus nodos elementos secundarios, y así sucesivamente. Desde cada uno de esos elementos, puede navegar por la estructura DOM y moverse a diferentes nodos.
Recorriendo el DOM hacia abajo
querySelector y querySelectorAll
querySelector y querySelectorAll no se limitan solo a ejecutarse en el documento. Se pueden ejecutar en cualquier elemento para buscar solo elementos dentro de él.
<section class="section" id="section_1">Section Content</section>
<section class="section" id="section_2">Section Content</section>
<section class="section" id="section_3">Section Content</section>
let element = document.querySelector('#section_2');
console.dir(element); //-> section#section_2.section
let elements = document.querySelectorAll('section');
console.dir(elements); //-> NodeList(3)
children
Mientras querySelector y querySelectorAll buscan en todos los niveles dentro de una estructura DOM / HTML anidada, es posible que desee obtener descendientes inmediatos de un elemento en particular. Para esto utilizamos children.
<section class="section" id="section_1">Section Content<a href="webpage">Link</a></section>
<section class="section" id="section_2">Section Content</section>
<section class="section" id="section_3">Section Content</section>
let element = document.querySelector('#section_1');
let decendants = element.children;
console.dir(decendants); //-> HTMLCollection(1)
Recorriendo el DOM hacia arriba
parentNode
Utilizamos parentNode para obtener el padre de un elemento.
<section class="section" id="section_1">Section Content<a href="webpage" id="link_1" >Link</a></section>
<section class="section" id="section_2">Section Content</section>
<section class="section" id="section_3">Section Content</section>
let element = document.querySelector('#link_1');
let parent = element.parentNode;
console.dir(parent); //-> section#section_1.section
getClosest
getClosest es un método que escribímos como utilidad para obtener el padre más cercano en el árbol DOM que coincide con un selector. Este metodo es equivalente al método .closest de jQuery.
<section class="section">
<ul class="lists-outer" data-lists="one">
<ul class="lists-inner" data-lists="two>">
<li><span id="number_1">Number One</span></li>
<li><span id="number_2">Number Two</span></li>
</ul>
</ul>
</section>
let getClosest = function(elem, selector) {
// Element.matches() polyfill
if(!Element.prototype.matches) {
Element.prototype.matches =
Element.prototype.matchesSelector ||
Element.prototype.mozMatchesSelector ||
Element.prototype.msMatchesSelector ||
Element.prototype.oMatchesSelector ||
Element.prototype.webkitMatchesSelector ||
function(s) {
let matches = (this.document || this.ownerDocument).querySelectorAll(s),
i = matches.length;
while(--i >= 0 && matches.item(i) !== this) {}
return i > -1;
};
}
// Get closest match
for( ; elem && elem !== document; elem = elem.parentNode) {
if ( elem.matches( selector ) ) return elem;
}
return null;
};
let element = document.querySelector("#number_1");
let closestParent = getClosest(element, 'ul');
console.dir(closestParent); //-> ul.lists-inner
let closestParentByDataAttr = getClosest(element, '[data-lists]');
console.dir(closestParentByDataAttr); //-> ul.lists-inner
getParents
getParents es un método que escribímos como utilidad para obtener una matriz de elementos padres, opcionalmente coincidiendo con un selector. Este metodo es equivalente al método .parents de jQuery.
<section class="section">
<ul class="lists-outer" data-lists="one">
<ul class="lists-inner" data-lists="two>">
<li><span id="number_1">Number One</span></li>
<li><span id="number_2">Number Two</span></li>
</ul>
</ul>
</section>
let getParents = function(elem, selector) {
// Element.matches() polyfill
if(!Element.prototype.matches) {
Element.prototype.matches =
Element.prototype.matchesSelector ||
Element.prototype.mozMatchesSelector ||
Element.prototype.msMatchesSelector ||
Element.prototype.oMatchesSelector ||
Element.prototype.webkitMatchesSelector ||
function(s) {
let matches = (this.document || this.ownerDocument).querySelectorAll(s),
i = matches.length;
while (--i >= 0 && matches.item(i) !== this) {}
return i > -1;
};
}
// Setup parents array
let parents = [];
// Get matching parent elements
for(; elem && elem !== document; elem = elem.parentNode) {
// Add matching parents to array
if(selector) {
if(elem.matches(selector)) {
parents.push( elem );
}
}
else {
parents.push(elem);
}
}
return parents;
};
let element = document.querySelector("#number_1");
let closestParentSelector = getParents(element, 'ul');
console.dir(closestParentSelector); //-> Array(2) 0: ul.lists-inner 1: ul.lists-outer
let closestParentAll = getParents(element);
console.dir(closestParentAll); //-> Array(7) 0: span#number_1 1: li 2: ul.lists-inner 3: ul.lists-outer 4: section.section 5: body 6: html
getParentsUntil
getParentsUntil es un método que escribímos como utilidad para obtener una matriz de elementos principales hasta que se encuentre un elemento padre coincidente, opcionalmente coincidente con un selector. Este metodo es equivalente al método .parentsUntil de jQuery.
<section class="section">
<ul class="lists-outer" data-lists="one">
<ul class="lists-inner" data-lists="two>">
<li><span id="number_1">Number One</span></li>
<li><span id="number_2">Number Two</span></li>
</ul>
</ul>
</section>
let getParentsUntil = function(elem, parent, selector) {
// Element.matches() polyfill
if(!Element.prototype.matches) {
Element.prototype.matches =
Element.prototype.matchesSelector ||
Element.prototype.mozMatchesSelector ||
Element.prototype.msMatchesSelector ||
Element.prototype.oMatchesSelector ||
Element.prototype.webkitMatchesSelector ||
function(s) {
let matches = (this.document || this.ownerDocument).querySelectorAll(s),
i = matches.length;
while (--i >= 0 && matches.item(i) !== this) {}
return i > -1;
};
}
// Setup parents array
let parents = [];
// Get matching parent elements
for(; elem && elem !== document; elem = elem.parentNode) {
if(parent) {
if(elem.matches(parent)) break;
}
if(selector) {
if(elem.matches(selector)) {
parents.push(elem);
}
break;
}
parents.push( elem );
}
return parents;
};
let element = document.querySelector("#number_1");
let parentsUntil = getParentsUntil(element, '.section');
console.dir(parentsUntil); //-> Array(4) 0: span#number_1 1: li 2: ul.lists-inner 3: ul.lists-outer
Atravesando lateralmente en el DOM
getSiblings es un método que escribímos como utilidad para obtiene los hermanos de un elemento en el DOM. Por ejemplo: si tenía un elemento de la lista li y quería obtener todos los demás elementos de la lista.
<section class="section">
<ul class="lists-outer" data-lists="one">
<ul class="lists-inner" data-lists="two>">
<li id="number_1">><span>Number One</span></li>
<li id="number_2">><span>Number Two</span></li>
<li id="number_3">><span>Number Three</span></li>
<li id="number_4">><span>Number Four</span></li>
</ul>
</ul>
</section>
let getSiblings = function(elem) {
let siblings = [];
let sibling = elem.parentNode.firstChild;
for(; sibling; sibling = sibling.nextSibling) {
if(sibling.nodeType === 1 && sibling !== elem) {
siblings.push( sibling );
}
}
return siblings;
};
let element = document.querySelector("#number_3");
let siblings = getSiblings(element);
console.dir(siblings); //-> Array(3) 0: li#number_1 1: li#number_2 2: li#number_4