DEV Community

Discussion on: Writing a .parents() function using Vanilla JS

Collapse
 
maxxheth profile image
Maximillian Heth

Regarding your example in which you looped through the paragraph elements, it's worth noting that it's also possible to use event delegation in vanilla JS so you can avoid looping altogether:

document.addEventListener('click', function(event) {

    if (event.target.tagName !== 'P') return; // If it's not a paragraph element, skip it.

    event.target.textContent += ' has been modified...';

});
Enter fullscreen mode Exit fullscreen mode

Also, nice function you wrote there! To further bolster our collective laziness as devs, I added some features to allow the function to receive class or ID strings as arguments and pick a specific element via an index if multiple elements share the same class or tag name:

function getParents(el, parentSelector, elIndex, parentIndex) {
  if (parentSelector === undefined) {
    parentSelector = document;
  }

  function ifStringUseQS(selector, index) {

    if (!index) index = 0;

    if (Object.prototype.toString.call(selector).toLowerCase().indexOf('string') > -1) { // Is it a string?

      /**
       * 
       * If the selector can potentially refer to more than one element, 
       * then entering an index will allow you grab that specific element.
       * 
       */

        return document.querySelectorAll(selector)[index]; 

    } else {

        return selector; // If it's not a string, it'll just be reassigned unto itself.

        }

  }

  el = ifStringUseQS(el, elIndex);

  parentSelector = ifStringUseQS(parentSelector, parentIndex);


  if (!el) return; // If el is undefined, hit the brakes.


  var parents = [];
  var p = el.parentNode;
  while (p !== parentSelector) {
    parents.push(p);
    p = p.parentNode;
  }
  parents.push(parentSelector);
  return parents;
}
Enter fullscreen mode Exit fullscreen mode

So now you can use the function like so:

// Grab an element.

getParents('.some-elem');

// Grab an element and set the uppermost parent.

getParents('.some-elem', '.some-parent');

// Choose a different element or a different parent with the same class.

getParents('.some-elem', '.some-parent', 2, 4);
Enter fullscreen mode Exit fullscreen mode