You Don't Need jQuery

Examples of how to do query, style, dom, ajax, event etc like jQuery with p...

README

You (Might) Don't Need jQuery


Frontend environments evolve rapidly nowadays and modern browsers have already implemented a great deal of DOM/BOM APIs which are good enough for production use. We don't have to learn jQuery from scratch for DOM manipulation or event handling. In the meantime, thanks to the spread of frontend libraries such as React, Angular and Vue, manipulating the DOM directly becomes anti-pattern, so that jQuery usage has never been less important. This project summarizes most of the alternatives in native Javascript implementation to jQuery methods, with IE 10+ support.

ℹ️ Notice:
1. jQuery is still a great library and has many valid use cases. Don’t migrate away if you don’t want to!
2. The alternatives are not completely equivalent in all scenarios, and it is recommended that you test it before using it.

Table of Contents


1. Ajax

Translations



Query Selector


In place of common selectors like class, id or attribute we can use document.querySelector or document.querySelectorAll for substitution. The differences lie in:
document.querySelector returns the first matched element
document.querySelectorAll returns all matched elements as NodeList. It can be converted to Array using Array.prototype.slice.call(document.querySelectorAll(selector)); or any of the methods outlined in makeArray
If there are no elements matched, jQuery and document.querySelectorAll will return [], whereas document.querySelector will return null.

Notice: document.querySelector and document.querySelectorAll are quite SLOW, thus try to use document.getElementById, document.getElementsByClassName or document.getElementsByTagName if you want to get a performance bonus.


- [1.0](#1.0) Query by selector

  1. ``` js
  2.   // jQuery
  3.   $('selector');

  4.   // Native
  5.   document.querySelectorAll('selector');
  6. ```

- [1.1](#1.1) Query by class

  1. ``` js
  2.   // jQuery
  3.   $('.class');

  4.   // Native
  5.   document.querySelectorAll('.class');

  6.   // or
  7.   document.getElementsByClassName('class');
  8. ```

- [1.2](#1.2) Query by id

  1. ``` js
  2.   // jQuery
  3.   $('#id');

  4.   // Native
  5.   document.querySelector('#id');

  6.   // or
  7.   document.getElementById('id');

  8.   // or
  9.   window['id']
  10. ```

- [1.3](#1.3) Query by attribute

  1. ``` js
  2.   // jQuery
  3.   $('a[target=_blank]');

  4.   // Native
  5.   document.querySelectorAll('a[target=_blank]');
  6. ```

- [1.4](#1.4) Query in descendants

  1. ``` js
  2.   // jQuery
  3.   $el.find('li');

  4.   // Native
  5.   el.querySelectorAll('li');
  6. ```

- [1.5](#1.5) Sibling/Previous/Next Elements

  + All siblings

  1. ``` js
  2.     // jQuery
  3.     $el.siblings();

  4.     // Native - latest, Edge13+
  5.     [...el.parentNode.children].filter((child) =>
  6.       child !== el
  7.     );
  8.     // Native (alternative) - latest, Edge13+
  9.     Array.from(el.parentNode.children).filter((child) =>
  10.       child !== el
  11.     );
  12.     // Native - IE10+
  13.     Array.prototype.filter.call(el.parentNode.children, (child) =>
  14.       child !== el
  15.     );
  16. ```

  + Previous sibling

  1. ``` js
  2.     // jQuery
  3.     $el.prev();

  4.     // Native
  5.     el.previousElementSibling;
  6. ```
  + Next sibling

  1. ``` js
  2.     // jQuery
  3.     $el.next();

  4.     // Native
  5.     el.nextElementSibling;
  6. ```

  + All previous siblings

  1. ``` js
  2.     // jQuery (optional filter selector)
  3.     $el.prevAll($filter);

  4.     // Native (optional filter function)
  5.     function getPreviousSiblings(elem, filter) {
  6.       var sibs = [];
  7.       while (elem = elem.previousSibling) {
  8.           if (elem.nodeType === 3) continue; // ignore text nodes
  9.           if (!filter || filter(elem)) sibs.push(elem);
  10.       }
  11.       return sibs;
  12.     }

  13.   + All next siblings

  14. ``` js
    // jQuery (optional selector filter)
    $el.nextAll($filter);

    // Native (optional filter function)
    function getNextSiblings(elem, filter) {
            var sibs = [];
            var nextElem = elem.parentNode.firstChild;
            do {
                if (nextElem.nodeType === 3) continue; // ignore text nodes
                if (nextElem === elem) continue; // ignore elem of target
                if (nextElem === elem.nextElementSibling) {
                    if (!filter || filter(elem)) {
                        sibs.push(nextElem);
                        elem = nextElem;
                    }
                }
            } while(nextElem = nextElem.nextSibling)
            return sibs;
        }

An example of filter function:

  1. ``` js
  2. function exampleFilter(elem) {
  3.   switch (elem.nodeName.toUpperCase()) {
  4.     case 'DIV':
  5.       return true;
  6.     case 'SPAN':
  7.       return true;
  8.     default:
  9.       return false;
  10.   }
  11. }
  12. ```

- [1.6](#1.6) Closest

  Return the first matched element by provided selector, traversing from current element up through its ancestors in the DOM tree.

  1. ``` js
  2.   // jQuery
  3.   $el.closest(selector);

  4.   // Native - Only latest, NO IE
  5.   el.closest(selector);

  6.   // Native - IE10+
  7.   function closest(el, selector) {
  8.     const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;

  9.     while (el) {
  10.       if (matchesSelector.call(el, selector)) {
  11.         return el;
  12.       } else {
  13.         el = el.parentElement;
  14.       }
  15.     }
  16.     return null;
  17.   }
  18. ```

- [1.7](#1.7) Parents Until

  Get the ancestors of each element in the current set of matched elements, up to but not including the element matched by the selector, DOM node, or jQuery object.

  1. ``` js
  2.   // jQuery
  3.   $el.parentsUntil(selector, filter);

  4.   // Native
  5.   function parentsUntil(el, selector, filter) {
  6.     const result = [];
  7.     const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;

  8.     // match start from parent
  9.     el = el.parentElement;
  10.     while (el && !matchesSelector.call(el, selector)) {
  11.       if (!filter) {
  12.         result.push(el);
  13.       } else {
  14.         if (matchesSelector.call(el, filter)) {
  15.           result.push(el);
  16.         }
  17.       }
  18.       el = el.parentElement;
  19.     }
  20.     return result;
  21.   }
  22. ```

- [1.8](#1.8) Form

  + Input/Textarea

  1. ``` js
  2.     // jQuery
  3.     $('#my-input').val();

  4.     // Native
  5.     document.querySelector('#my-input').value;
  6. ```

  + Get index of e.currentTarget between .radio

  1. ``` js
  2.     // jQuery
  3.     $('.radio').index(e.currentTarget);

  4.     // Native
  5.     Array.from(document.querySelectorAll('.radio')).indexOf(e.currentTarget);
  6.     or
  7.     Array.prototype.indexOf.call(document.querySelectorAll('.radio'), e.currentTarget);
  8. ```

- [1.9](#1.9) Iframe Contents

  $('iframe').contents() returns contentDocument for this specific iframe

  + Iframe contents

  1. ``` js
  2.     // jQuery
  3.     $iframe.contents();

  4.     // Native
  5.     iframe.contentDocument;
  6. ```

  + Iframe Query

  1. ``` js
  2.     // jQuery
  3.     $iframe.contents().find('.css');

  4.     // Native
  5.     iframe.contentDocument.querySelectorAll('.css');
  6. ```

- [1.10](#1.10) Get body

  1. ``` js
  2.   // jQuery
  3.   $('body');

  4.   // Native
  5.   document.body;
  6. ```

- [1.11](#1.11) Attribute getter and setter

  + Get an attribute

  1. ``` js
  2.     // jQuery
  3.     $el.attr('foo');

  4.     // Native
  5.     el.getAttribute('foo');
  6. ```
  + Set an attribute

  1. ``` js
  2.     // jQuery
  3.     $el.attr('foo', 'bar');

  4.     // Native
  5.     el.setAttribute('foo', 'bar');
  6. ```

  + Get a data- attribute

  1. ``` js
  2.     // jQuery
  3.     $el.data('foo');

  4.     // Native (use `getAttribute`)
  5.     el.getAttribute('data-foo');

  6.     // Native (use `dataset` if only need to support IE 11+)
  7.     el.dataset['foo'];
  8. ```

- [1.12](#1.12) Selector containing string (case-sensitive)

  1. ``` js
  2.     // jQuery
  3.     $("selector:contains('text')");

  4.     // Native
  5.     function contains(selector, text) {
  6.       var elements = document.querySelectorAll(selector);
  7.       return Array.from(elements).filter(function(element) {
  8.         return RegExp(text).test(element.textContent);
  9.       });
  10.     }
  11. ```


CSS & Style


- [2.1](#2.1) CSS

  + Get style

  1. ``` js
  2.     // jQuery
  3.     $el.css('color');

  4.     // Native
  5.     // NOTE: Known bug, will return 'auto' if style value is 'auto'
  6.     const win = el.ownerDocument.defaultView;

  7.     // null means not to return pseudo styles
  8.     win.getComputedStyle(el, null).color;
  9. ```

  + Set style

  1. ``` js
  2.     // jQuery
  3.     $el.css({ color: '#f01' });

  4.     // Native
  5.     el.style.color = '#f01';
  6. ```

  + Get/Set Styles

    Note that if you want to set multiple styles once, you could refer to setStyles method in oui-dom-utils package.


  + Add class

  1. ``` js
  2.     // jQuery
  3.     $el.addClass(className);

  4.     // Native
  5.     el.classList.add(className);
  6. ```

  + Remove class

  1. ``` js
  2.     // jQuery
  3.     $el.removeClass(className);

  4.     // Native
  5.     el.classList.remove(className);
  6. ```

  + has class

  1. ``` js
  2.     // jQuery
  3.     $el.hasClass(className);

  4.     // Native
  5.     el.classList.contains(className);
  6. ```

  + Toggle class

  1. ``` js
  2.     // jQuery
  3.     $el.toggleClass(className);

  4.     // Native
  5.     el.classList.toggle(className);
  6. ```

- [2.2](#2.2) Width & Height

  Width and Height are theoretically identical, take Height as example:

  + Window height

  1. ``` js
  2.     // window height
  3.     $(window).height();

  4.     // without scrollbar, behaves like jQuery
  5.     window.document.documentElement.clientHeight;

  6.     // with scrollbar
  7.     window.innerHeight;
  8. ```

  + Document height

  1. ``` js
  2.     // jQuery
  3.     $(document).height();

  4.     // Native
  5.     const body = document.body;
  6.     const html = document.documentElement;
  7.     const height = Math.max(
  8.       body.offsetHeight,
  9.       body.scrollHeight,
  10.       html.clientHeight,
  11.       html.offsetHeight,
  12.       html.scrollHeight
  13.     );
  14. ```

  + Element height

  1. ``` js
  2.     // jQuery
  3.     $el.height();

  4.     // Native
  5.     function getHeight(el) {
  6.       const styles = window.getComputedStyle(el);
  7.       const height = el.offsetHeight;
  8.       const borderTopWidth = parseFloat(styles.borderTopWidth);
  9.       const borderBottomWidth = parseFloat(styles.borderBottomWidth);
  10.       const paddingTop = parseFloat(styles.paddingTop);
  11.       const paddingBottom = parseFloat(styles.paddingBottom);
  12.       return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;
  13.     }

  14.     // accurate to integer(when `border-box`, it's `height - border`; when `content-box`, it's `height + padding`)
  15.     el.clientHeight;

  16.     // accurate to decimal(when `border-box`, it's `height`; when `content-box`, it's `height + padding + border`)
  17.     el.getBoundingClientRect().height;
  18. ```

- [2.3](#2.3) Position & Offset

  + Position

    Get the current coordinates of the element relative to the offset parent.

  1. ``` js
  2.     // jQuery
  3.     $el.position();

  4.     // Native
  5.     { left: el.offsetLeft, top: el.offsetTop }
  6. ```

  + Offset

    Get the current coordinates of the element relative to the document.

  1. ``` js
  2.     // jQuery
  3.     $el.offset();

  4.     // Native
  5.     function getOffset (el) {
  6.       const box = el.getBoundingClientRect();

  7.       return {
  8.         top: box.top + window.pageYOffset - document.documentElement.clientTop,
  9.         left: box.left + window.pageXOffset - document.documentElement.clientLeft
  10.       };
  11.     }
  12. ```

- [2.4](#2.4) Scroll Top

  Get the current vertical position of the scroll bar for the element.

  1. ``` js
  2.   // jQuery
  3.   $(window).scrollTop();

  4.   // Native
  5.   (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
  6. ```


DOM Manipulation


- [3.1](#3.1) Remove

  Remove the element from the DOM.

  1. ``` js
  2.   // jQuery
  3.   $el.remove();

  4.   // Native
  5.   el.parentNode.removeChild(el);
  6. ```

- [3.2](#3.2) Text

  + Get text

    Get the combined text contents of the element including their descendants,

  1. ``` js
  2.     // jQuery
  3.     $el.text();

  4.     // Native
  5.     el.textContent;
  6. ```

  + Set text

    Set the content of the element to the specified text.

  1. ``` js
  2.     // jQuery
  3.     $el.text(string);

  4.     // Native
  5.     el.textContent = string;
  6. ```

- [3.3](#3.3) HTML

  + Get HTML

  1. ``` js
  2.     // jQuery
  3.     $el.html();

  4.     // Native
  5.     el.innerHTML;
  6. ```

  + Set HTML

  1. ``` js
  2.     // jQuery
  3.     $el.html(htmlString);

  4.     // Native
  5.     el.innerHTML = htmlString;
  6. ```

- [3.4](#3.4) Append

  Append child element after the last child of parent element

  1. ``` js
  2.   // jQuery: unified syntax for DOMString and Node objects
  3.   $parent.append(newEl | '<div id="container">Hello World</div>');

  4.   // Native: different syntax
  5.   parent.insertAdjacentHTML('beforeend', '<div id="container">Hello World</div>');
  6.   parent.appendChild(newEl);

  7.   // Native (ES6-way): unified syntax
  8.   parent.append(newEl | '<div id="container">Hello World</div>');
  9. ```

- [3.5](#3.5) Prepend

  1. ``` js
  2.   // jQuery: unified syntax for DOMString and Node objects
  3.   $parent.prepend(newEl | '<div id="container">Hello World</div>');

  4.   // Native: different syntax
  5.   parent.insertAdjacentHTML('afterbegin', '<div id="container">Hello World</div>');
  6.   parent.insertBefore(newEl, parent.firstChild);

  7.   // Native (ES6-way): unified syntax
  8.   parent.prepend(newEl | '<div id="container">Hello World</div>');
  9. ```

- [3.6](#3.6) insertBefore

  Insert a new node before the selected elements

  1. ``` js
  2.   // jQuery
  3.   $newEl.insertBefore(selector);

  4.   // Native (HTML string)
  5.   el.insertAdjacentHTML('beforebegin ', '<div id="container">Hello World</div>');

  6.   // Native (Element)
  7.   const el = document.querySelector(selector);
  8.   if (el.parentNode) {
  9.     el.parentNode.insertBefore(newEl, el);
  10.   }
  11. ```

- [3.7](#3.7) insertAfter

  Insert a new node after the selected elements

  1. ``` js
  2.   // jQuery
  3.   $newEl.insertAfter(selector);

  4.   // Native (HTML string)
  5.   el.insertAdjacentHTML('afterend', '<div id="container">Hello World</div>');

  6.   // Native (Element)
  7.   const el = document.querySelector(selector);
  8.   if (el.parentNode) {
  9.     el.parentNode.insertBefore(newEl, el.nextSibling);
  10.   }
  11. ```

- [3.8](#3.8) is

  Return true if it matches the query selector

  1. ``` js
  2.   // jQuery - Notice `is` also works with a function, an existing jQuery object or a DOM element, which are not of concern here
  3.   $el.is(selector);

  4.   // Native
  5.   el.matches(selector);
  6. ```
- [3.9](#3.9) clone

  Create a deep copy of an element: it copies the matched element as well as all of its descendant elements and text nodes.

  1. ``` js
  2.   // jQuery. Sets parameter as `true` to indicate that event handlers should be copied along with the element.
  3.   $el.clone();

  4.   // Native
  5.   el.cloneNode();

  6. ```

- [3.10](#3.10) empty

  Remove all child nodes

  1. ``` js
  2.   // jQuery
  3.   $el.empty();

  4.   // Native
  5.   el.innerHTML = null;
  6. ```

- [3.11](#3.11) wrap

  Wrap an HTML structure around each element

  1. ``` js
  2.   // jQuery
  3.   $('.inner').wrap('<div class="wrapper"></div>');

  4.   // Native
  5.   Array.from(document.querySelectorAll('.inner')).forEach((el) => {
  6.     const wrapper = document.createElement('div');
  7.     wrapper.className = 'wrapper';
  8.     el.parentNode.insertBefore(wrapper, el);
  9.     wrapper.appendChild(el);
  10.   });
  11. ```

- [3.12](#3.12) unwrap

  Remove the parents of the set of matched elements from the DOM

  1. ``` js
  2.   // jQuery
  3.   $('.inner').unwrap();

  4.   // Native
  5.   Array.from(document.querySelectorAll('.inner')).forEach((el) => {
  6.     let elParentNode = el.parentNode;

  7.     if(elParentNode !== document.body) {
  8.         elParentNode.parentNode.insertBefore(el, elParentNode);
  9.         elParentNode.parentNode.removeChild(elParentNode);
  10.     }
  11.   });
  12. ```

- [3.13](#3.13) replaceWith

  Replace each element in the set of matched elements with the provided new content

  1. ``` js
  2.   // jQuery
  3.   $('.inner').replaceWith('<div class="outer"></div>');

  4.   // Native (alternative) - latest, Edge17+
  5.   Array.from(document.querySelectorAll('.inner')).forEach((el) => {
  6.     const outer = document.createElement('div');
  7.     outer.className = 'outer';
  8.     el.replaceWith(outer);
  9.   });

  10.   // Native
  11.   Array.from(document.querySelectorAll('.inner')).forEach((el) => {
  12.     const outer = document.createElement('div');
  13.     outer.className = 'outer';
  14.     el.parentNode.replaceChild(outer, el);
  15.   });
  16. ```

- [3.14](#3.14) simple parse

  Parse a string into HTML/SVG/XML

  1. ``` js
  2.   // jQuery
  3.   $(`<ol>
  4.     <li>a</li>
  5.     <li>b</li>
  6.   </ol>
  7.   <ol>
  8.     <li>c</li>
  9.     <li>d</li>
  10.   </ol>`);

  11.   // Native
  12.   range = document.createRange();
  13.   parse = range.createContextualFragment.bind(range);

  14.   parse(`<ol>
  15.     <li>a</li>
  16.     <li>b</li>
  17.   </ol>
  18.   <ol>
  19.     <li>c</li>
  20.     <li>d</li>
  21.   </ol>`);
  22. ```



Ajax


Fetch API is the new standard to replace XMLHttpRequest to do ajax. It works on Chrome and Firefox, you can use polyfills to make it work on legacy browsers.

Try github/fetch on IE9+ or fetch-ie8 on IE8+, fetch-jsonp to make JSONP requests.

- [4.1](#4.1) Load data from the server and place the returned HTML into the matched element.

  1. ``` js
  2.   // jQuery
  3.   $(selector).load(url, completeCallback)

  4.   // Native
  5.   fetch(url).then(data => data.text()).then(data => {
  6.     document.querySelector(selector).innerHTML = data
  7.   }).then(completeCallback)
  8. ```


Events


For a complete replacement with namespace and delegation, refer to https://github.com/oneuijs/oui-dom-events

- [5.0](#5.0) Document ready by `DOMContentLoaded`

  1. ``` js
  2.     // jQuery
  3.     $(document).ready(eventHandler);

  4.     // Native
  5.     // Check if the DOMContentLoaded has already been completed
  6.     if (document.readyState !== 'loading') {
  7.       eventHandler();
  8.     } else {
  9.       document.addEventListener('DOMContentLoaded', eventHandler);
  10.     }

  11.     // Native
  12.     // Example 2 - Ternary Operator - Async
  13.     // Check if the DOMContentLoaded has already been completed
  14.     (async function() {
  15.       (document.readyState !== 'loading') ?
  16.         eventHandler() : document.addEventListener('DOMContentLoaded',
  17.           function() {
  18.             eventHandler(); // EventHandler
  19.           });
  20.     })();

  21.     // Native
  22.     // Example 3 - Ternary Operator - Non Async
  23.     // Check if the DOMContentLoaded has already been completed
  24.     (function() {
  25.       (document.readyState !== 'loading') ?
  26.         eventHandler() : document.addEventListener('DOMContentLoaded',
  27.           function() {
  28.             eventHandler(); // EventHandler
  29.           });
  30.     })();
  31. ```

- [5.1](#5.1) Bind an event with on

  1. ``` js
  2.   // jQuery
  3.   $el.on(eventName, eventHandler);

  4.   // Native
  5.   el.addEventListener(eventName, eventHandler);
  6. ```

- [5.2](#5.2) Unbind an event with off

  1. ``` js
  2.   // jQuery
  3.   $el.off(eventName, eventHandler);

  4.   // Native
  5.   el.removeEventListener(eventName, eventHandler);
  6. ```

- [5.3](#5.3) Trigger

  1. ``` js
  2.   // jQuery
  3.   $(el).trigger('custom-event', {key1: 'data'});

  4.   // Native
  5.   if (window.CustomEvent) {
  6.     const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});
  7.   } else {
  8.     const event = document.createEvent('CustomEvent');
  9.     event.initCustomEvent('custom-event', true, true, {key1: 'data'});
  10.   }

  11.   el.dispatchEvent(event);
  12. ```


Utilities


Most of jQuery utilities are also found in the native API. Other advanced functions could be chosen from better utilities libraries, focusing on consistency and performance. Lodash is a recommended replacement.

- [6.1](#6.1) Basic utilities

  + isArray

  Determine whether the argument is an array.

  1. ``` js
  2.   // jQuery
  3.   $.isArray(array);

  4.   // Native
  5.   Array.isArray(array);
  6. ```

  + isWindow

  Determine whether the argument is a window.

  1. ``` js
  2.   // jQuery
  3.   $.isWindow(obj);

  4.   // Native
  5.   function isWindow(obj) {
  6.     return obj !== null && obj !== undefined && obj === obj.window;
  7.   }
  8. ```

  + inArray

  Search for a specified value within an array and return its index (or -1 if not found).

  1. ``` js
  2.   // jQuery
  3.   $.inArray(item, array);

  4.   // Native
  5.   array.indexOf(item) > -1;

  6.   // ES6-way
  7.   array.includes(item);
  8. ```

  + isNumeric

  Determine if the argument passed is numerical.
  Use typeof to decide the type or the type example for better accuracy.

  1. ``` js
  2.   // jQuery
  3.   $.isNumeric(item);

  4.   // Native
  5.   function isNumeric(n) {
  6.     return !isNaN(parseFloat(n)) && isFinite(n);
  7.   }
  8. ```

  + isFunction

  Determine if the argument passed is a JavaScript function object.

  1. ``` js
  2.   // jQuery
  3.   $.isFunction(item);

  4.   // Native
  5.   function isFunction(item) {
  6.     if (typeof item === 'function') {
  7.       return true;
  8.     }
  9.     var type = Object.prototype.toString.call(item);
  10.     return type === '[object Function]' || type === '[object GeneratorFunction]';
  11.   }
  12. ```

  + isEmptyObject

  Check to see if an object is empty (contains no enumerable properties).

  1. ``` js
  2.   // jQuery
  3.   $.isEmptyObject(obj);

  4.   // Native
  5.   function isEmptyObject(obj) {
  6.     return Object.keys(obj).length === 0;
  7.   }
  8. ```

  + isPlainObject

  Check to see if an object is a plain object (created using “{}” or “new Object”).

  1. ``` js
  2.   // jQuery
  3.   $.isPlainObject(obj);

  4.   // Native
  5.   function isPlainObject(obj) {
  6.     if (typeof (obj) !== 'object' || obj.nodeType || obj !== null && obj !== undefined && obj === obj.window) {
  7.       return false;
  8.     }

  9.     if (obj.constructor &&
  10.         !Object.prototype.hasOwnProperty.call(obj.constructor.prototype, 'isPrototypeOf')) {
  11.       return false;
  12.     }

  13.     return true;
  14.   }
  15. ```

  + extend

  Merge the contents of two or more objects together into a new object, without modifying either argument.
  object.assign is part of ES6 API, and you could also use a polyfill.

  1. ``` js
  2.   // jQuery
  3.   $.extend({}, object1, object2);

  4.   // Native
  5.   Object.assign({}, object1, object2);
  6. ```

  + trim

  Remove the white-space from the beginning and end of a string.

  1. ``` js
  2.   // jQuery
  3.   $.trim(string);

  4.   // Native
  5.   string.trim();
  6. ```

  + map

  Translate all items in an array or object to new array of items.

  1. ``` js
  2.   // jQuery
  3.   $.map(array, (value, index) => {
  4.   });

  5.   // Native
  6.   array.map((value, index) => {
  7.   });
  8. ```

  + each

  A generic iterator function, which can be used to seamlessly iterate over both objects and arrays.

  1. ``` js
  2.   // jQuery
  3.   $.each(array, (index, value) => {
  4.   });

  5.   // Native
  6.   array.forEach((value, index) => {
  7.   });
  8. ```

  + grep

  Finds the elements of an array which satisfy a filter function.

  1. ``` js
  2.   // jQuery
  3.   $.grep(array, (value, index) => {
  4.   });

  5.   // Native
  6.   array.filter((value, index) => {
  7.   });
  8. ```

  + type

  Determine the internal JavaScript [Class] of an object.

  1. ``` js
  2.   // jQuery
  3.   $.type(obj);

  4.   // Native
  5.   function type(item) {
  6.     const reTypeOf = /(?:^\[object\s(.*?)\]$)/;
  7.     return Object.prototype.toString.call(item)
  8.       .replace(reTypeOf, '$1')
  9.       .toLowerCase();
  10.   }
  11. ```

  + merge

  Merge the contents of two arrays together into the first array.

  1. ``` js
  2.   // jQuery, doesn't remove duplicate items
  3.   $.merge(array1, array2);

  4.   // Native, doesn't remove duplicate items
  5.   function merge(...args) {
  6.     return [].concat(...args)
  7.   }

  8.   // ES6-way, doesn't remove duplicate items
  9.   array1 = [...array1, ...array2]

  10.   // Set version, does remove duplicate items
  11.   function merge(...args) {
  12.     return Array.from(new Set([].concat(...args)))
  13.   }
  14. ```

  + now

  Return a number representing the current time.

  1. ``` js
  2.   // jQuery
  3.   $.now();

  4.   // Native
  5.   Date.now();
  6. ```

  + proxy

  Takes a function and returns a new one that will always have a particular context.

  1. ``` js
  2.   // jQuery
  3.   $.proxy(fn, context);

  4.   // Native
  5.   fn.bind(context);
  6. ```

+ makeArray

  Convert an array-like object into a true JavaScript array.

  1. ``` js
  2.   // jQuery
  3.   $.makeArray(arrayLike);

  4.   // Native
  5.   Array.prototype.slice.call(arrayLike);

  6.   // ES6-way: Array.from() method
  7.   Array.from(arrayLike);

  8.   // ES6-way: spread operator
  9.   [...arrayLike];
  10. ```

- [6.2](#6.2) Contains

  Check to see if a DOM element is a descendant of another DOM element.

  1. ``` js
  2.   // jQuery
  3.   $.contains(el, child);

  4.   // Native
  5.   el !== child && el.contains(child);
  6. ```

- [6.3](#6.3) Globaleval

  Execute some JavaScript code globally.

  1. ``` js
  2.   // jQuery
  3.   $.globaleval(code);

  4.   // Native
  5.   function Globaleval(code) {
  6.     const script = document.createElement('script');
  7.     script.text = code;

  8.     document.head.appendChild(script).parentNode.removeChild(script);
  9.   }

  10.   // Use eval, but context of eval is current, context of $.Globaleval is global.
  11.   eval(code);
  12. ```

- [6.4](#6.4) parse

  + parseHTML

  Parses a string into an array of DOM nodes.

  1. ``` js
  2.   // jQuery
  3.   $.parseHTML(htmlString);

  4.   // Native
  5.   function parseHTML(string) {
  6.     const context = document.implementation.createHTMLDocument();

  7.     // Set the base href for the created document so any parsed elements with URLs
  8.     // are based on the document's URL
  9.     const base = context.createElement('base');
  10.     base.href = document.location.href;
  11.     context.head.appendChild(base);

  12.     context.body.innerHTML = string;
  13.     return context.body.children;
  14.   }
  15. ```
- [6.5](#6.4) exists

+ exists

  Check if an element exists in the DOM

  1. ``` js
  2.   // jQuery
  3.   if ($('selector').length) {
  4.      // exists
  5.   }

  6.   // Native
  7.   var element =  document.getElementById('elementId');
  8.   if (typeof(element) != 'undefined' && element != null)
  9.   {
  10.      // exists
  11.   }
  12. ```


Promises


A promise represents the eventual result of an asynchronous operation. jQuery has its own way to handle promises. Native JavaScript implements a thin and minimal API to handle promises according to the Promises/A+ specification.

- [7.1](#7.1) done, fail, always

  done is called when promise is resolved, fail is called when promise is rejected, always is called when promise is either resolved or rejected.

  1. ``` js
  2.   // jQuery
  3.   $promise.done(doneCallback).fail(failCallback).always(alwaysCallback)

  4.   // Native
  5.   promise.then(doneCallback, failCallback).then(alwaysCallback, alwaysCallback)
  6. ```

- [7.2](#7.2) when

  when is used to handle multiple promises. It will resolve when all promises are resolved, and reject if either one is rejected.

  1. ``` js
  2.   // jQuery
  3.   $.when($promise1, $promise2).done((promise1Result, promise2Result) => {
  4.   });

  5.   // Native
  6.   Promise.all([$promise1, $promise2]).then([promise1Result, promise2Result] => {});
  7. ```

- [7.3](#7.3) Deferred

  Deferred is a way to create promises.

  1. ``` js
  2.   // jQuery
  3.   function asyncFunc() {
  4.     const defer = new $.Deferred();
  5.     setTimeout(() => {
  6.       if(true) {
  7.         defer.resolve('some_value_computed_asynchronously');
  8.       } else {
  9.         defer.reject('failed');
  10.       }
  11.     }, 1000);

  12.     return defer.promise();
  13.   }

  14.   // Native
  15.   function asyncFunc() {
  16.     return new Promise((resolve, reject) => {
  17.       setTimeout(() => {
  18.         if (true) {
  19.           resolve('some_value_computed_asynchronously');
  20.         } else {
  21.           reject('failed');
  22.         }
  23.       }, 1000);
  24.     });
  25.   }

  26.   // Deferred way
  27.   function defer() {
  28.     const deferred = {};
  29.     const promise = new Promise((resolve, reject) => {
  30.       deferred.resolve = resolve;
  31.       deferred.reject = reject;
  32.     });

  33.     deferred.promise = () => {
  34.       return promise;
  35.     };

  36.     return deferred;
  37.   }

  38.   function asyncFunc() {
  39.     const defer = defer();
  40.     setTimeout(() => {
  41.       if(true) {
  42.         defer.resolve('some_value_computed_asynchronously');
  43.       } else {
  44.         defer.reject('failed');
  45.       }
  46.     }, 1000);

  47.     return defer.promise();
  48.   }
  49. ```


Animation


- [8.1](#8.1) Show & Hide

  1. ``` js
  2.   // jQuery
  3.   $el.show();
  4.   $el.hide();

  5.   // Native
  6.   // More detail about show method, please refer to https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L363
  7.   el.style.display = ''|'inline'|'inline-block'|'inline-table'|'block';
  8.   el.style.display = 'none';
  9. ```

- [8.2](#8.2) Toggle

  Display or hide the element.

  1. ``` js
  2.   // jQuery
  3.   $el.toggle();

  4.   // Native
  5.   if (el.ownerDocument.defaultView.getComputedStyle(el, null).display === 'none') {
  6.     el.style.display = ''|'inline'|'inline-block'|'inline-table'|'block';
  7.   } else {
  8.     el.style.display = 'none';
  9.   }
  10. ```

- [8.3](#8.3) FadeIn & FadeOut

  1. ``` js
  2.   // jQuery
  3.   $el.fadeIn(3000);
  4.   $el.fadeOut(3000);

  5.   // Native fadeOut
  6.   function fadeOut(el, ms) {
  7.     if (ms) {
  8.       el.style.transition = `opacity ${ms} ms`;
  9.       el.addEventListener(
  10.         'transitionend',
  11.         function(event) {
  12.           el.style.display = 'none';
  13.         },
  14.         false
  15.       );
  16.     }
  17.     el.style.opacity = '0';
  18.   }

  19.   // Native fadeIn
  20.   function fadeIn(elem, ms) {
  21.     elem.style.opacity = 0;

  22.     if (ms) {
  23.       let opacity = 0;
  24.       const timer = setInterval(function() {
  25.         opacity += 50 / ms;
  26.         if (opacity >= 1) {
  27.           clearInterval(timer);
  28.           opacity = 1;
  29.         }
  30.         elem.style.opacity = opacity;
  31.       }, 50);
  32.     } else {
  33.       elem.style.opacity = 1;
  34.     }
  35.   }
  36. ```

- [8.4](#8.4) FadeTo

  Adjust the opacity of the element.

  1. ``` js
  2.   // jQuery
  3.   $el.fadeTo('slow',0.15);
  4.   // Native
  5.   el.style.transition = 'opacity 3s'; // assume 'slow' equals 3 seconds
  6.   el.style.opacity = '0.15';
  7. ```

- [8.5](#8.5) FadeToggle

  Display or hide the element by animating their opacity.

  1. ``` js
  2.   // jQuery
  3.   $el.fadeToggle();

  4.   // Native
  5.   el.style.transition = 'opacity 3s';
  6.   const { opacity } = el.ownerDocument.defaultView.getComputedStyle(el, null);
  7.   if (opacity === '1') {
  8.     el.style.opacity = '0';
  9.   } else {
  10.     el.style.opacity = '1';
  11.   }
  12. ```

- [8.6](#8.6) SlideUp & SlideDown

  1. ``` js
  2.   // jQuery
  3.   $el.slideUp();
  4.   $el.slideDown();

  5.   // Native
  6.   const originHeight = '100px';
  7.   el.style.transition = 'height 3s';
  8.   // slideUp
  9.   el.style.height = '0px';
  10.   // slideDown
  11.   el.style.height = originHeight;
  12. ```

- [8.7](#8.7) SlideToggle

  Display or hide the element with a sliding motion.

  1. ``` js
  2.   // jQuery
  3.   $el.slideToggle();

  4.   // Native
  5.   const originHeight = '100px';
  6.   el.style.transition = 'height 3s';
  7.   const { height } = el.ownerDocument.defaultView.getComputedStyle(el, null);
  8.   if (parseInt(height, 10) === 0) {
  9.     el.style.height = originHeight;
  10.   } else {
  11.    el.style.height = '0px';
  12.   }
  13. ```

- [8.8](#8.8) Animate

  Perform a custom animation of a set of CSS properties.

  1. ``` js
  2.   // jQuery
  3.   $el.animate({ params }, speed);

  4.   // Native
  5.   el.style.transition = 'all ' + speed;
  6.   Object.keys(params).forEach((key) => {
  7.     el.style[key] = params[key];
  8.   });
  9. ```

Alternatives


You Might Not Need jQuery - Examples of how to do common event, element, ajax etc with plain javascript.
npm-dom and webmodules - Organizations you can find individual DOM modules on NPM

Browser Support


![Chrome][chrome-image] | ![Firefox][firefox-image] | ![IE][ie-image] | ![Opera][opera-image] | ![Safari][safari-image]
Latest ✔ | Latest ✔ | 10+ ✔ | Latest ✔ | 6.1+ ✔ |

License


MIT

[chrome-image]: https://raw.github.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png
[firefox-image]: https://raw.github.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png
[ie-image]: https://raw.github.com/alrra/browser-logos/master/src/archive/internet-explorer_9-11/internet-explorer_9-11_48x48.png
[opera-image]: https://raw.github.com/alrra/browser-logos/master/src/opera/opera_48x48.png
[safari-image]: https://raw.github.com/alrra/browser-logos/master/src/safari/safari_48x48.png