DOMtastic

Array

every (callback, thisArg)

Checks if the given callback returns a true(-ish) value for each element in the collection.

Arguments
callback Function

Function to execute for each element, invoked with element as argument.

thisArg Object

Value to use as this when executing callback.

optional

Returns
Boolean  

Whether each element passed the callback check.

    // Test whether every element in the collection has the "active" attribute
    $('.items').every(function(element) {
        return element.hasAttribute('active')
    });
export const every = ArrayProto.every;

filter (selector, thisArg)

Filter the collection by selector or function, and return a new collection with the result.

Arguments
selector String or Function

Selector or function to filter the collection.

thisArg Object

Value to use as this when executing callback.

optional

Returns
Object  

A new wrapped collection

chainable

    $('.items').filter('.active');
    $('.items').filter(function(element) {
        return element.hasAttribute('active')
    });
export const filter = function(selector, thisArg) {
  const callback = typeof selector === 'function' ? selector : element => matches(element, selector);
  return $(ArrayProto.filter.call(this, callback, thisArg));
};

forEach (callback, thisArg)

Execute a function for each element in the collection.

Arguments
callback Function

Function to execute for each element, invoked with element as argument.

thisArg Object

Value to use as this when executing callback.

optional

Returns
Object  

The wrapped collection

chainable

    $('.items').forEach(function(element) {
        element.style.color = 'evergreen';
    );
export const forEach = function(callback, thisArg) {
  return _each(this, callback, thisArg);
};

export const each = forEach;

indexOf (element)

Returns the index of an element in the collection.

Arguments
element Node

Returns
Number  

The zero-based index, -1 if not found.

    $('.items').indexOf(element); // 2
export const indexOf = ArrayProto.indexOf;

map (callback, thisArg)

Create a new collection by executing the callback for each element in the collection.

Arguments
callback Function

Function to execute for each element, invoked with element as argument.

thisArg Object

Value to use as this when executing callback.

optional

Returns
Array  

Collection with the return value of the executed callback for each element.

    // Create a new array with the attribute value of each element:
    $('.items').map(function(element) {
        return element.getAttribute('name')
export const map = ArrayProto.map;

pop ()

Removes the last element from the collection, and returns that element.

Returns
Object  

The last element from the collection.

    var lastElement = $('.items').pop();
export const pop = ArrayProto.pop;

push (element)

Adds one or more elements to the end of the collection, and returns the new length of the collection.

Arguments
element Object

Element(s) to add to the collection

Returns
Number  

The new length of the collection

    $('.items').push(element);
export const push = ArrayProto.push;

reduce (callback, initialValue)

Apply a function against each element in the collection, and this accumulator function has to reduce it
to a single value.

Arguments
callback Function

Function to execute on each value in the array, taking four arguments (see example).

initialValue Mixed

Object to use as the first argument to the first call of the callback.

    // Calculate the combined height of elements:
    $('.items').reduce(function(previousValue, element, index, collection) {
        return previousValue + element.clientHeight;
    }, 0);
export const reduce = ArrayProto.reduce;

reduceRight (callback, initialValue)

Apply a function against each element in the collection (from right-to-left), and this accumulator function has
to reduce it to a single value.

Arguments
callback Function

Function to execute on each value in the array, taking four arguments (see example).

initialValue Mixed

Object to use as the first argument to the first call of the callback.

    // Concatenate the text of elements in reversed order:
    $('.items').reduceRight(function(previousValue, element, index, collection) {
        return previousValue + element.textContent;
    }, '');
export const reduceRight = ArrayProto.reduceRight;

reverse ()

Reverses an array in place. The first array element becomes the last and the last becomes the first.

Returns
Object  

The wrapped collection, reversed

chainable

    $('.items').reverse();
export const reverse = function() {
  return $(toArray(this).reverse());
};

shift ()

Removes the first element from the collection, and returns that element.

Returns
Object  

The first element from the collection.

    var firstElement = $('.items').shift();
export const shift = ArrayProto.shift;

some (callback)

Checks if the given callback returns a true(-ish) value for any of the elements in the collection.

Arguments
callback Function

Function to execute for each element, invoked with element as argument.

Returns
Boolean  

Whether any element passed the callback check.

    $('.items').some(function(element) {
        return element.hasAttribute('active')
    }); // true/false
export const some = ArrayProto.some;

unshift (element)

Adds one or more elements to the beginning of the collection, and returns the new length of the collection.

Arguments
element Object

Element(s) to add to the collection

Returns
Number  

The new length of the collection

    $('.items').unshift(element);
export const unshift = ArrayProto.unshift;

BaseClass

BaseClass ()

Provide subclass for classes or components to extend from.
The opposite and successor of plugins (no need to extend $.fn anymore, complete control).

Returns
Class  

The class to extend from, including all $.fn methods.

    import { BaseClass } from  'domtastic';

    class MyComponent extends BaseClass {
        doSomething() {
            return this.addClass('.foo');
        }
    }

    let component = new MyComponent('body');
    component.doSomething();
    import $ from  'domtastic';

    class MyComponent extends $.BaseClass {
        progress(value) {
            return this.attr('data-progress', value);
        }
    }

    let component = new MyComponent(document.body);
    component.progress('ive').append('<p>enhancement</p>');
class BaseClass {
  constructor() {
    DOMtastic.call(this, selector(...arguments));
  }
}
extend(BaseClass.prototype, api);
return BaseClass;
}

CSS

css (key, value)

Get the value of a style property for the first element, or set one or more style properties for each element in the collection.

Arguments
key String or Object

The name of the style property to get or set. Or an object containing key-value pairs to set as style properties.

value String

The value of the style property to set.

optional

Returns
Object  

The wrapped collection

chainable

    $('.item').css('padding-left'); // get
    $('.item').css('color', '#f00'); // set
    $('.item').css({'border-width': '1px', display: 'inline-block'}); // set multiple
export const css = function(key, value) {

  let styleProps, prop, val;

  if(typeof key === 'string') {
    key = camelize(key);

    if(typeof value === 'undefined') {
      let element = this.nodeType ? this : this[0];
      if(element) {
        val = element.style[key];
        return isNumeric(val) ? parseFloat(val) : val;
      }
      return undefined;
    }

    styleProps = {};
    styleProps[key] = value;
  } else {
    styleProps = key;
    for(prop in styleProps) {
      val = styleProps[prop];
      delete styleProps[prop];
      styleProps[camelize(prop)] = val;
    }
  }

  each(this, element => {
    for(prop in styleProps) {
      if(styleProps[prop] || styleProps[prop] === 0) {
        element.style[prop] = styleProps[prop];
      } else {
        element.style.removeProperty(dasherize(prop));
      }
    }
  });

  return this;
};

DOM

append (element)

Append element(s) to each element in the collection.

Arguments
element String or Node or NodeList or Object

What to append to the element(s). Clones elements as necessary.

Returns
Object  

The wrapped collection

chainable

    $('.item').append('<p>more</p>');
export const append = function(element) {
  if(this instanceof Node) {
    if(typeof element === 'string') {
      this.insertAdjacentHTML('beforeend', element);
    } else {
      if(element instanceof Node) {
        this.appendChild(element);
      } else {
        const elements = element instanceof NodeList ? toArray(element) : element;
        forEach.call(elements, this.appendChild.bind(this));
      }
    }
  } else {
    _each(this, append, element);
  }
  return this;
};

prepend (element)

Place element(s) at the beginning of each element in the collection.

Arguments
element String or Node or NodeList or Object

What to place at the beginning of the element(s). Clones elements as necessary.

Returns
Object  

The wrapped collection

chainable

    $('.item').prepend('<span>start</span>');
export const prepend = function(element) {
  if(this instanceof Node) {
    if(typeof element === 'string') {
      this.insertAdjacentHTML('afterbegin', element);
    } else {
      if(element instanceof Node) {
        this.insertBefore(element, this.firstChild);
      } else {
        let elements = element instanceof NodeList ? toArray(element) : element;
        forEach.call(elements.reverse(), prepend.bind(this));
      }
    }
  } else {
    _each(this, prepend, element);
  }
  return this;
};

before (element)

Place element(s) before each element in the collection.

Arguments
element String or Node or NodeList or Object

What to place as sibling(s) before to the element(s). Clones elements as necessary.

Returns
Object  

The wrapped collection

chainable

    $('.items').before('<p>prefix</p>');
export const before = function(element) {
  if(this instanceof Node) {
    if(typeof element === 'string') {
      this.insertAdjacentHTML('beforebegin', element);
    } else {
      if(element instanceof Node) {
        this.parentNode.insertBefore(element, this);
      } else {
        const elements = element instanceof NodeList ? toArray(element) : element;
        forEach.call(elements, before.bind(this));
      }
    }
  } else {
    _each(this, before, element);
  }
  return this;
};

after (element)

Place element(s) after each element in the collection.

Arguments
element String or Node or NodeList or Object

What to place as sibling(s) after to the element(s). Clones elements as necessary.

Returns
Object  

The wrapped collection

chainable

    $('.items').after('<span>suf</span><span>fix</span>');
export const after = function(element) {
  if(this instanceof Node) {
    if(typeof element === 'string') {
      this.insertAdjacentHTML('afterend', element);
    } else {
      if(element instanceof Node) {
        this.parentNode.insertBefore(element, this.nextSibling);
      } else {
        const elements = element instanceof NodeList ? toArray(element) : element;
        forEach.call(elements.reverse(), after.bind(this));
      }
    }
  } else {
    _each(this, after, element);
  }
  return this;
};

clone ()

Clone a wrapped object.

Returns
Object  

Wrapped collection of cloned nodes.

    $(element).clone();
export const clone = function() {
  return $(_clone(this));
};

DOM/attr

attr (key, value)

Get the value of an attribute for the first element, or set one or more attributes for each element in the collection.

Arguments
key String or Object

The name of the attribute to get or set. Or an object containing key-value pairs to set as attributes.

value String

The value of the attribute to set.

optional

Returns
Object  

The wrapped collection

chainable

    $('.item').attr('attrName'); // get
    $('.item').attr('attrName', 'attrValue'); // set
    $('.item').attr({attr1: 'value1', 'attr-2': 'value2'}); // set multiple
export const attr = function(key, value) {

  if(typeof key === 'string' && typeof value === 'undefined') {
    const element = this.nodeType ? this : this[0];
    return element ? element.getAttribute(key) : undefined;
  }

  return each(this, element => {
    if(typeof key === 'object') {
      for(let attr in key) {
        element.setAttribute(attr, key[attr]);
      }
    } else {
      element.setAttribute(key, value);
    }
  });
};

removeAttr (key)

Remove attribute from each element in the collection.

Arguments
key String

Attribute name

Returns
Object  

The wrapped collection

chainable

    $('.items').removeAttr('attrName');
export const removeAttr = function(key) {
  return each(this, element => element.removeAttribute(key));
};

DOM/class

addClass (value)

Add a class to the element(s)

Arguments
value String

Space-separated class name(s) to add to the element(s).

Returns
Object  

The wrapped collection

chainable

    $('.item').addClass('bar');
    $('.item').addClass('bar foo');
export const addClass = function(value) {
  if(value && value.length) {
    each(value.split(' '), _each.bind(this, 'add'));
  }
  return this;
};

removeClass (value)

Remove a class from the element(s)

Arguments
value String

Space-separated class name(s) to remove from the element(s).

Returns
Object  

The wrapped collection

chainable

    $('.items').removeClass('bar');
    $('.items').removeClass('bar foo');
export const removeClass = function(value) {
  if(value && value.length) {
    each(value.split(' '), _each.bind(this, 'remove'));
  }
  return this;
};

toggleClass (value, state)

Toggle a class at the element(s)

Arguments
value String

Space-separated class name(s) to toggle at the element(s).

state Boolean

A Boolean value to determine whether the class should be added or removed.

optional

Returns
Object  

The wrapped collection

chainable

    $('.item').toggleClass('bar');
    $('.item').toggleClass('bar foo');
    $('.item').toggleClass('bar', true);
export const toggleClass = function(value, state) {
  if(value && value.length) {
    const action = typeof state === 'boolean' ? state ? 'add' : 'remove' : 'toggle';
    each(value.split(' '), _each.bind(this, action));
  }
  return this;
};

hasClass (value)

Check if the element(s) have a class.

Arguments
value String

Check if the DOM element contains the class name. When applied to multiple elements, returns true if any of them contains the class name.

Returns
Boolean  

Whether the element's class attribute contains the class name.

    $('.item').hasClass('bar');
export const hasClass = function(value) {
  return (this.nodeType ? [this] : this).some(element => element.classList.contains(value));
};

DOM/contains

contains (container, element)

Test whether an element contains another element in the DOM.

Arguments
container Element

The element that may contain the other element.

element Element

The element that may be a descendant of the other element.

Returns
Boolean  

Whether the container element contains the element.

    $.contains(parentElement, childElement); // true/false
export const contains = (container, element) => {
  if(!container || !element || container === element) {
    return false;
  } else if(container.contains) {
    return container.contains(element);
  } else if(container.compareDocumentPosition) {
    return !(container.compareDocumentPosition(element) & Node.DOCUMENT_POSITION_DISCONNECTED);
  }
  return false;
};

DOM/data

data (key, value)

Get data from first element, or set data for each element in the collection.

Arguments
key String

The key for the data to get or set.

value String

The data to set.

optional

Returns
Object  

The wrapped collection

chainable

    $('.item').data('attrName'); // get
    $('.item').data('attrName', {any: 'data'}); // set
export const data = function(key, value) {

  if(typeof key === 'string' && typeof value === 'undefined') {
    const element = this.nodeType ? this : this[0];
    return element && DATAKEYPROP in element ? element[DATAKEYPROP][key] : undefined;
  }

  return each(this, element => {
    if(!isSupportsDataSet) {
      element[DATAKEYPROP] = element[DATAKEYPROP] || {};
    }
    element[DATAKEYPROP][key] = value;
  });
};

prop (key, value)

Get property from first element, or set property on each element in the collection.

Arguments
key String

The name of the property to get or set.

value String

The value of the property to set.

optional

Returns
Object  

The wrapped collection

chainable

    $('.item').prop('attrName'); // get
    $('.item').prop('attrName', 'attrValue'); // set
export const prop = function(key, value) {

  if(typeof key === 'string' && typeof value === 'undefined') {
    const element = this.nodeType ? this : this[0];
    return element && element ? element[key] : undefined;
  }

  return each(this, element => element[key] = value);
};

DOM/extra

appendTo (element)

Append each element in the collection to the specified element(s).

Arguments
element Node or NodeList or Object

What to append the element(s) to. Clones elements as necessary.

Returns
Object  

The wrapped collection

chainable

    $('.item').appendTo(container);
export const appendTo = function(element) {
  const context = typeof element === 'string' ? $(element) : element;
  append.call(context, this);
  return this;
};

empty ()

Empty each element in the collection.

Returns
Object  

The wrapped collection

chainable

    $('.item').empty();
export const empty = function() {
  return each(this, element => element.innerHTML = '');
};

remove ()

Remove the collection from the DOM.

Returns
Array  

Array containing the removed elements

    $('.item').remove();
export const remove = function() {
  return each(this, element => {
    if(element.parentNode) {
      element.parentNode.removeChild(element);
    }
  });
};

replaceWith ()

Replace each element in the collection with the provided new content, and return the array of elements that were replaced.

Returns
Array  

Array containing the replaced elements

// Sorry, no example available.
export const replaceWith = function() {
  return before.apply(this, arguments).remove();
};

text (value)

Get the textContent from the first, or set the textContent of each element in the collection.

Arguments
value String optional

Returns
Object  

The wrapped collection

chainable

    $('.item').text('New content');
export const text = function(value) {

  if(value === undefined) {
    return this[0].textContent;
  }

  return each(this, element => element.textContent = '' + value);
};

val (value)

Get the value from the first, or set the value of each element in the collection.

Arguments
value String optional

Returns
Object  

The wrapped collection

chainable

    $('input.firstName').val('New value');
export const val = function(value) {

  if(value === undefined) {
    return this[0].value;
  }

  return each(this, element => element.value = value);
};

DOM/html

html (fragment)

Get the HTML contents of the first element, or set the HTML contents for each element in the collection.

Arguments
fragment String

HTML fragment to set for the element. If this argument is omitted, the HTML contents are returned.

optional

Returns
Object  

The wrapped collection

chainable

    $('.item').html();
    $('.item').html('<span>more</span>');
export const html = function(fragment) {

  if(typeof fragment !== 'string') {
    const element = this.nodeType ? this : this[0];
    return element ? element.innerHTML : undefined;
  }

  return each(this, element => element.innerHTML = fragment);
};

Event

on (eventNames, selector, handler, useCapture, once)

Shorthand for addEventListener. Supports event delegation if a filter (selector) is provided.

Arguments
eventNames String

List of space-separated event types to be added to the element(s)

selector String

Selector to filter descendants that delegate the event to this element.

optional
handler Function

Event handler

useCapture Boolean (default: false)
once Boolean (default: false)

Returns
Object  

The wrapped collection

chainable

    $('.item').on('click', callback);
    $('.container').on('click focus', '.item', handler);
export const on = function(eventNames, selector, handler, useCapture, once) {

  if(typeof selector === 'function') {
    handler = selector;
    selector = null;
  }

  let parts,
    namespace,
    eventListener;

  eventNames.split(' ').forEach(eventName => {

    parts = eventName.split('.');
    eventName = parts[0] || null;
    namespace = parts[1] || null;

    eventListener = proxyHandler(handler);

    each(this, element => {

      if(selector) {
        eventListener = delegateHandler.bind(element, selector, eventListener);
      }

      if(once) {
        const listener = eventListener;
        eventListener = event => {
          off.call(element, eventNames, selector, handler, useCapture);
          listener.call(element, event);
        };
      }

      element.addEventListener(eventName, eventListener, useCapture || false);

      getHandlers(element).push({
        eventName,
        handler,
        eventListener,
        selector,
        namespace
      });
    });

  }, this);

  return this;
};

off (eventNames, selector, handler, useCapture)

Shorthand for removeEventListener.

Arguments
eventNames String

List of space-separated event types to be removed from the element(s)

selector String

Selector to filter descendants that undelegate the event to this element.

optional
handler Function

Event handler

useCapture Boolean (default: false)

Returns
Object  

The wrapped collection

chainable

    $('.item').off('click', callback);
    $('#my-element').off('myEvent myOtherEvent');
    $('.item').off();
export const off = function(eventNames = '', selector, handler, useCapture) {

  if(typeof selector === 'function') {
    handler = selector;
    selector = null;
  }

  let parts,
    namespace,
    handlers;

  eventNames.split(' ').forEach(eventName => {

    parts = eventName.split('.');
    eventName = parts[0] || null;
    namespace = parts[1] || null;

    return each(this, element => {

      handlers = getHandlers(element);

      each(handlers.filter(item => {
        return (
          (!eventName || item.eventName === eventName) &&
          (!namespace || item.namespace === namespace) &&
          (!handler || item.handler === handler) &&
          (!selector || item.selector === selector)
        );
      }), item => {
        element.removeEventListener(item.eventName, item.eventListener, useCapture || false);
        handlers.splice(handlers.indexOf(item), 1);
      });

      if(!eventName && !namespace && !selector && !handler) {
        clearHandlers(element);
      } else if(handlers.length === 0) {
        clearHandlers(element);
      }

    });

  }, this);

  return this;
};

one (eventNames, selector, handler, useCapture)

Add event listener and execute the handler at most once per element.

Arguments
eventNames
selector
handler
useCapture

Returns
Object  

The wrapped collection

chainable

    $('.item').one('click', callback);
export const one = function(eventNames, selector, handler, useCapture) {
  return on.call(this, eventNames, selector, handler, useCapture, 1);
};

Event/ready

ready (handler)

Execute callback when DOMContentLoaded fires for document, or immediately if called afterwards.

Arguments
handler

Callback to execute when initial DOM content is loaded.

Returns
Object  

The wrapped collection

chainable

    $(document).ready(callback);
export const ready = function(handler) {
  if(/complete|loaded|interactive/.test(document.readyState) && document.body) {
    handler();
  } else {
    document.addEventListener('DOMContentLoaded', handler, false);
  }
  return this;
};

Event/trigger

trigger (type, data, params)

Trigger event at element(s)

Arguments
type String

Type of the event

data Object

Data to be sent with the event (params.detail will be set to this).

params Object

Event parameters (optional)

optional
params.bubbles Boolean

Does the event bubble up through the DOM or not.

(default: true)
params.cancelable Boolean

Is the event cancelable or not.

(default: true)
params.detail Mixed

Additional information about the event.

(default: undefined)

Returns
Object  

The wrapped collection

chainable

    $('.item').trigger('anyEventType');
export const trigger = function(type, data, {bubbles = true, cancelable = true, preventDefault = false} = {}) {

  const EventConstructor = getEventConstructor(type);
  const event = new EventConstructor(type, {
    bubbles,
    cancelable,
    preventDefault,
    detail: data
  });

  event._preventDefault = preventDefault;

  return each(this, element => {
    if(!bubbles || isEventBubblingInDetachedTree || isAttachedToDocument(element)) {
      dispatchEvent(element, event);
    } else {
      triggerForPath(element, type, {
        bubbles,
        cancelable,
        preventDefault,
        detail: data
      });
    }
  });
};

const getEventConstructor = type => supportsOtherEventConstructors ? (reMouseEvent.test(type) ? MouseEvent : (reKeyEvent.test(type) ? KeyboardEvent : CustomEvent)) : CustomEvent;

triggerHandler (type, data)

Trigger event at first element in the collection. Similar to trigger(), except:

  • Event does not bubble
  • Default event behavior is prevented
  • Only triggers handler for first matching element
Arguments
type String

Type of the event

data Object

Data to be sent with the event

    $('form').triggerHandler('submit');
export const triggerHandler = function(type, data) {
  if(this[0]) {
    trigger.call(this[0], type, data, {
      bubbles: false,
      preventDefault: true
    });
  }
};

NoConflict

noConflict ()

In case another library sets the global $ variable before DOMtastic does,
this method can be used to return the global $ to that other library.

Returns
Object  

Reference to DOMtastic.

    var domtastic = $.noConflict();
export const noConflict = function() {
  win.$ = previousLib;
  return this;
};

Selector

domtastic (selector, context)

Versatile wrapper for querySelectorAll.

Arguments
selector String or Node or NodeList or Array

Query selector, Node, NodeList, array of elements, or HTML fragment string.

context String or Node or NodeList

The context for the selector to query elements.

(default: document)

Returns
Object  

The wrapped collection

chainable

    var $items = $(.items');
    var $element = $(domElement);
    var $list = $(nodeList, document.body);
    var $element = $('<p>evergreen</p>');
const domtastic = function domtastic(selector, context = document) {

  let collection;

  if(!selector) {

    collection = document.querySelectorAll(null);

  } else if(selector instanceof DOMtastic) {

    return selector;

  } else if(typeof selector !== 'string') {

    collection = selector.nodeType || selector === window ? [selector] : selector;

  } else if(reFragment.test(selector)) {

    collection = createFragment(selector);

  } else {

    context = typeof context === 'string' ? document.querySelector(context) : context.length ? context[0] : context;

    collection = querySelector(selector, context);

  }

  return wrap(collection);

};

export const $ = domtastic;

find (selector)

Find descendants matching the provided selector for each element in the collection.

Arguments
selector String or Node or NodeList or Array

Query selector, Node, NodeList, array of elements, or HTML fragment string.

Returns
Object  

The wrapped collection

    $('.selector').find('.deep').$('.deepest');
export const find = function(selector) {
  const nodes = [];
  each(this, node => each(querySelector(selector, node), child => {
    if(nodes.indexOf(child) === -1) {
      nodes.push(child);
    }
  }));
  return $(nodes);
};

matches (element, selector)

Returns true if the element would be selected by the specified selector string; otherwise, returns false.

Arguments
element Node

Element to test

selector String

Selector to match against element

Returns
Boolean  

    $.matches(element, '.match');
export const matches = (() => {
  const context = typeof Element !== 'undefined' ? Element.prototype : win;
  const _matches = context.matches || context.matchesSelector || context.mozMatchesSelector || context.msMatchesSelector || context.oMatchesSelector || context.webkitMatchesSelector;
  return (element, selector) => _matches.call(element, selector);
})();

Selector/closest

closest (selector, context)

Return the closest element matching the selector (starting by itself) for each element in the collection.

Arguments
selector String

Filter

context Object

If provided, matching elements must be a descendant of this element

optional

Returns
Object  

New wrapped collection (containing zero or one element)

chainable

    $('.selector').closest('.container');
export const closest = (() => {

  const closest = function(selector, context) {
    const nodes = [];
    each(this, node => {
      while(node && node !== context) {
        if(matches(node, selector)) {
          nodes.push(node);
          break;
        }
        node = node.parentElement;
      }
    });
    return $(uniq(nodes));
  };

  return typeof Element === 'undefined' || !Element.prototype.closest ? closest : function(selector, context) {
    if(!context) {
      const nodes = [];
      each(this, node => {
        const n = node.closest(selector);
        if(n) {
          nodes.push(n);
        }
      });
      return $(uniq(nodes));
    } else {
      return closest.call(this, selector, context);
    }
  };
})();

Selector/extra

children (selector)

Return children of each element in the collection, optionally filtered by a selector.

Arguments
selector String

Filter

optional

Returns
Object  

New wrapped collection

chainable

    $('.selector').children();
    $('.selector').children('.filter');
export const children = function(selector) {
  const nodes = [];
  each(this, element => {
    if(element.children) {
      each(element.children, child => {
        if(!selector || (selector && matches(child, selector))) {
          nodes.push(child);
        }
      });
    }
  });
  return $(nodes);
};

concat (selector)

Add the elements of a wrapped collection to another.

Arguments
selector String or Node or NodeList or Array

Query selector, Node, NodeList, array of elements, or HTML fragment string.

Returns
Object  

The extended wrapped collection

    $('.items').concat($('.more-items));
    $('.items').concat('.more-items);
    $('.items').concat('<div>more</div>');
export const concat = function(selector) {
  each($(selector), element => {
    if([].indexOf.call(this, element) === -1) {
      [].push.call(this, element);
    }
  });
  return this;
};

contents ()

Return child nodes of each element in the collection, including text and comment nodes.

Returns
Object  

New wrapped collection

    $('.selector').contents();
export const contents = function() {
  const nodes = [];
  each(this, element => nodes.push.apply(nodes, toArray(element.childNodes)));
  return $(nodes);
};

eq (index)

Return a collection containing only the one at the specified index.

Arguments
index Number

Returns
Object  

New wrapped collection

chainable

    $('.items').eq(1)
    // The second item; result is the same as doing $($('.items')[1]);
export const eq = function(index) {
  return slice.call(this, index, index + 1);
};

first ()

Return a collection containing only the first item.

Returns
Object  

New wrapped collection

chainable

    $('.items').first()
    // The first item; result is the same as doing $($('.items')[0]);
export const first = function() {
  return slice.call(this, 0, 1);
};

get (index)

Return the DOM element at the specified index.

Arguments
index Number

Returns
Node  

Element at the specified index

    $('.items').get(1)
    // The second element; result is the same as doing $('.items')[1];
export const get = function(index) {
  return this[index];
};

parent (selector)

Return the parent elements of each element in the collection, optionally filtered by a selector.

Arguments
selector String

Filter

optional

Returns
Object  

New wrapped collection

chainable

    $('.selector').parent();
    $('.selector').parent('.filter');
export const parent = function(selector) {
  const nodes = [];
  each(this, element => {
    if(!selector || (selector && matches(element.parentNode, selector))) {
      nodes.push(element.parentNode);
    }
  });
  return $(nodes);
};

siblings (selector)

Return the sibling elements of each element in the collection, optionally filtered by a selector.

Arguments
selector String

Filter

optional

Returns
Object  

New wrapped collection

chainable

    $('.selector').siblings();
    $('.selector').siblings('.filter');
export const siblings = function(selector) {
  const nodes = [];
  each(this, element => each(element.parentNode.children, sibling => {
    if(sibling !== element && (!selector || (selector && matches(sibling, selector)))) {
      nodes.push(sibling);
    }
  }));
  return $(nodes);
};

slice (start, end)

Create a new, sliced collection.

Arguments
start Number
end Number

Returns
Object  

New wrapped collection

    $('.items').slice(1, 3)
    // New wrapped collection containing the second, third, and fourth element.
export const slice = function(start, end) { // eslint-disable-line no-unused-vars
  return $([].slice.apply(this, arguments));
};

Type

isFunction (obj)

Determine if the argument passed is a Javascript function object.

Arguments
obj Object

Object to test whether or not it is a function.

optional

Returns
boolean  

    $.isFunction(function(){}); // true
    $.isFunction({}); // false
export const isFunction = obj => typeof obj === 'function';

isArray (obj)

Determine whether the argument is an array.

Arguments
obj Object

Object to test whether or not it is an array.

optional

Returns
boolean  

    $.isArray([]); // true
    $.isArray({}); // false
export const isArray = Array.isArray;

Util

extend (target, source)

Assign enumerable properties from source object(s) to target object

Arguments
target Object

Object to extend

source Object

Object to extend from

optional

Returns
Object  

Extended object

    $.extend({a: 1}, {b: 2}); // {a: 1, b: 2}
    $.extend({a: 1}, {b: 2}, {a: 3}); // {a: 3, b: 2}
export const extend = (target, ...sources) => {
  sources.forEach(src => {
    for(let prop in src) {
      target[prop] = src[prop];
    }
  });
  return target;
};