【轉】You Don't Need jQuery

You Don't Need jQuery

轉自You Don't Need jQuery

前端發(fā)展很快,現(xiàn)代瀏覽器原生 API 已經足夠好用。我們并不需要為了操作 DOM、Event 等再學習一下 jQuery 的 API。同時由于 React、Angular、Vue 等框架的流行,直接操作 DOM 不再是好的模式,jQuery 使用場景大大減少。本項目總結了大部分 jQuery API 替代的方法,暫時只支持 IE10+ 以上瀏覽器。

Query Selector

常用的 class、id、屬性 選擇器都可以使用 document.querySelectordocument.querySelectorAll 替代。區(qū)別是

  • document.querySelector 返回第一個匹配的 Element
  • document.querySelectorAll 返回所有匹配的 Element 組成的 NodeList。它可以通過 [].slice.call() 把它轉成 Array
  • 如果匹配不到任何 Element,jQuery 返回空數(shù)組 [],但 document.querySelector 返回 null,注意空指針異常。當找不到時,也可以使用 || 設置默認的值,如 document.querySelectorAll(selector) || []

注意:document.querySelectordocument.querySelectorAll 性能很。如果想提高性能,盡量使用 document.getElementById、document.getElementsByClassNamedocument.getElementsByTagName

  • 1.0 <a name='1.0'></a> Query by selector

    // jQuery
    $('selector');
    
    // Native
    document.querySelectorAll('selector');
    
  • 1.1 <a name='1.1'></a> Query by class

    // jQuery
    $('.css');
    
    // Native
    document.querySelectorAll('.css');
    
    // or
    document.getElementsByClassName('css');
    
  • 1.2 <a name='1.2'></a> Query by id

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

    // jQuery
    $('a[target=_blank]');
    
    // Native
    document.querySelectorAll('a[target=_blank]');
    
  • 1.4 <a name='1.4'></a> 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
      e.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 <a name='1.5'></a> 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

      // next
      $el.next();
      el.nextElementSibling;
      
  • 1.6 <a name='1.6'></a> Closest

    Closest 獲得匹配選擇器的第一個祖先元素,從當前元素開始沿 DOM 樹向上。

    // jQuery
    $el.closest(queryString);
    
    // Native
    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 <a name='1.7'></a> Parents Until

    獲取當前每一個匹配元素集的祖先,不包括匹配元素的本身。

    // 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 <a name='1.8'></a> 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.querySelectorAll('.radio'), e.currentTarget);
      
  • 1.9 <a name='1.9'></a> Iframe Contents

    jQuery 對象的 iframe contents() 返回的是 iframe 內的 document

    • Iframe contents

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

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

CSS & Style

  • 2.1 <a name='2.1'></a> CSS

    • Get style

      // jQuery
      $el.css("color");
      
      // Native
      // 注意:此處為了解決當 style 值為 auto 時,返回 auto 的問題
      const win = el.ownerDocument.defaultView;
      // null 的意思是不返回偽類元素
      win.getComputedStyle(el, null).color;
      
    • Set style

      // jQuery
      $el.css({ color: "#ff0011" });
      
      // Native
      el.style.color = '#ff0011';
      
    • Get/Set Styles

      注意,如果想一次設置多個 style,可以參考 oui-dom-utils 中 setStyles 方法

    • 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 <a name='2.2'></a> Width & Height

    Width 與 Height 獲取方法相同,下面以 Height 為例:

    • Window height

      // jQuery
      $(window).height();
      
      // Native
      // 不含 scrollbar,與 jQuery 行為一致
      window.document.documentElement.clientHeight;
      // 含 scrollbar
      window.innerHeight;
      
    • Document height

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

      // jQuery
      $el.height();
      
      // Native
      // 與 jQuery 一致(一直為 content 區(qū)域的高度)
      function getHeight(el) {
        const styles = this.getComputedStyle(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;
      }
      // 精確到整數(shù)(border-box 時為 height 值,content-box 時為 height + padding + border 值)
      el.clientHeight;
      // 精確到小數(shù)(border-box 時為 height 值,content-box 時為 height + padding + border 值)
      el.getBoundingClientRect().height;
      
    • Iframe height

      $iframe .contents() 方法返回 iframe 的 contentDocument

      // jQuery
      $('iframe').contents().height();
      
      // Native
      iframe.contentDocument.documentElement.scrollHeight;
      
  • 2.3 <a name='2.3'></a> 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 <a name='2.4'></a> Scroll Top

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

DOM Manipulation

  • 3.1 <a name='3.1'></a> Remove

    // jQuery
    $el.remove();
    
    // Native
    el.parentNode.removeChild(el);
    
  • 3.2 <a name='3.2'></a> Text

    • Get text

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

      // jQuery
      $el.text(string);
      
      // Native
      el.textContent = string;
      
  • 3.3 <a name='3.3'></a> HTML

    • Get HTML

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

      // jQuery
      $el.html(htmlString);
      
      // Native
      el.innerHTML = htmlString;
      
  • 3.4 <a name='3.4'></a> Append

    Append 插入到子節(jié)點的末尾

    // jQuery
    $el.append("<div id='container'>hello</div>");
    
    // Native
    let newEl = document.createElement('div');
    newEl.setAttribute('id', 'container');
    newEl.innerHTML = 'hello';
    el.appendChild(newEl);
    
  • 3.5 <a name='3.5'></a> Prepend

    // jQuery
    $el.prepend("<div id='container'>hello</div>");
    
    // Native
    let newEl = document.createElement('div');
    newEl.setAttribute('id', 'container');
    newEl.innerHTML = 'hello';
    el.insertBefore(newEl, el.firstChild);
    
  • 3.6 <a name='3.6'></a> insertBefore

    在選中元素前插入新節(jié)點

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

    在選中元素后插入新節(jié)點

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

Ajax

fetchfetch-jsonp 替代

Events

完整地替代命名空間和事件代理,鏈接到 https://github.com/oneuijs/oui-dom-events

  • 5.1 <a name='5.1'></a> Bind an event with on

    // jQuery
    $el.on(eventName, eventHandler);
    
    // Native
    el.addEventListener(eventName, eventHandler);
    
  • 5.2 <a name='5.2'></a> Unbind an event with off

    // jQuery
    $el.off(eventName, eventHandler);
    
    // Native
    el.removeEventListener(eventName, eventHandler);
    
  • 5.3 <a name='5.3'></a> 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);
    

Utilities

  • 6.1 <a name='6.1'></a> isArray

    // jQuery
    $.isArray(range);
    
    // Native
    Array.isArray(range);
    
  • 6.2 <a name='6.2'></a> Trim

    // jQuery
    $.trim(string);
    
    // Native
    string.trim();
    
  • 6.3 <a name='6.3'></a> Object Assign

    繼承,使用 object.assign polyfill https://github.com/ljharb/object.assign

    // jQuery
    $.extend({}, defaultOpts, opts);
    
    // Native
    Object.assign({}, defaultOpts, opts);
    
  • 6.4 <a name='6.4'></a> Contains

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

Alternatives

Browser Support

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

License

MIT

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 前端發(fā)展很快,現(xiàn)代瀏覽器原生 API 已經足夠好用。我們并不需要為了操作 DOM、Event 等再學習一下 jQu...
    codinger閱讀 671評論 0 3
  • 前端發(fā)展很快,現(xiàn)代瀏覽器原生API已經足夠好用。我們并不需要為了操作DOM、Event等再學習Jquery的API...
    我是白夜閱讀 709評論 0 50
  • 目錄 元素查找 class操作 節(jié)點操作 屬性操作 內容操作 css操作 位置大小 事件 DOM加載完畢 綁定上下...
    北瀟閱讀 318評論 0 0
  • 最是無情不過時間 歲月的痕跡不著顏色,卻又透射著強大的力量 不知道何時,現(xiàn)在的我只會發(fā)一些簡短的朋友圈動態(tài)式的文字...
    簡煦閱讀 162評論 0 0
  • 多讀書。讀書破萬卷,下筆如有神。書讀的多,見識便廣,每讀一本書,就像經歷一次不同的人生,我們從中獲得不同的經歷,得...
    想變成一只貓閱讀 276評論 0 1