Skip to content

Latest commit

 

History

History
1277 lines (919 loc) · 30.1 KB

README-ja.md

File metadata and controls

1277 lines (919 loc) · 30.1 KB

jQueryは必要ない(You Don't Need jQuery)

フロントエンドの開発環境はめまぐるしく進化していて、最近のブラウザでは十分な質、量のDOM/BOM APIが実装されています。もうDOM操作やイベント処理のためにjQueryを覚える必要はありません。また、ReactやAngularそしてVueなどのフロントエンドライブラリの流行により、DOMを直接操作することはアンチパターンとなりました。jQueryはそれほど重要ではなくなったのです。このプロジェクトは、jQueryでの書き方の代わりとなるネイティブでの書き方(IE10以上)をまとめます。

目次

  1. Translations
  2. セレクタ
  3. CSSとスタイル
  4. DOM操作
  5. Ajax
  6. イベント
  7. ユーティリティ関数
  8. Promise
  9. アニメーション
  10. 選択肢
  11. 対応ブラウザ

Translations

セレクタ

classセレクタ、idセレクタ、属性セレクタのような主要セレクタはdocument.querySelectorもしくはdocument.querySelectorAllで代替できます。

jQueryのセレクタと比べて以下の違いがあります。

  • document.querySelectorはセレクタにマッチする最初のエレメントを返す
  • document.querySelectorAllはセレクタにマッチする全てのエレメントのNodeListを返す。Array.prototype.slice.call(document.querySelectorAll(selector) || []);で配列に変換できる。
  • セレクタにマッチする要素がなかった場合、jQueryは[]を返すが、DOM APIはnullを返す。したがってNull Pointer Exceptionに注意する必要がある。もしくはdocument.querySelectorAll(selector) || []のように||を使ってデフォルト値を指定しておく。

注意:document.querySelectordocument.querySelectorAllはかなり遅いです。もし、パフォーマンスが必要ならdocument.getElementByIddocument.getElementsByClassNamedocument.getElementsByTagNameを使ってください。

  • 1.0 セレクタによる選択

    // jQuery
    $('selector');
    
    // Native
    document.querySelectorAll('selector');
  • 1.1 クラス名による選択

    // jQuery
    $('.class');
    
    // Native
    document.querySelectorAll('.class');
    
    // or
    document.getElementsByClassName('class');
  • 1.2 idによる選択

    // jQuery
    $('#id');
    
    // Native
    document.querySelector('#id');
    
    // or
    document.getElementById('id');
  • 1.3 属性による選択

    // jQuery
    $('a[target=_blank]');
    
    // Native
    document.querySelectorAll('a[target=_blank]');
  • 1.4 子孫要素の選択

    // jQuery
    $el.find('li');
    
    // Native
    el.querySelectorAll('li');
  • 1.5 兄弟要素の選択

    • 兄弟要素

      // jQuery
      $el.siblings();
      
      // Native
      Array.prototype.filter.call(el.parentNode.children, function(child) {
        return child !== el;
      });
    • 直前の兄弟要素

      // jQuery
      $el.prev();
      
      // Native
      el.previousElementSibling;
    • 直後の兄弟要素

      // jQuery
      $el.next();
      
      // Native
      el.nextElementSibling;
  • 1.6 祖先要素の選択

    指定要素からdocument方向に遡って走査し、セレクタにマッチする最初の祖先要素を返します。

    // jQuery
    $el.closest(selector);
    
    // Native - 最近のブラウザのみ。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

    指定要素からセレクタにマッチする祖先要素までdocument方向に遡って走査し、フィルタにマッチする祖先要素を全て取得します。ただし、セレクタで指定された要素は含みません。

    // jQuery
    $el.parentsUntil(selector, filter);
    
    // Native
    function parentsUntil(el, selector, filter) {
      const result = [];
      const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
    
      // 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 フォーム

    • input/textarea

      // jQuery
      $('#my-input').val();
      
      // Native
      document.querySelector('#my-input').value;
    • .radio内でのe.currentTargetのインデックスを返す

      // jQuery
      $(e.currentTarget).index('.radio');
      
      // Native
      Array.prototype.indexOf.call(document.querySelectorAll('.radio'), e.currentTarget);
  • 1.9 iframeのコンテンツ

    $('iframe').contents()はiframeのcontentDocumentを返します。

    • Iframe contents

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

      // jQuery
      $iframe.contents().find('.css');
      
      // Native
      iframe.contentDocument.querySelectorAll('.css');
  • 1.10 bodyを取得する

    // jQuery
    $('body');
    
    // Native
    document.body;
  • 1.11 属性の設定、取得

    • 属性値を取得する

      // jQuery
      $el.attr('foo');
      
      // Native
      el.getAttribute('foo');
    • 属性値を設定する

      // jQuery, DOMを変化させずメモリ上で動作することに注意
      $el.attr('foo', 'bar');
      
      // Native
      el.setAttribute('foo', 'bar');
    • data-属性を取得する

      // jQuery
      $el.data('foo');
      
      // Native (`getAttribute`を使う)
      el.getAttribute('data-foo');
      // Native (IE11以上のサポートなら`dataset`を使ってもよい)
      el.dataset['foo'];

⬆ back to top

CSSとスタイル

  • 2.1 CSS

    • スタイルを取得する

      // jQuery
      $el.css("color");
      
      // Native
      // NOTE: 既知のバグ デフォルト値が'auto'の場合、値が指定されていなくても'auto'が返る
      const win = el.ownerDocument.defaultView;
      // nullは疑似要素でないことを示している
      win.getComputedStyle(el, null).color;
    • スタイルを設定する

      // jQuery
      $el.css({ color: "#ff0011" });
      
      // Native
      el.style.color = '#ff0011';
    • スタイルを一括取得、一括設定する

      複数のスタイルを一括で設定したいなら、oui-dom-utilsのsetStyles関数を参考にすると良いでしょう。

    • クラスを追加する

      // jQuery
      $el.addClass(className);
      
      // Native
      el.classList.add(className);
    • クラスを削除する

      // jQuery
      $el.removeClass(className);
      
      // Native
      el.classList.remove(className);
    • クラスの有無をチェックする

      // jQuery
      $el.hasClass(className);
      
      // Native
      el.classList.contains(className);
    • クラスの有無を切り替える

      // jQuery
      $el.toggleClass(className);
      
      // Native
      el.classList.toggle(className);
  • 2.2 横幅と高さ

    横幅(width)と高さ(height)の書き方はほぼ同じなので、高さ(height)の例のみを示します。

    • ウィンドウの高さ

      // window height
      $(window).height();
      // jQueryのようにスクロールバーを除いた高さ
      window.document.documentElement.clientHeight;
      // スクロールバーを含めるなら
      window.innerHeight;
    • ドキュメントの高さ

      // jQuery
      $(document).height();
      
      // Native
      document.documentElement.scrollHeight;
    • エレメントの高さ

      // jQuery
      $el.height();
      
      // Native
      function getHeight(el) {
        const styles = window.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;
      }
      // integerで取得(`border-box`の時は`height - border`が、`content-box`の時は`height + padding`が返る)
      el.clientHeight;
      // decimalで取得(`border-box`の時は`height`が、`content-box`の時は`height + padding + border`が返る)
      el.getBoundingClientRect().height;
  • 2.3 PositionとOffset

    • Position

      offset parentを起点として、エレメントの座標を取得する。

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

      documentを起点として、エレメントの座標を取得する。

      // 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 スクロール位置

    縦スクロールバーの位置を取得する。

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

⬆ back to top

DOM操作

  • 3.1 Remove

    DOMからエレメントを削除する。

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

    • テキストを取得する

      子孫エレメントも含めた全テキスト内容を取得する。

      // jQuery
      $el.text();
      
      // Native
      el.textContent;
    • テキストを設定する

      エレメントのコンテントを指定されたテキストに設定する。

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

    • HTMLを取得する

      // jQuery
      $el.html();
      
      // Native
      el.innerHTML;
    • HTMLを設定する

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

    最後の子要素としてエレメントを追加する。

    // 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

    指定要素の後ろに新しいノードを追加する。

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

    指定要素の前に新しいノードを追加する。

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

    セレクタにマッチするならtrueを返す。

    // is関数は複数エレメントや関数にも対応するが、matches関数は単一エレメントのみに使える
    $el.is(selector);
    
    // Native
    el.matches(selector);
  • 3.9 clone

    エレメントのディープコピーを生成する。

    // jQuery
    $el.clone();
    
    // Native
    el.cloneNode();
    
    //  パラメータには`true`が渡され、深い複製を生成します。
    // 浅い複製を生成するには、`false`を渡します。
  • 3.10 empty

    全ての子ノードを削除する。

    // jQuery
    $el.empty();
    
    // Native
    el.innerHTML = '';
  • 3.11 wrap

    エレメントを指定のHTMLで囲む。

    // jQuery
    $('.inner').wrap('<div class="wrapper"></div>');
    
    // Native
    Array.prototype.slice.call(document.querySelectorAll('.inner')).forEach(function(el){
      var wrapper = document.createElement('div');
      wrapper.className = 'wrapper';
      el.parentNode.insertBefore(wrapper, el);
      el.parentNode.removeChild(el);
      wrapper.appendChild(el);
    });
  • 3.12 unwrap

    セレクタにマッチしたエレメントの親要素をDOMから削除する。マッチしたエレメント自体は残す。

    // jQuery
    $('.inner').unwrap();
    
    // Native
    Array.prototype.slice.call(document.querySelectorAll('.inner')).forEach(function(el){
      Array.prototype.slice.call(el.childNodes).forEach(function(child){
        el.parentNode.insertBefore(child, el);
      });
      el.parentNode.removeChild(el);
    });
  • 3.13 replaceWith

    セレクタにマッチしたエレメントの内容を与えられた内容に置き換える。

    // jQuery
    $('.inner').replaceWith('<div class="outer"></div>');
    
    // Native
    Array.prototype.slice.call(document.querySelectorAll('.inner')).forEach(function(el){
      var outer = document.createElement('div');
      outer.className = 'outer';
      el.parentNode.insertBefore(outer, el);
      el.parentNode.removeChild(el);
    });

⬆ back to top

Ajax

Fetch APIはXMLHttpRequestを置き換える新たな規格です。ChromeとFirefoxで動きます。レガシーなブラウザでもpolyfillを使えます。

IE9以上ならgithub/fetch、IE8以上ならfetch-ie8、jsonpを利用したいならfetch-jsonpを試してみてください。

  • 4.1 マッチしたエレメントをサーバから取得したHTMLに置き換える。

    // jQuery
    $(selector).load(url, completeCallback)
    
    // Native
    fetch(url).then(data => data.text()).then(data => {
      document.querySelector(selector).innerHTML = data
    }).then(completeCallback)

⬆ back to top

イベント

名前空間(namespace)と委譲(delegation)を利用した完全な代替手段が必要なら、 https://github.com/oneuijs/oui-dom-events を参照してください。

  • 5.0 ドキュメントが読み込まれたときの動作(DOMContentLoaded)

    // jQuery
    $(document).ready(eventHandler);
    
    // Native
    // DOMContentLoadedがすでに完了していないか確認する
    if (document.readyState !== 'loading') {
      eventHandler();
    } else {
      document.addEventListener('DOMContentLoaded', eventHandler);
    }
  • 5.1 イベントをバインドする(on)

    // jQuery
    $el.on(eventName, eventHandler);
    
    // Native
    el.addEventListener(eventName, eventHandler);
  • 5.2 イベントをアンバインドする(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

ユーティリティ関数

殆どのユーティリティ関数はネイティブのAPIで置き換えることができます。表記の一貫性やパフォーマンスを重視した他のライブラリを使う選択肢もあります。lodashがおすすめです。

  • 6.1 基本的なユーティリティ関数

    • isArray

    配列かどうか判定する。

    // jQuery
    $.isArray(array);
    
    // Native
    Array.isArray(array);
    • isWindow

    windowかどうか判定する。

    // jQuery
    $.isWindow(obj);
    
    // Native
    function isWindow(obj) {
      return obj != null && obj === obj.window;
    }
    • inArray

    配列の中で、指定された値が最初に現れたインデックスを返す。(見つからなければ-1を返す)。

    // jQuery
    $.inArray(item, array);
    
    // Native
    Array.indexOf(item);
    • isNumeric

    数値かどうか判定する。 typeofを使ってください。ライブラリを使う場合、typeofは正確でない場合があります。

    // jQuery
    $.isNumeric(item);
    
    // Native
    function isNumeric(item) {
      return typeof item === 'number';
    }
    • isFunction

    JavaScript関数オブジェクトかどうか判定する。

    // jQuery
    $.isFunction(item);
    
    // Native
    function isFunction(item) {
      return typeof item === 'function';
    }
    • isEmptyObject

    空のオブジェクトである(列挙できる要素がない)か判定する。

    // jQuery
    $.isEmptyObject(obj);
    
    // Native
    function isEmptyObject(obj) {
      for (let key in obj) {
        return false;
      }
      return true;
    }
    • isPlainObject

    {}もしくはnew Objectで生成されたオブジェクトであるか判定する。

    // jQuery
    $.isPlainObject(obj);
    
    // Native
    function isPlainObject(obj) {
      if (typeof (obj) !== 'object' || obj.nodeType || obj != null && obj === obj.window) {
        return false;
      }
    
      if (obj.constructor &&
          !{}.hasOwnProperty.call(obj.constructor.prototype, 'isPrototypeOf')) {
        return false;
      }
    
      return true;
    }
    • extend

    二つ以上のオブジェクトをマージする。 object.assignはECMAScript6のAPIですが、polyfillも利用できます。

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

    前後の空白を除去する。

    // jQuery
    $.trim(string);
    
    // Native
    string.trim();
    • map

    配列やオブジェクトを新しい配列に変換する。

    // jQuery
    $.map(array, function(value, index) {
    });
    
    // Native
    array.map(function(value, index) {
    });
    • each

    配列やオブジェクトに対して繰り返し処理を行う。

    // jQuery
    $.each(array, function(value, index) {
    });
    
    // Native
    array.forEach(function(value, index) {
    });
    • grep

    フィルター関数に合致したエレメントだけを返す。

    // jQuery
    $.grep(array, function(value, index) {
    });
    
    // Native
    array.filter(function(value, index) {
    });
    • type

    JavaScript「クラス」名を判定します。

    // jQuery
    $.type(obj);
    
    // Native
    Object.prototype.toString.call(obj).replace(/^\[object (.+)\]$/, '$1').toLowerCase();
    • merge

    二つの配列をマージする。

    // jQuery
    $.merge(array1, array2);
    
    // Native
    // 重複した要素は削除されない
    function merge() {
      return Array.prototype.concat.apply([], arguments)
    }
    • now

    現在の時刻を返す。

    // jQuery
    $.now();
    
    // Native
    Date.now();
    • proxy

    関数内で実行されるthisを任意のオブジェクトに変更する。

    // jQuery
    $.proxy(fn, context);
    
    // Native
    fn.bind(context);
    • makeArray

    配列形式のオブジェクトを配列に変換する。

    // jQuery
    $.makeArray(arrayLike);
    
    // Native
    Array.prototype.slice.call(arrayLike);
    
    // ES6なら
    Array.from(arrayLike);
  • 6.2 contains

    ある要素が他の要素の子孫であるか判定する。

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

    JavaScriptコードをグローバル空間で実行する。

    // jQuery
    $.globaleval(code);
    
    // Native
    function Globaleval(code) {
      let script = document.createElement('script');
      script.text = code;
    
      document.head.appendChild(script).parentNode.removeChild(script);
    }
    
    // evalはcurrentコンテキストで実行される。$.globalevalのコンテキストはグローバルである。
    eval(code);
  • 6.4 parse

    • parseHTML

    文字列をDOM nodeの配列として返します。

    // jQuery
    $.parseHTML(htmlString);
    
    // Native
    function parseHTML(string) {
      const tmp = document.implementation.createHTMLDocument();
      tmp.body.innerHTML = string;
      return tmp.body.children;
    }
    • parseJSON

    JSON文字列をJavaScriptに変換します。

    // jQuery
    $.parseJSON(str);
    
    // Native
    JSON.parse(str);

⬆ back to top

Promise

promiseは非同期処理の最終的な処理結果を表します。jQueryにはpromiseを扱うための独自の方法があります。ネイティブのJavaScriptではPromises/A+規格に則り、薄く、最小限のAPIを実装しています。

  • 7.1 done, fail, always

    doneはpromiseが成功(resolved)したとき、fallは失敗(rejected)したとき、alwaysはどちらの場合も呼び出されます。

    // jQuery
    $promise.done(doneCallback).fail(failCallback).always(alwaysCallback)
    
    // Native
    promise.then(doneCallback, failCallback).then(alwaysCallback, alwaysCallback)
  • 7.2 when

    whenは複数のpromiseを扱うときに使います。すべてのpromiseの結果が返ったときに成功となります(失敗が含まれてても成功となります)。

    // jQuery
    $.when($promise1, $promise2).done((promise1Result, promise2Result) => {})
    
    // Native
    Promise.all([$promise1, $promise2]).then([promise1Result, promise2Result] => {});
  • 7.3 Deferred

    Deferredはpromiseを作成する方法の一つです。

    // jQuery
    function asyncFunc() {
      var d = new $.Deferred();
      setTimeout(function() {
        if(true) {
          d.resolve('some_value_compute_asynchronously');
        } else {
          d.reject('failed');
        }
      }, 1000);
      return d.promise();
    }
    
    // Native
    function asyncFunc() {
      return new Promise((resolve, reject) => {
        setTimeout(function() {
          if (true) {
            resolve('some_value_compute_asynchronously');
          } else {
            reject('failed');
          }
        }, 1000);
      });
    }
    
    // Deferred way
    function defer() {
      let resolve, reject;
      let promise = new Promise(function() {
        resolve = arguments[0];
        reject = arguments[1];
      });
      return { resolve, reject, promise };
    }
    function asyncFunc() {
      var d = defer();
      setTimeout(function() {
        if(true) {
          d.resolve('some_value_compute_asynchronously');
        } else {
          d.reject('failed');
        }
      }, 1000);
      return d.promise;
    }

⬆ back to top

アニメーション

  • 8.1 show、hide

    // jQuery
    $el.show();
    $el.hide();
    
    // Native
    // show関数の詳細を見たければ次のURLを参照してください
    // https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L363
    el.style.display = ''|'inline'|'inline-block'|'inline-table'|'block';
    el.style.display = 'none';
  • 8.2 toggle

    エレメントが表示されていないなら表示し、表示されているなら非表示にします。

    // jQuery
    $el.toggle();
    
    // Native
    if (el.ownerDocument.defaultView.getComputedStyle(el, null).display === 'none') {
      el.style.display = ''|'inline'|'inline-block'|'inline-table'|'block';
    }
    else {
      el.style.display = 'none';
    }
  • 8.3 fadeIn、fadeOut

    // jQuery
    $el.fadeIn(3000);
    $el.fadeOut(3000);
    
    // Native
    el.style.transition = 'opacity 3s';
    // fadeIn
    el.style.opacity = '1';
    // fadeOut
    el.style.opacity = '0';
  • 8.4 fadeTo

    エレメントのopacityを調整してください。

    // jQuery
    $el.fadeTo('slow',0.15);
    // Native
    el.style.transition = 'opacity 3s'; // 'slow'は3秒だということにしている
    el.style.opacity = '0.15';
  • 8.5 fadeToggle

    フェードイン・フェードアウトを伴ってエレメントの表示・非表示を切り替えます。

    // jQuery
    $el.fadeToggle();
    
    // Native
    el.style.transition = 'opacity 3s';
    let { opacity } = el.ownerDocument.defaultView.getComputedStyle(el, null);
    if (opacity === '1') {
      el.style.opacity = '0';
    }
    else {
      el.style.opacity = '1';
    }
  • 8.6 スライドアップ、スライドダウン

    // jQuery
    $el.slideUp();
    $el.slideDown();
    
    // Native
    let originHeight = '100px';
    el.style.transition = 'height 3s';
    // slideUp
    el.style.height = '0px';
    // slideDown
    el.style.height = originHeight;
  • 8.7 slideToggle

    スライドを伴って、エレメントの表示・非表示を切り替えます。

    // jQuery
    $el.slideToggle();
    
    // Native
    let originHeight = '100px';
    el.style.transition = 'height 3s';
    let { height } = el.ownerDocument.defaultView.getComputedStyle(el, null);
    if (parseInt(height, 10) === 0) {
      el.style.height = originHeight;
    }
    else {
     el.style.height = '0px';
    }
  • 8.8 animate

    CSSプロパティで定義されたアニメーションを表示します。

    // jQuery
    $el.animate({params}, speed);
    
    // Native
    el.style.transition = 'all' + speed;
    Object.keys(params).forEach(function(key) {
      el.style[key] = params[key];
    })

選択肢

  • You Might Not Need jQuery - ネイティブのJavaScriptでイベント、エレメント、Ajaxを扱うサンプル集(英語)
  • npm-dom and webmodules - npmで利用できるDOMモジュールを集めたOrganizationです

対応ブラウザ

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

ライセンス

MIT