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