Code Monkey home page Code Monkey logo

you-dont-need-jquery's Introduction

You Don't Need jQuery Build Status

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

Table of Contents

  1. Query Selector
  2. CSS & Style
  3. DOM Manipulation
  4. Ajax
  5. Events
  6. Utilities
  7. Alternatives
  8. Translations
  9. Browser Support

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 [].slice.call(document.querySelectorAll(selector) || []);
  • If no elements matched, jQuery would return [] whereas the DOM API will return null. Pay attention to Null Pointer Exception. You can also use || to set default value if not found, like document.querySelectorAll(selector) || []

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

  • 1.0 Query by selector

    // jQuery
    $('selector');
    
    // Native
    document.querySelectorAll('selector');
  • 1.1 Query by class

    // jQuery
    $('.class');
    
    // Native
    document.querySelectorAll('.class');
    
    // or
    document.getElementsByClassName('class');
  • 1.2 Query by id

    // jQuery
    $('#id');
    
    // Native
    document.querySelector('#id');
    
    // or
    document.getElementById('id');
  • 1.3 Query by attribute

    // jQuery
    $('a[target=_blank]');
    
    // Native
    document.querySelectorAll('a[target=_blank]');
  • 1.4 Find sth.

    • Find nodes

      // jQuery
      $el.find('li');
      
      // Native
      el.querySelectorAll('li');
    • Find body

      // jQuery
      $('body');
      
      // Native
      document.body;
    • Find Attribute

      // jQuery
      $el.attr('foo');
      
      // Native
      el.getAttribute('foo');
    • Find data attribute

      // jQuery
      $el.data('foo');
      
      // Native
      // using getAttribute
      el.getAttribute('data-foo');
      // you can also use `dataset` if only need to support IE 11+
      el.dataset['foo'];
  • 1.5 Sibling/Previous/Next Elements

    • Sibling elements

      // jQuery
      $el.siblings();
      
      // Native
      [].filter.call(el.parentNode.children, function(child) {
        return child !== el;
      });
    • Previous elements

      // jQuery
      $el.prev();
      
      // Native
      el.previousElementSibling;
    • Next elements

      // jQuery
      $el.next();
      
      // Native
      el.nextElementSibling;
  • 1.6 Closest

    Return the first matched element by provided selector, traversing from current element to document.

    // jQuery
    $el.closest(selector);
    
    // Native - Only latest, NO IE
    el.closest(selector);
    
    // Native - IE10+ 
    function closest(el, selector) {
      const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
    
      while (el) {
        if (matchesSelector.call(el, selector)) {
          return el;
        } else {
          el = el.parentElement;
        }
      }
      return null;
    }
  • 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.

    // jQuery
    $el.parentsUntil(selector, filter);
    
    // Native
    function parentsUntil(el, selector, filter) {
      const result = [];
      const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
    
      // match start from parent
      el = el.parentElement;
      while (el && !matchesSelector.call(el, selector)) {
        if (!filter) {
          result.push(el);
        } else {
          if (matchesSelector.call(el, filter)) {
            result.push(el);
          }
        }
        el = el.parentElement;
      }
      return result;
    }
  • 1.8 Form

    • Input/Textarea

      // jQuery
      $('#my-input').val();
      
      // Native
      document.querySelector('#my-input').value;
    • Get index of e.currentTarget between .radio

      // jQuery
      $(e.currentTarget).index('.radio');
      
      // Native
      [].indexOf.call(document.querySelectAll('.radio'), e.currentTarget);
  • 1.9 Iframe Contents

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

    • Iframe contents

      // jQuery
      $iframe.contents();
      
      // Native
      iframe.contentDocument;
    • Iframe Query

      // jQuery
      $iframe.contents().find('.css');
      
      // Native
      iframe.contentDocument.querySelectorAll('.css');

⬆ back to top

CSS & Style

  • 2.1 CSS

    • Get style

      // jQuery
      $el.css("color");
      
      // Native
      // NOTE: Known bug, will return 'auto' if style value is 'auto'
      const win = el.ownerDocument.defaultView;
      // null means not return pseudo styles
      win.getComputedStyle(el, null).color;
    • Set style

      // jQuery
      $el.css({ color: "#ff0011" });
      
      // Native
      el.style.color = '#ff0011';
    • 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

      // jQuery
      $el.addClass(className);
      
      // Native
      el.classList.add(className);
    • Remove class

      // jQuery
      $el.removeClass(className);
      
      // Native
      el.classList.remove(className);
    • has class

      // jQuery
      $el.hasClass(className);
      
      // Native
      el.classList.contains(className);
    • Toggle class

      // jQuery
      $el.toggleClass(className);
      
      // Native
      el.classList.toggle(className);
  • 2.2 Width & Height

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

    • Window height

      // window height
      $(window).height();
      // without scrollbar, behaves like jQuery
      window.document.documentElement.clientHeight;
      // with scrollbar
      window.innerHeight;
    • Document height

      // jQuery
      $(document).height();
      
      // Native
      document.documentElement.scrollHeight;
    • Element height

      // jQuery
      $el.height();
      
      // Native
      function getHeight(el) {
        const styles = this.getComputedStyles(el);
        const height = el.offsetHeight;
        const borderTopWidth = parseFloat(styles.borderTopWidth);
        const borderBottomWidth = parseFloat(styles.borderBottomWidth);
        const paddingTop = parseFloat(styles.paddingTop);
        const paddingBottom = parseFloat(styles.paddingBottom);
        return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;
      }
      // accurate to integer(when `border-box`, it's `height`; when `content-box`, it's `height + padding + border`)
      el.clientHeight;
      // accurate to decimal(when `border-box`, it's `height`; when `content-box`, it's `height + padding + border`)
      el.getBoundingClientRect().height;
  • 2.3 Position & Offset

    • Position

      // jQuery
      $el.position();
      
      // Native
      { left: el.offsetLeft, top: el.offsetTop }
    • Offset

      // jQuery
      $el.offset();
      
      // Native
      function getOffset (el) {
        const box = el.getBoundingClientRect();
      
        return {
          top: box.top + window.pageYOffset - document.documentElement.clientTop,
          left: box.left + window.pageXOffset - document.documentElement.clientLeft
        }
      }
  • 2.4 Scroll Top

    // jQuery
    $(window).scrollTop();
    
    // Native
    (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;

⬆ back to top

DOM Manipulation

  • 3.1 Remove

    // jQuery
    $el.remove();
    
    // Native
    el.parentNode.removeChild(el);
  • 3.2 Text

    • Get text

      // jQuery
      $el.text();
      
      // Native
      el.textContent;
    • Set text

      // jQuery
      $el.text(string);
      
      // Native
      el.textContent = string;
  • 3.3 HTML

    • Get HTML

      // jQuery
      $el.html();
      
      // Native
      el.innerHTML;
    • Set HTML

      // jQuery
      $el.html(htmlString);
      
      // Native
      el.innerHTML = htmlString;
  • 3.4 Append

    append child element after the last child of parent element

    // jQuery
    $el.append("<div id='container'>hello</div>");
    
    // Native
    el.insertAdjacentHTML("beforeend","<div id='container'>hello</div>");
  • 3.5 Prepend

    // jQuery
    $el.prepend("<div id='container'>hello</div>");
    
    // Native
    el.insertAdjacentHTML("afterbegin","<div id='container'>hello</div>");
  • 3.6 insertBefore

    Insert a new node before the selected elements

    // jQuery
    $newEl.insertBefore(queryString);
    
    // Native
    const target = document.querySelector(queryString);
    target.parentNode.insertBefore(newEl, target);
  • 3.7 insertAfter

    Insert a new node after the selected elements

    // jQuery
    $newEl.insertAfter(queryString);
    
    // Native
    const target = document.querySelector(queryString);
    target.parentNode.insertBefore(newEl, target.nextSibling);
  • 3.8 is

    Returns true if it matches the query selector

    // jQuery - Notice `is` also work with `function` or `elements` which is not concerned here
    $el.is(selector);
    
    // Native
    el.matches(selector);
  • 3.9 clone

    Create a deep copy of that element

    // jQuery 
    $el.clone(); 
    
    // Native
    el.cloneNode();
    
    // For Deep clone , set param as `true`  

⬆ back to top

Ajax

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

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

⬆ back to top

Events

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

  • 5.1 Bind an event with on

    // jQuery
    $el.on(eventName, eventHandler);
    
    // Native
    el.addEventListener(eventName, eventHandler);
  • 5.2 Unbind an event with off

    // jQuery
    $el.off(eventName, eventHandler);
    
    // Native
    el.removeEventListener(eventName, eventHandler);
  • 5.3 Trigger

    // jQuery
    $(el).trigger('custom-event', {key1: 'data'});
    
    // Native
    if (window.CustomEvent) {
      const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});
    } else {
      const event = document.createEvent('CustomEvent');
      event.initCustomEvent('custom-event', true, true, {key1: 'data'});
    }
    
    el.dispatchEvent(event);

⬆ back to top

Utilities

  • 6.1 isArray

    // jQuery
    $.isArray(range);
    
    // Native
    Array.isArray(range);
  • 6.2 Trim

    // jQuery
    $.trim(string);
    
    // Native
    string.trim();
  • 6.3 Object Assign

    Extend, use object.assign polyfill https://github.com/ljharb/object.assign

    // jQuery
    $.extend({}, defaultOpts, opts);
    
    // Native
    Object.assign({}, defaultOpts, opts);
  • 6.4 Contains

    // jQuery
    $.contains(el, child);
    
    // Native
    el !== child && el.contains(child);

⬆ back to top

Alternatives

Translations

Browser Support

Chrome Firefox IE Opera Safari
Latest ✔ Latest ✔ 10+ ✔ Latest ✔ 6.1+ ✔

License

MIT

you-dont-need-jquery's People

Contributors

camsong avatar arcthur avatar infacq avatar gaulatti avatar andersonaguiar avatar jasonslyvia avatar woneob avatar item4 avatar naprirfan avatar rodrigoalviani avatar nguyenvanduocit avatar chentsulin avatar heian0224 avatar dduong42 avatar idiotwu avatar enricolucia avatar jovey-zheng avatar staabm avatar michael-alt avatar riseledger avatar welksonramos avatar angt avatar antonk52 avatar jsgv avatar risyasin avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.