Skip to content

Instantly share code, notes, and snippets.

@m3g4p0p
Last active August 26, 2016 15:51
Show Gist options
  • Save m3g4p0p/3d2a3af2c64425fed88ad36a731d567c to your computer and use it in GitHub Desktop.
Save m3g4p0p/3d2a3af2c64425fed88ad36a731d567c to your computer and use it in GitHub Desktop.
Some ideas for simply DOM helper functions
/**
* Get an array (!) of elements in a given context
*/
const find = (selector, context) =>
Array.from((context || document).querySelectorAll(selector));
/**
* Create a new element and optionally initialize it
* with some content and attributes
*/
const create = function(tagName, innerHTML, attributes) {
const element = document.createElement(tagName);
if (innerHTML && typeof innerHTML === 'string') {
element.innerHTML = innerHTML;
} else {
attributes = innerHTML;
}
if (!attributes) return element;
for (let attr in attributes) {
if (attributes.hasOwnProperty(attr)) {
element.setAttribute(attr, attributes[attr]);
}
}
return element;
};
/**
* Get the ancestor of an element that matches the
* selector
*/
const next = function(element, selector) {
var parent = element.parentElement;
if (parent.matches(selector)) return parent;
if (parent === document.body) return null;
return next(parent, selector);
}
/**
* Get the sibling elements of an element, optionally
* filtered by a selector
*/
const siblings = function(element, selector) {
const nodes = Array.from(element.parentNode.childNodes);
return nodes.filter(
node => node instanceof Element
&& node !== element
&& node.matches(selector)
);
};
/**
* Add some classes to an element or any iterable
* collection of elements
*/
const addClass = function(element, ...classes) {
// Also account for collections of elements
if (element.length !== undefined) {
Array.from(element).forEach(current => addClass(current, ...classes));
} else {
element.classList.add(...classes);
}
};
/**
* Replace an element or any iterable collection of elements
* with a clone of another element
*/
const replace = function(newElement, oldElement, deep = true) {
const clone = newElement.cloneNode(deep);
if (oldElement.length !== undefined) {
return Array.from(oldElement).reduce(
(carry, current) => carry.concat(replace(newElement, current, deep)),
[]
);
}
return [oldElement.parentNode.replaceChild(clone, oldElement)];
};
/**
* Add event listeners, saves you typing 14 characters :-)
*/
const on = function(element, event, callback, options = false) {
if (element.length !== undefined) {
Array.from(element).forEach(current => on(current, event, callback, options));
} else {
element.addEventListener(event, callback, options);
}
};
@m3g4p0p
Copy link
Author

m3g4p0p commented Aug 26, 2016

<!DOCTYPE html>
<html>
<head>
  <title>Example</title>
</head>
<body>

  <div class="foo">Foo</div>
  <div class="bar">Bar</div>
  <div class="bar">Bar</div>

  <script type="text/javascript">
    const link = create('a', 'foo', {href: '#'});

    replace(link, find('.bar'));

    on(find('a'), 'click', function() {
      addClass(siblings(this, 'div'), 'baz');
    });
  </script>
</body>
</html>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment