JavaScript Document Object (DOM) Helpers
Tags: javascript
Published: 2019-12-15 14:23:28

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/hnkg7wac6xu0mfhj92zl.png)

A few DOM helpers to assist with the transition from jQuery to vanilla JavaScript.

#### indexInParent

```javascript
export function indexInParent(el) {
    let children = el.parentNode.childNodes;
    let num = 0;

    for (let i = 0; i < children.length; i++) {
        if (children[i] == el) return num;
        if (children[i].nodeType == 1) num++;
    }
    return -1;
}
```

#### indexOfParent

```javascript
export function indexOfParent(el) {
    return [].indexOf.call(el.parentElement.children, el);
}
```

#### matches

```javascript
export function matches(elem, selector) {
    const isMsMatch = 'msMatchesSelector' in elem && elem.msMatchesSelector(selector);
    const isMatchSelector = 'matchesSelector' in elem && elem.matchesSelector(selector)
    const isMatch = 'matches' in elem && elem.matches(selector);
    // Test the element to see if it matches the provided selector
    // use different methods for compatibility
    return isMsMatch || isMatchSelector || isMatch;
    // Return the result of the test
    // If any of the above variables is true, the return value will be true
}
```

#### closest

For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.

Depends on `matches`;

```javascript
export function getClosest(elem, selector) {
    // This allows for matching based on any selector, not just a single class.
    for (; elem && elem !== document; elem = elem.parentNode) {
        // Traverse up the dom until document is reached
        if (matches(elem, selector)) {
            // Test each element to see if it matches. If it does, return it.
            return elem
        }
    }
    return null;
}

export const closest = getClosest;
```

Usage for the above that's in a file set up for [tree shaking](https://developers.google.com/web/fundamentals/performance/optimizing-javascript/tree-shaking), e.g., `helpers.js`
```
import { closest } from 'js/helpers';
```

#### offset top

```javascript
export function getOffsetTop(el) {
    let offsetTop = 0;
    do {
        if (!isNaN(el.offsetTop)) {
            offsetTop += el.offsetTop;
        }
    } while (el = el.offsetParent);
    return offsetTop;
}
```

#### next

Get the immediately following sibling of each element in the set of matched elements.

Depends on `matches`, `prev`;

```javascript
export function next(el, selector) {
    if (el.nextElementSibling) {
        if (matches(el.nextElementSibling, selector)) {
            return el.nextElementSibling;
        } else {
            return prev(el.nextElementSibling, selector);
        }
    }

    return false;
}
```

#### prev

Get the immediately preceding sibling of each element in the set of matched elements.

Depends on `matches`;

```javascript
export function prev(el, selector) {
    if (el.previousElementSibling) {
        if (matches(el.previousElementSibling, selector)) {
            return el.previousElementSibling;
        } else {
            return prev(el.previousElementSibling, selector);
        }
    }

    return false;
}
```

#### siblings

Get the siblings of each element in the set of matched elements.

Depends on `matches`;

```javascript
export function siblings(el, selector) {
    return Array.prototype.filter.call(el.parentNode.children, function (child) {
        return matches(child, selector);
    }) || [];
}
```

Originally published at [jimfrenette.com/javascript/document](https://jimfrenette.com/javascript/document/)