[
  {
    "path": ".babelrc",
    "content": "{\n  presets: [\"es2015\", \"stage-0\"]\n}\n"
  },
  {
    "path": ".eslintrc",
    "content": "{\n  \"extends\": \"eslint-config-airbnb\",\n  \"env\": {\n    \"browser\": true,\n    \"mocha\": true,\n    \"node\": true\n  },\n  \"rules\": {\n    \"valid-jsdoc\": 2,\n    \"no-param-reassign\": 0,\n    \"comma-dangle\": 0,\n    \"one-var\": 0,\n    \"no-else-return\": 1,\n    \"no-unused-expressions\": 0,\n    \"indent\": 1,\n    \"eol-last\": 0\n  }\n}\n"
  },
  {
    "path": ".gitignore",
    "content": ".DS_Store\n*.log\nnode_modules\ncoverage\nlogs\n.idea\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015 oneuijs\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
  },
  {
    "path": "README-es.md",
    "content": "## Tú no necesitas jQuery\n\nEl desarrollo Frontend evoluciona día a día, y los navegadores modernos ya han implementado nativamente APIs para trabajar con DOM/BOM, las cuales son muy buenas, por lo que definitivamente no es necesario aprender jQuery desde cero para manipular el DOM. En la actualidad, gracias al surgimiento de librerías frontend como React, Angular y Vue, manipular el DOM es contrario a los patrones establecidos, y jQuery se ha vuelto menos importante. Este proyecto resume la mayoría de métodos alternativos a jQuery, pero de forma nativa con soporte IE 10+.\n\n## Tabla de Contenidos\n\n1. [Traducción](#traducción)\n1. [Query Selector](#query-selector)\n1. [CSS & Estilo](#css--estilo)\n1. [Manipulación DOM](#manipulación-dom)\n1. [Ajax](#ajax)\n1. [Eventos](#eventos)\n1. [Utilidades](#utilidades)\n1. [Promesas](#promesas)\n1. [Animaciones](#animaciones)\n1. [Alternativas](#alternativas)\n1. [Navegadores soportados](#navegadores-soportados)\n\n## Traducción\n\n* [한국어](./README.ko-KR.md)\n* [正體中文](./README.zh-TW.md)\n* [简体中文](./README.zh-CN.md)\n* [Bahasa Melayu](./README-my.md)\n* [Bahasa Indonesia](./README-id.md)\n* [Português(PT-BR)](./README.pt-BR.md)\n* [Tiếng Việt Nam](./README-vi.md)\n* [Español](./README-es.md)\n* [Русский](./README-ru.md)\n* [Кыргызча](./README-kg.md)\n* [Türkçe](./README-tr.md)\n* [Italiano](./README-it.md)\n* [Français](./README-fr.md)\n* [日本語](./README-ja.md)\n* [Polski](./README-pl.md)\n\n## Query Selector\n\nEn lugar de los selectores comunes como clase, id o atributos podemos usar `document.querySelector` o `document.querySelectorAll` como alternativas. Las diferencias radican en:\n* `document.querySelector` devuelve el primer elemento que cumpla con la condición\n* `document.querySelectorAll` devuelve todos los elementos que cumplen con la condición en forma de NodeList. Puede ser convertido a Array usando `[].slice.call(document.querySelectorAll(selector) || []);`\n* Si ningún elemento cumple con la condición, jQuery retornaría `[]` mientras la API DOM retornaría `null`. Nótese el NullPointerException. Se puede usar `||` para establecer el valor por defecto al no encontrar elementos, como en `document.querySelectorAll(selector) || []`\n\n> Nota: document.querySelector y document.querySelectorAll son bastante LENTOS, procuree utilizar getElementById, document.getElementsByClassName o document.getElementsByTagName si desea obtener un mejor rendimiento.\n\n- [1.0](#1.0) <a name='1.0'></a> Buscar por selector\n\n  ```js\n  // jQuery\n  $('selector');\n\n  // Nativo\n  document.querySelectorAll('selector');\n  ```\n\n- [1.1](#1.1) <a name='1.1'></a> Buscar por Clase\n\n  ```js\n  // jQuery\n  $('.class');\n\n  // Nativo\n  document.querySelectorAll('.class');\n\n  // Forma alternativa\n  document.getElementsByClassName('class');\n  ```\n\n- [1.2](#1.2) <a name='1.2'></a> Buscar por id\n\n  ```js\n  // jQuery\n  $('#id');\n\n  // Nativo\n  document.querySelector('#id');\n\n  // Forma alternativa\n  document.getElementById('id');\n  ```\n\n- [1.3](#1.3) <a name='1.3'></a> Buscar por atributo\n\n  ```js\n  // jQuery\n  $('a[target=_blank]');\n\n  // Nativo\n  document.querySelectorAll('a[target=_blank]');\n  ```\n\n- [1.4](#1.4) <a name='1.4'></a> Buscar en descendientes\n\n    ```js\n    // jQuery\n    $el.find('li');\n\n    // Nativo\n    el.querySelectorAll('li');\n    ```\n\n- [1.5](#1.5) <a name='1.5'></a> Elementos Hermanos/Previos/Siguientes\n\n  + Elementos hermanos\n\n    ```js\n    // jQuery\n    $el.siblings();\n\n    // Nativo\n    Array.prototype.filter.call(el.parentNode.children, (child) =>\n      child !== el\n    );\n    ```\n\n  + Elementos previos\n\n    ```js\n    // jQuery\n    $el.prev();\n\n    // Nativo\n    el.previousElementSibling;\n    ```\n\n  + Elementos siguientes\n\n    ```js\n    // jQuery\n    $el.next();\n\n    // Nativo\n    el.nextElementSibling;\n    ```\n\n- [1.6](#1.6) <a name='1.6'></a> Más cercano\n\n  Retorna el elemento más cercano que coincida con la condición, partiendo desde el nodo actual hasta document.\n\n  ```js\n  // jQuery\n  $el.closest(selector);\n\n  // Nativo - Sólo el último, NO IE\n  el.closest(selector);\n\n  // Nativo - IE10+\n  function closest(el, selector) {\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    while (el) {\n      if (matchesSelector.call(el, selector)) {\n        return el;\n      } else {\n        el = el.parentElement;\n      }\n    }\n    return null;\n  }\n  ```\n\n- [1.7](#1.7) <a name='1.7'></a> Padres hasta\n\n  Obtiene los ancestros de cada elemento en el set actual de elementos que cumplan con la condición, sin incluir el actual\n\n  ```js\n  // jQuery\n  $el.parentsUntil(selector, filter);\n\n  // Nativo\n  function parentsUntil(el, selector, filter) {\n    const result = [];\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    // Partir desde el elemento padre\n    el = el.parentElement;\n    while (el && !matchesSelector.call(el, selector)) {\n      if (!filter) {\n        result.push(el);\n      } else {\n        if (matchesSelector.call(el, filter)) {\n          result.push(el);\n        }\n      }\n      el = el.parentElement;\n    }\n    return result;\n  }\n  ```\n\n- [1.8](#1.8) <a name='1.8'></a> Formularios\n\n  + Input/Textarea\n\n    ```js\n    // jQuery\n    $('#my-input').val();\n\n    // Nativo\n    document.querySelector('#my-input').value;\n    ```\n\n  + Obtener el índice de e.currentTarget en `.radio`\n\n    ```js\n    // jQuery\n    $('.radio').index(e.currentTarget);\n\n    // Nativo\n    Array.prototype.indexOf.call(document.querySelectorAll('.radio'), e.currentTarget);\n    ```\n\n- [1.9](#1.9) <a name='1.9'></a> Contenidos de Iframe\n\n  `$('iframe').contents()` devuelve `contentDocument` para este iframe específico\n\n  + Contenidos de Iframe\n\n    ```js\n    // jQuery\n    $iframe.contents();\n\n    // Nativo\n    iframe.contentDocument;\n    ```\n\n  + Buscar dentro de un Iframe\n\n    ```js\n    // jQuery\n    $iframe.contents().find('.css');\n\n    // Nativo\n    iframe.contentDocument.querySelectorAll('.css');\n    ```\n\n- [1.10](#1.10) <a name='1.10'></a> Obtener body\n\n  ```js\n  // jQuery\n  $('body');\n\n  // Nativo\n  document.body;\n  ```\n\n- [1.11](#1.11) <a name='1.11'></a> Obtener y establecer atributos\n\n  + Obtener un atributo\n\n    ```js\n    // jQuery\n    $el.attr('foo');\n\n    // Nativo\n    el.getAttribute('foo');\n    ```\n  + Establecer un atributo\n\n    ```js\n    // jQuery, note que esto funciona en memoria sin cambiar el DOM\n    $el.attr('foo', 'bar');\n\n    // Nativo\n    el.setAttribute('foo', 'bar');\n    ```\n\n  + Obtener un atributo `data-`\n\n    ```js\n    // jQuery\n    $el.data('foo');\n\n    // Nativo\n    el.getAttribute('data-foo');\n\n    // Nativo (Utilice `dataset` solamente si necesita dar soporte a IE 11+)\n    el.dataset['foo'];\n    ```\n\n**[⬆ volver al inicio](#tabla-de-contenidos)**\n\n## CSS & Estilo\n\n- [2.1](#2.1) <a name='2.1'></a> CSS\n\n  + Obtener Estilo\n\n    ```js\n    // jQuery\n    $el.css(\"color\");\n\n    // Nativo\n    // NOTA: Bug conocido, retornará 'auto' si el valor de estilo es 'auto'\n    const win = el.ownerDocument.defaultView;\n\n    // null significa que no retorne pseudo estilos\n    win.getComputedStyle(el, null).color;\n    ```\n\n  + Establecer estilo\n\n    ```js\n    // jQuery\n    $el.css({ color: \"#ff0011\" });\n\n    // Nativo\n    el.style.color = '#ff0011';\n    ```\n\n  + Obtener/Establecer Estilos\n\n    Nótese que si se desea establecer múltiples estilos a la vez, se puede utilizar el método [setStyles](https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L194) en el paquete oui-dom-utils.\n\n\n  + Agregar clase\n\n    ```js\n    // jQuery\n    $el.addClass(className);\n\n    // Nativo\n    el.classList.add(className);\n    ```\n\n  + Quitar Clase\n\n    ```js\n    // jQuery\n    $el.removeClass(className);\n\n    // Nativo\n    el.classList.remove(className);\n    ```\n\n  + Consultar si tiene clase\n\n    ```js\n    // jQuery\n    $el.hasClass(className);\n\n    // Nativo\n    el.classList.contains(className);\n    ```\n\n  + Toggle class\n\n    ```js\n    // jQuery\n    $el.toggleClass(className);\n\n    // Nativo\n    el.classList.toggle(className);\n    ```\n\n- [2.2](#2.2) <a name='2.2'></a> Width & Height\n\n  Ancho y Alto son teóricamente idénticos. Usaremos el Alto como ejemplo:\n\n  + Alto de Ventana\n\n    ```js\n    // alto de ventana\n    $(window).height();\n\n    // Con scrollbar, se comporta como jQuery\n    window.document.documentElement.clientHeight;\n\n    // Sin scrollbar\n    window.innerHeight;\n    ```\n\n  + Alto de Documento\n\n    ```js\n    // jQuery\n    $(document).height();\n\n    // Native\n    const body = document.body;\n    const html = document.documentElement;\n    const height = Math.max(\n      body.offsetHeight,\n      body.scrollHeight,\n      html.clientHeight,\n      html.offsetHeight,\n      html.scrollHeight\n    );\n    ```\n\n  + Alto de Elemento\n\n    ```js\n    // jQuery\n    $el.height();\n\n    // Nativo\n    function getHeight(el) {\n      const styles = window.getComputedStyle(el);\n      const height = el.offsetHeight;\n      const borderTopWidth = parseFloat(styles.borderTopWidth);\n      const borderBottomWidth = parseFloat(styles.borderBottomWidth);\n      const paddingTop = parseFloat(styles.paddingTop);\n      const paddingBottom = parseFloat(styles.paddingBottom);\n      return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;\n    }\n\n    // Precisión de entero（para `border-box`, es `height - border`; con content-box`, es `height + padding`）\n    el.clientHeight;\n\n    // Precisión de decimal（para `border-box`, es `height`; con `content-box`, es `height + padding + border`）\n    el.getBoundingClientRect().height;\n    ```\n\n- [2.3](#2.3) <a name='2.3'></a> Posición y Offset\n\n  + Posición\n\n    Obtiene las coordenadas actuales del elemento, en relación con el padre.\n\n    ```js\n    // jQuery\n    $el.position();\n\n    // Nativo\n    { left: el.offsetLeft, top: el.offsetTop }\n    ```\n\n  + Offset\n\n    Obtiene las coordenadas actuales del elemento, en relación con el documento.\n\n    ```js\n    // jQuery\n    $el.offset();\n\n    // Nativo\n    function getOffset (el) {\n      const box = el.getBoundingClientRect();\n\n      return {\n        top: box.top + window.pageYOffset - document.documentElement.clientTop,\n        left: box.left + window.pageXOffset - document.documentElement.clientLeft\n      }\n    }\n    ```\n\n- [2.4](#2.4) <a name='2.4'></a> Posición vertical del scroll\n\n  Obtiene la posición vertical actual de la barra de scroll para el elemento.\n\n  ```js\n  // jQuery\n  $(window).scrollTop();\n\n  // Nativo\n  (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;\n  ```\n\n**[⬆ volver al inicio](#tabla-de-contenidos)**\n\n## Manipulación DOM\n\n- [3.1](#3.1) <a name='3.1'></a> Eliminar\n\n  Elimina el elemento del DOM\n\n  ```js\n  // jQuery\n  $el.remove();\n\n  // Nativo\n  el.parentNode.removeChild(el);\n  ```\n\n- [3.2](#3.2) <a name='3.2'></a> Texto\n\n  + Obtener Texto\n\n    Obtiene los contenidos de texto combinado del elemento, incluyendo sus decendientes.\n\n    ```js\n    // jQuery\n    $el.text();\n\n    // Nativo\n    el.textContent;\n    ```\n\n  + Establecer Texto\n\n    Establece el contenido del elemento al texto especificado\n\n    ```js\n    // jQuery\n    $el.text(string);\n\n    // Nativo\n    el.textContent = string;\n    ```\n\n- [3.3](#3.3) <a name='3.3'></a> HTML\n\n  + Obtener HTML\n\n    ```js\n    // jQuery\n    $el.html();\n\n    // Nativo\n    el.innerHTML;\n    ```\n\n  + Establecer HTML\n\n    ```js\n    // jQuery\n    $el.html(htmlString);\n\n    // Nativo\n    el.innerHTML = htmlString;\n    ```\n\n- [3.4](#3.4) <a name='3.4'></a> Añadir al final\n\n  Añadir elemento hijo después del último hijo del elemento padre\n\n  ```js\n  // jQuery\n  $el.append('<div id=\"container\">Hello World</div>');\n\n  // Nativo (string de HTML)\n  el.insertAdjacentHTML('beforeend', '<div id=\"container\">Hello World</div>');\n\n  // Nativo (Elemento)\n  el.appendChild(newEl);\n  ```\n\n- [3.5](#3.5) <a name='3.5'></a> Añadir al inicio\n\n  ```js\n  // jQuery\n  $el.prepend('<div id=\"container\">Hello World</div>');\n\n  // Nativo (String HTML)\n  el.insertAdjacentHTML('afterbegin', '<div id=\"container\">Hello World</div>');\n\n  // Nativo (Elemento)\n  el.insertBefore(newEl, el.firstChild);\n  ```\n\n- [3.6](#3.6) <a name='3.6'></a> Insertar Antes\n\n  Insertar un nuevo nodo antes de los elementos seleccionados\n\n  ```js\n  // jQuery\n  $newEl.insertBefore(selector);\n\n  // Nativo (String HTML)\n  el.insertAdjacentHTML('beforebegin ', '<div id=\"container\">Hello World</div>');\n\n  // Native (Elemento)\n  const el = document.querySelector(selector);\n  if (el.parentNode) {\n    el.parentNode.insertBefore(newEl, el);\n  }\n  ```\n\n- [3.7](#3.7) <a name='3.7'></a> Insertar después\n\n  Insertar un nuevo nodo después de los elementos seleccionados\n\n  ```js\n  // jQuery\n  $newEl.insertAfter(selector);\n\n  // Nativo (String HTML)\n  el.insertAdjacentHTML('afterend', '<div id=\"container\">Hello World</div>');\n\n  // Nativo (Elemento)\n  const el = document.querySelector(selector);\n  if (el.parentNode) {\n    el.parentNode.insertBefore(newEl, el.nextSibling);\n  }\n  ```\n\n- [3.8](#3.8) <a name='3.8'></a> es\n\n  Retorna `true` si coincide con el selector de la búsqueda\n\n  ```js\n  // jQuery - Nota `is` también funciona con `funciones` o `elementos` que no veremos aquí\n  $el.is(selector);\n\n  // Nativo\n  el.matches(selector);\n  ```\n- [3.9](#3.9) <a name='3.9'></a> Clonar\n\n  Crea una copia profunda del elemento\n\n  ```js\n  // jQuery\n  $el.clone();\n\n  // Nativo\n  el.cloneNode();\n\n  // Para hacer copia profunda , establece como parametro `true`\n  ```\n\n- [3.10](#3.10) <a name='3.10'></a> Vaciar\n\n  Elimina todos los nodos hijo\n\n  ```js\n  // jQuery\n  $el.empty();\n\n  // Nativo\n  el.innerHTML = '';\n  ```\n\n- [3.11](#3.11) <a name='3.11'></a> Envolver\n\n  Crea una estructura HTML alrededor de cada elemento\n\n  ```js\n  // jQuery\n  $('.inner').wrap('<div class=\"wrapper\"></div>');\n\n  // Nativo\n  Array.prototype.forEach.call(document.querySelectorAll('.inner'), (el) => {\n    const wrapper = document.createElement('div');\n    wrapper.className = 'wrapper';\n    el.parentNode.insertBefore(wrapper, el);\n    el.parentNode.removeChild(el);\n    wrapper.appendChild(el);\n  });\n  ```\n\n- [3.12](#3.12) <a name='3.12'></a> Desenvolver\n\n  Elimina los padres de una serie de elementos seleccionados del DOM\n\n  ```js\n  // jQuery\n  $('.inner').unwrap();\n\n  // Nativo\n  Array.prototype.forEach.call(document.querySelectorAll('.inner'), (el) => {\n    Array.prototype.forEach.call(el.childNodes, (child) => {\n      el.parentNode.insertBefore(child, el);\n    });\n    el.parentNode.removeChild(el);\n  });\n  ```\n\n- [3.13](#3.13) <a name='3.13'></a> Remplazar con\n\n  Remplaza cada elemento en una serie de elementos seleccionados con nuevo contenido.\n\n  ```js\n  // jQuery\n  $('.inner').replaceWith('<div class=\"outer\"></div>');\n\n  // Nativo\n  Array.prototype.forEach.call(document.querySelectorAll('.inner'), (el) => {\n    const outer = document.createElement('div');\n    outer.className = 'outer';\n    el.parentNode.insertBefore(outer, el);\n    el.parentNode.removeChild(el);\n  });\n  ```\n\n\n**[⬆ volver al inicio](#tabla-de-contenidos)**\n\n## Ajax\n\n+[Fetch API](https://fetch.spec.whatwg.org/) es el nuevo estándar que reemplaza a XMLHttpRequest para efectuar peticiones AJAX. Funciona en Chrome y Firefox, como también es posible usar un polyfill en otros navegadores.\n\nEs una buena alternativa utilizar [github/fetch](http://github.com/github/fetch) en IE9+ o [fetch-ie8](https://github.com/camsong/fetch-ie8/) en IE8+, [fetch-jsonp](https://github.com/camsong/fetch-jsonp) para efectuar peticiones JSONP.\n\n- [4.1](#4.1) <a name='4.1'></a> Carga datos desde un servidor y coloca el HTML regresado en el elemento seleccionado.\n\n  ```js\n  // jQuery\n  $(selector).load(url, completeCallback)\n\n  // Nativo\n  fetch(url).then(data => data.text()).then(data => {\n    document.querySelector(selector).innerHTML = data\n  }).then(completeCallback)\n  ```\n\n**[⬆ volver al inicio](#tabla-de-contenidos)**\n\n## Eventos\n\nPara un reemplazo completo con namespace y delegación, utilizar https://github.com/oneuijs/oui-dom-events\n\n- [5.0](#5.0) <a name='5.0'></a> Document ready by `DOMContentLoaded`\n\n  ```js\n  // jQuery\n  $(document).ready(eventHandler);\n\n  // Nativo\n  // Verifica que DOMContentLoaded ya se ha completado\n  if (document.readyState !== 'loading') {\n    eventHandler();\n  } else {\n    document.addEventListener('DOMContentLoaded', eventHandler);\n  }\n  ```\n\n- [5.1](#5.1) <a name='5.1'></a> Asignar un evento con \"on\"\n\n  ```js\n  // jQuery\n  $el.on(eventName, eventHandler);\n\n  // Nativo\n  el.addEventListener(eventName, eventHandler);\n  ```\n\n- [5.2](#5.2) <a name='5.2'></a> Desasignar un evento con \"off\"\n\n  ```js\n  // jQuery\n  $el.off(eventName, eventHandler);\n\n  // Nativo\n  el.removeEventListener(eventName, eventHandler);\n  ```\n\n- [5.3](#5.3) <a name='5.3'></a> Trigger\n\n  ```js\n  // jQuery\n  $(el).trigger('custom-event', {key1: 'data'});\n\n  // Nativo\n  if (window.CustomEvent) {\n    const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});\n  } else {\n    const event = document.createEvent('CustomEvent');\n    event.initCustomEvent('custom-event', true, true, {key1: 'data'});\n  }\n\n  el.dispatchEvent(event);\n  ```\n\n**[⬆ volver al inicio](#tabla-de-contenidos)**\n\n## Utilidades\n\nLa mayoría de las utilidades se encuentran en la API nativa. Otras funciones avanzadas podrían por utilidades de librerías que se centran en la consistencia y rendimiento. Se recomienda [lodash](https://lodash.com) como replazo.\n\n- [6.1](#6.1) <a name='6.1'></a> Utilidades Básicas\n\n  + isArray\n\n  Determina si el lemento es un vector(array).\n\n  ```js\n  // jQuery\n  $.isArray(array);\n\n  // Nativo\n  Array.isArray(array);\n  ```\n\n  + isWindow\n\n  Determina si el argumento en una ventana(window).\n\n  ```js\n  // jQuery\n  $.isWindow(obj);\n\n  // Nativo\n  function isWindow(obj) {\n    return obj !== null && obj !== undefined && obj === obj.window;\n  }\n  ```\n\n  + inArray\n\n  Busca un valor específico en el array y retorna su índice (o -1 si no lo encuentra).\n\n  ```js\n  // jQuery\n  $.inArray(item, array);\n\n  // Nativo\n  array.indexOf(item) > -1;\n\n  // ES6\n  array.includes(item);\n  ```\n\n  + isNumeric\n\n  Determina si el argumento es un número.\n  Utiliza `typeof` para decidir el tipo del `type` ejemplo para mayor precisión.\n\n  ```js\n  // jQuery\n  $.isNumeric(item);\n\n  // Nativo\n  function isNumeric(value) {\n    var type = typeof value;\n\n    return (type === 'number' || type === 'string') && !Number.isNaN(value - Number.parseFloat(value));\n  }\n  ```\n\n  + isFunction\n\n  Determina si el argumento es objecto función de Javascript.\n\n  ```js\n  // jQuery\n  $.isFunction(item);\n\n  // Nativo\n  function isFunction(item) {\n    if (typeof item === 'function') {\n      return true;\n    }\n    var type = Object.prototype.toString(item);\n    return type === '[object Function]' || type === '[object GeneratorFunction]';\n  }\n  ```\n\n  + isEmptyObject\n\n  Verifica que un objeto esté vacío(contiene propiedades no enumerables).\n\n  ```js\n  // jQuery\n  $.isEmptyObject(obj);\n\n  // Nativo\n  function isEmptyObject(obj) {\n    return Object.keys(obj).length === 0;\n  }\n  ```\n\n  + isPlainObject\n\n  Verifica si un objeto es un objeto plano (creado utilizando “{}” o “new Object”).\n\n  ```js\n  // jQuery\n  $.isPlainObject(obj);\n\n  // Nativo\n  function isPlainObject(obj) {\n    if (typeof (obj) !== 'object' || obj.nodeType || obj !== null && obj !== undefined && obj === obj.window) {\n      return false;\n    }\n\n    if (obj.constructor &&\n        !Object.prototype.hasOwnProperty.call(obj.constructor.prototype, 'isPrototypeOf')) {\n      return false;\n    }\n\n    return true;\n  }\n  ```\n\n  + extend\n\n  Combina los contenidos de dos o mas objetos en el primer objeto.\n  object.assign es una API de ES6, puedes utilizar [polyfill](https://github.com/ljharb/object.assign) también.\n\n  ```js\n  // jQuery\n  $.extend({}, defaultOpts, opts);\n\n  // Nativo\n  Object.assign({}, defaultOpts, opts);\n  ```\n\n  + trim\n\n  Elimina los espacios en blanco del inicio y final de un string.\n\n  ```js\n  // jQuery\n  $.trim(string);\n\n  // Nativo\n  string.trim();\n  ```\n\n  + map\n\n  Traslada todos los elementos en un arreglo u objeto a un nuevo arreglo de elementos.\n\n  ```js\n  // jQuery\n  $.map(array, (value, index) => {\n  });\n\n  // Nativo\n  array.map((value, index) => {\n  });\n  ```\n\n  + each\n\n  Una función genérica de iteración, que puede ser utilizada de manera similar para iterar en objetos o arreglos.\n\n  ```js\n  // jQuery\n  $.each(array, (index, value) => {\n  });\n\n  // Nativo\n  array.forEach((value, index) => {\n  });\n  ```\n\n  + grep\n\n  Encuentra los elementos de un arreglo que satisfacen una función filtro.\n\n  ```js\n  // jQuery\n  $.grep(array, (value, index) => {\n  });\n\n  // Nativo\n  array.filter((value, index) => {\n  });\n  ```\n\n  + type\n\n  Determina la clase [Class]  interna de Javascript de un objeto.\n\n  ```js\n  // jQuery\n  $.type(obj);\n\n  // Nativo\n  function type(item) {\n    const reTypeOf = /(?:^\\[object\\s(.*?)\\]$)/;\n    return Object.prototype.toString.call(item)\n      .replace(reTypeOf, '$1')\n      .toLowerCase();\n  }\n  ```\n\n  + merge\n\n  Combina los contenidos de dos o mas arreglos en el primero.\n\n  ```js\n  // jQuery\n  $.merge(array1, array2);\n\n  // Nativo\n  // Pero la función concat no elimina elementos duplicados.\n  function merge(...args) {\n    return [].concat(...args)\n  }\n  ```\n\n  + now\n\n  Retorna un número que representa la hora actual.\n\n  ```js\n  // jQuery\n  $.now();\n\n  // Native\n  Date.now();\n  ```\n\n  + proxy\n\n  Toma una función y regresa una nueva que siempre tendrá un contexto particular.\n\n  ```js\n  // jQuery\n  $.proxy(fn, context);\n\n  // Nativo\n  fn.bind(context);\n  ```\n\n  + makeArray\n\n  Convierte un objeto similar a un arreglo en un verdarero arreglo de Javascript.\n\n  ```js\n  // jQuery\n  $.makeArray(arrayLike);\n\n  // Nativo\n  Array.prototype.slice.call(arrayLike);\n\n  // ES6\n  Array.from(arrayLike);\n  ```\n\n- [6.2](#6.2) <a name='6.2'></a> Contenedores\n\n  Verifica si un elemento del DOM es descendiente de otro elemento del DOM.\n\n  ```js\n  // jQuery\n  $.contains(el, child);\n\n  // Nativo\n  el !== child && el.contains(child);\n  ```\n\n- [6.3](#6.3) <a name='6.3'></a> Globaleval\n\n  Ejecuta el mismo código Javascript de manera global.\n\n  ```js\n  // jQuery\n  $.globaleval(code);\n\n  // Nativo\n  function Globaleval(code) {\n    const script = document.createElement('script');\n    script.text = code;\n\n    document.head.appendChild(script).parentNode.removeChild(script);\n  }\n\n  // Utilzando eval, pero el contexto de eval es el actual, el contexto de $.Globaleval es global.\n  eval(code);\n  ```\n\n- [6.4](#6.4) <a name='6.4'></a> parse\n\n  + parseHTML\n\n  Parsea un string ien un arreglo de nodos DOM.\n\n  ```js\n  // jQuery\n  $.parseHTML(htmlString);\n\n  // Nativo\n  function parseHTML(string) {\n    const context = document.implementation.createHTMLDocument();\n\n    // Se establece la base href para el documento creado, así todos los elementos parseados con URLs\n    // estarán basados en ña URL del documento\n    const base = context.createElement('base');\n    base.href = document.location.href;\n    context.head.appendChild(base);\n\n    context.body.innerHTML = string;\n    return context.body.children;\n  }\n  ```\n\n  + parseJSON\n\n  Toma un string de JSON *bien formado* y retorna el valor resultante de Javascript.\n\n  ```js\n  // jQuery\n  $.parseJSON(str);\n\n  // Native\n  JSON.parse(str);\n  ```\n\n**[⬆ volver al inicio](#tabla-de-contenidos)**\n\n## Promesas\n\nUna promesa, representa el resultado eventual de una operación asíncrona. jQuery tiene su propio sistema para utilizar promesas. JavaScript nativo implementa una ligera y mínima API para utilizar promesas de acuerdo con la especificación [Promises/A+](http://promises-aplus.github.io/promises-spec/).\n\n- [7.1](#7.1) <a name='7.1'></a> done, fail, always\n\n  `done` se llama cuando una promesa se resuelve, `fail` se llama cuando una promesa es rechazada, `always` se llama cuando una promesa no ha sido resuelta o rechazada.\n\n  ```js\n  // jQuery\n  $promise.done(doneCallback).fail(failCallback).always(alwaysCallback)\n\n  // Nativo\n  promise.then(doneCallback, failCallback).then(alwaysCallback, alwaysCallback)\n  ```\n\n- [7.2](#7.2) <a name='7.2'></a> when\n\n  `when` se utiliza para manipular múltiples promesas. Se resolverá cuando todas las promesas sean resueltas y se rechazará si alguna es rechazada.\n\n  ```js\n  // jQuery\n  $.when($promise1, $promise2).done((promise1Result, promise2Result) => {\n  });\n\n  // Nativo\n  Promise.all([$promise1, $promise2]).then([promise1Result, promise2Result] => {});\n  ```\n\n- [7.3](#7.3) <a name='7.3'></a> Deferred\n\n  Deferred es una manera de crear promesas.\n\n  ```js\n  // jQuery\n  function asyncFunc() {\n    const defer = new $.Deferred();\n    setTimeout(() => {\n      if(true) {\n        defer.resolve('some_value_computed_asynchronously');\n      } else {\n        defer.reject('failed');\n      }\n    }, 1000);\n\n    return defer.promise();\n  }\n\n  // Nativo\n  function asyncFunc() {\n    return new Promise((resolve, reject) => {\n      setTimeout(() => {\n        if (true) {\n          resolve('some_value_computed_asynchronously');\n        } else {\n          reject('failed');\n        }\n      }, 1000);\n    });\n  }\n\n  // Deferred\n  function defer() {\n    const deferred = {};\n    const promise = new Promise((resolve, reject) => {\n      deferred.resolve = resolve;\n      deferred.reject = reject;\n    });\n\n    deferred.promise = () => {\n      return promise;\n    };\n\n    return deferred;\n  }\n\n  function asyncFunc() {\n    const defer = defer();\n    setTimeout(() => {\n      if(true) {\n        defer.resolve('some_value_computed_asynchronously');\n      } else {\n        defer.reject('failed');\n      }\n    }, 1000);\n\n    return defer.promise();\n  }\n  ```\n\n**[⬆ volver al inicio](#tabla-de-contenidos)**\n\n## Animaciones\n\n- [8.1](#8.1) <a name='8.1'></a> Mostrar y ocultar\n\n  ```js\n  // jQuery\n  $el.show();\n  $el.hide();\n\n  // Native\n  // Para mas detalles acerca del método show, refierase a https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L363\n  el.style.display = ''|'inline'|'inline-block'|'inline-table'|'block';\n  el.style.display = 'none';\n  ```\n\n- [8.2](#8.2) <a name='8.2'></a> Toggle\n\n  Muestra u oculta el elemento\n\n  ```js\n  // jQuery\n  $el.toggle();\n\n  // Nativo\n  if (el.ownerDocument.defaultView.getComputedStyle(el, null).display === 'none') {\n    el.style.display = ''|'inline'|'inline-block'|'inline-table'|'block';\n  } else {\n    el.style.display = 'none';\n  }\n  ```\n\n- [8.3](#8.3) <a name='8.3'></a> FadeIn & FadeOut\n\n  ```js\n  // jQuery\n  $el.fadeIn(3000);\n  $el.fadeOut(3000);\n\n  // Nativo\n  el.style.transition = 'opacity 3s';\n  // fadeIn\n  el.style.opacity = '1';\n  // fadeOut\n  el.style.opacity = '0';\n  ```\n\n- [8.4](#8.4) <a name='8.4'></a> FadeTo\n\n  Ajusta la opacidad del elemento\n\n  ```js\n  // jQuery\n  $el.fadeTo('slow',0.15);\n  // Nativo\n  el.style.transition = 'opacity 3s'; // assume 'slow' equals 3 seconds\n  el.style.opacity = '0.15';\n  ```\n\n- [8.5](#8.5) <a name='8.5'></a> FadeToggle\n\n  Muestra u oculta el emento animando su opacidad.\n\n  ```js\n  // jQuery\n  $el.fadeToggle();\n\n  // Nativo\n  el.style.transition = 'opacity 3s';\n  const { opacity } = el.ownerDocument.defaultView.getComputedStyle(el, null);\n  if (opacity === '1') {\n    el.style.opacity = '0';\n  } else {\n    el.style.opacity = '1';\n  }\n  ```\n\n- [8.6](#8.6) <a name='8.6'></a> SlideUp & SlideDown\n\n  ```js\n  // jQuery\n  $el.slideUp();\n  $el.slideDown();\n\n  // Nativo\n  const originHeight = '100px';\n  el.style.transition = 'height 3s';\n  // slideUp\n  el.style.height = '0px';\n  // slideDown\n  el.style.height = originHeight;\n  ```\n\n- [8.7](#8.7) <a name='8.7'></a> SlideToggle\n\n  Muestra u oculta el elemento con una animación de deslizamiento.\n\n  ```js\n  // jQuery\n  $el.slideToggle();\n\n  // Nativo\n  const originHeight = '100px';\n  el.style.transition = 'height 3s';\n  const { height } = el.ownerDocument.defaultView.getComputedStyle(el, null);\n  if (parseInt(height, 10) === 0) {\n    el.style.height = originHeight;\n  }\n  else {\n   el.style.height = '0px';\n  }\n  ```\n\n- [8.8](#8.8) <a name='8.8'></a> Animate\n\n  Realiza una animación personalizada de un conjunto de propiedades CSS.\n\n  ```js\n  // jQuery\n  $el.animate({ params }, speed);\n\n  // Nativo\n  el.style.transition = 'all ' + speed;\n  Object.keys(params).forEach((key) => {\n    el.style[key] = params[key];\n  });\n  ```\n\n## Alternativas\n\n* [Quizá no necesites jQuery](http://youmightnotneedjquery.com/) - Ejemplos de como hacer un evento común, un elemento, ajax, etc, con Javascript puro.\n* [npm-dom](http://github.com/npm-dom) y [webmodules](http://github.com/webmodules) - Organizaciones en las puedes encontrar módulos individuales del DOM en NPM.\n\n## Navegadores soportados\n\n![Chrome][chrome-image] | ![Firefox][firefox-image] | ![IE][ie-image] | ![Opera][opera-image] | ![Safari][safari-image]\n--- | --- | --- | --- | --- |\nÚltima ✔ | Última ✔ | 10+ ✔ | Última ✔ | 6.1+ ✔ |\n\n# Licencia\n\nMIT\n\n[chrome-image]: https://raw.github.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png\n[firefox-image]: https://raw.github.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png\n[ie-image]: https://raw.github.com/alrra/browser-logos/master/src/archive/internet-explorer_9-11/internet-explorer_9-11_48x48.png\n[opera-image]: https://raw.github.com/alrra/browser-logos/master/src/opera/opera_48x48.png\n[safari-image]: https://raw.github.com/alrra/browser-logos/master/src/safari/safari_48x48.png\n"
  },
  {
    "path": "README-fr.md",
    "content": "## Vous n'avez pas besoin de jQuery\n\n\n\nDe nos jours, les environnements frontend évoluent si rapidement que les navigateurs récents ont déjà implémenté beaucoup d'API DOM/BOM suffisantes. Il n'est pas utile d'apprendre jQuery à partir de rien pour manipuler le DOM ou les évènements. Pendant ce temps, grâce à l'efficacité de bibliothèques frontend comme React, Angular et Vue, manipuler directement le DOM est devenu obsolète, jQuery n'a jamais été aussi peu important. Ce projet résume la plupart des alternatives à jQuery à l'aide d'implémentations natives, compatibles avec IE 10+.\n\n## Sommaire\n\n1. [Traductions](#traductions)\n1. [Sélecteur jQuery](#sélecteur-jquery)\n1. [Style et CSS](#style--css)\n1. [Manipulation du DOM](#manipulation-du-dom)\n1. [Ajax](#ajax)\n1. [Évènements](#évènements)\n1. [Utilitaires](#utilitaires)\n1. [Promesses](#promesses)\n1. [Animation](#animation)\n1. [Alternatives](#alternatives)\n1. [Navigateurs compatibles](#navigateurs-compatibles)\n\n## Traductions\n\n* [한국어](./README.ko-KR.md)\n* [正體中文](./README.zh-TW.md)\n* [简体中文](./README.zh-CN.md)\n* [Bahasa Melayu](./README-my.md)\n* [Bahasa Indonesia](./README-id.md)\n* [Português(PT-BR)](./README.pt-BR.md)\n* [Tiếng Việt Nam](./README-vi.md)\n* [Español](./README-es.md)\n* [Русский](./README-ru.md)\n* [Кыргызча](./README-kg.md)\n* [Türkçe](./README-tr.md)\n* [Italiano](./README-it.md)\n* [Français](./README-fr.md)\n* [日本語](./README-ja.md)\n* [Polski](./README-pl.md)\n\n## Sélecteur jQuery\n\nÀ la place des sélecteurs communs comme class, id ou attribute il est possible d'utiliser `document.querySelector` ou `document.querySelectorAll`. Les différences sont que:\n* `document.querySelector` retourne le premier élément trouvé,\n* `document.querySelectorAll` retourne tous les éléments trouvés sous forme d'une [NodeList](https://developer.mozilla.org/en-US/docs/Web/API/NodeList). Il est possible de le convertir en Array à l'aide de `[].slice.call(document.querySelectorAll(selector) || []);`,\n* si aucun élément n'a été trouvé, jQuery peut retourner `[]` alors que l'API DOM va retourner `null`. Faites attention au Null Pointer Exception. Vous pouvez aussi utiliser `||` pour définir la valeur par défaut si rien n'a été trouvé, comme `document.querySelectorAll(selector) || []`.\n\n> Remarque: `document.querySelector` et `document.querySelectorAll` sont assez **LENTS**, essayez plutôt d'utiliser `getElementById`, `document.getElementsByClassName` ou `document.getElementsByTagName` si vous souhaitez obtenir un gain de performance.\n\n- [1.0](#1.0) <a name='1.0'></a> Requête par sélecteur\n\n  ```js\n  // jQuery\n  $('selector');\n\n  // Natif\n  document.querySelectorAll('selector');\n  ```\n\n- [1.1](#1.1) <a name='1.1'></a> Requête par classe\n\n  ```js\n  // jQuery\n  $('.class');\n\n  // Natif\n  document.querySelectorAll('.class');\n\n  // ou\n  document.getElementsByClassName('class');\n  ```\n\n- [1.2](#1.2) <a name='1.2'></a> Requête par id\n\n  ```js\n  // jQuery\n  $('#id');\n\n  // Natif\n  document.querySelector('#id');\n\n  // ou\n  document.getElementById('id');\n  ```\n\n- [1.3](#1.3) <a name='1.3'></a> Requête par attribut\n\n  ```js\n  // jQuery\n  $('a[target=_blank]');\n\n  // Natif\n  document.querySelectorAll('a[target=_blank]');\n  ```\n- [1.4](#1.4) <a name='1.4'></a> Requête par descendants\n\n  ```js\n  // jQuery\n  $el.find('li');\n\n  // Natif\n  el.querySelectorAll('li');\n  ```\n- [1.5](#1.5) <a name='1.5'></a> Éléments voisins/précédents/suivants\n\n  + Éléments voisins\n\n    ```js\n    // jQuery\n    $el.siblings();\n\n    // Natif\n    [].filter.call(el.parentNode.children, function(child) {\n      return child !== el;\n    });\n    ```\n\n  + Éléments précédents\n\n    ```js\n    // jQuery\n    $el.prev();\n\n    // Natif\n    el.previousElementSibling;\n\n    ```\n\n  + Éléments suivants\n\n    ```js\n    // next\n    $el.next();\n    el.nextElementSibling;\n    ```\n\n- [1.6](#1.6) <a name='1.6'></a> Plus proche\n\n  Retourne le premier élément trouvé à l'aide du sélecteur fourni, parcourant l'élément actuel vers le document.\n\n  ```js\n  // jQuery\n  $el.closest(queryString);\n\n  // Natif - Seulement le dernier, ne fonctionne pas sous IE\n  el.closest(selector);\n\n  // Natif - IE10+\n  function closest(el, selector) {\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    while (el) {\n      if (matchesSelector.call(el, selector)) {\n        return el;\n      } else {\n        el = el.parentElement;\n      }\n    }\n    return null;\n  }\n  ```\n\n- [1.7](#1.7) <a name='1.7'></a> Parents jusqu'à\n\n  Retourne les ancêtres de chaque élément dans l'ensemble d'éléments trouvés courants, jusqu'à (sans l'inclure) l'élément correspondant au sélecteur, le noeud DOM ou l'objet JQuery.\n\n  ```js\n  // jQuery\n  $el.parentsUntil(selector, filter);\n\n  // Natif\n  function parentsUntil(el, selector, filter) {\n    const result = [];\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    // la correspondance commence à partir du parent\n    el = el.parentElement;\n    while (el && !matchesSelector.call(el, selector)) {\n      if (!filter) {\n        result.push(el);\n      } else {\n        if (matchesSelector.call(el, filter)) {\n          result.push(el);\n        }\n      }\n      el = el.parentElement;\n    }\n    return result;\n  }\n  ```\n\n- [1.8](#1.8) <a name='1.8'></a> Formulaire\n\n  + Input/Textarea\n\n    ```js\n    // jQuery\n    $('#my-input').val();\n\n    // Natif\n    document.querySelector('#my-input').value;\n    ```\n\n  + Obtenir l'index du e.currentTarget entre `.radio`\n\n    ```js\n    // jQuery\n    $(e.currentTarget).index('.radio');\n\n    // Natif\n    [].indexOf.call(document.querySelectorAll('.radio'), e.currentTarget);\n    ```\n\n- [1.9](#1.9) <a name='1.9'></a> Contenus Iframe\n\n  `$('iframe').contents()` retourne `contentDocument` pour cet iframe en particulier\n\n  + Contenus de l'Iframe\n\n    ```js\n    // jQuery\n    $iframe.contents();\n\n    // Natif\n    iframe.contentDocument;\n    ```\n\n  + Requête Iframe\n\n    ```js\n    // jQuery\n    $iframe.contents().find('.css');\n\n    // Natif\n    iframe.contentDocument.querySelectorAll('.css');\n    ```\n\n**[⬆ remonter](#table-of-contents)**\n\n## Style & CSS\n\n- [2.1](#2.1) <a name='2.1'></a> CSS\n\n  + Obtenir le style\n\n    ```js\n    // jQuery\n    $el.css(\"color\");\n\n    // Natif\n    // NOTE: Bug connu, retournera 'auto\" si la valeur du site est 'auto'\n    const win = el.ownerDocument.defaultView;\n    // null signifie ne pas retourner les pseudo styles\n    win.getComputedStyle(el, null).color;\n    ```\n\n  + Définir le style\n\n    ```js\n    // jQuery\n    $el.css({ color: \"#ff0011\" });\n\n    // Natif\n    el.style.color = '#ff0011';\n    ```\n\n  + Obtenir/Définir les styles\n\n    Notez que si vous souhaitez définir plusieurs styles à la fois, you devriez vous référer à la méthode [setStyles](https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L194) du paquet oui-dom-utils.\n\n\n  + Ajouter une classe\n\n    ```js\n    // jQuery\n    $el.addClass(className);\n\n    // Natif\n    el.classList.add(className);\n    ```\n\n  + Supprimer une classe\n\n    ```js\n    // jQuery\n    $el.removeClass(className);\n\n    // Natif\n    el.classList.remove(className);\n    ```\n\n  + Possède une classe\n\n    ```js\n    // jQuery\n    $el.hasClass(className);\n\n    // Natif\n    el.classList.contains(className);\n    ```\n\n  + Basculer une class\n\n    ```js\n    // jQuery\n    $el.toggleClass(className);\n\n    // Natif\n    el.classList.toggle(className);\n    ```\n\n- [2.2](#2.2) <a name='2.2'></a> Largeur et Hauteur\n\n  Travailler avec la hauteur ou la largeur est en théorie identique, prenons la hauteur pour exemple:\n\n  + Hauteur de la fenêtre\n\n    ```js\n    // hauteur de la fenêtre\n    $(window).height();\n    // se comporte comme jQuery sans ascenseur\n    window.document.documentElement.clientHeight;\n    // avec ascenseur\n    window.innerHeight;\n    ```\n\n  + Hauteur du document\n\n    ```js\n    // jQuery\n    $(document).height();\n\n    // Natif\n    document.documentElement.scrollHeight;\n    ```\n\n  + Hauteur de l'élement\n\n    ```js\n    // jQuery\n    $el.height();\n\n    // NatiF\n    function getHeight(el) {\n      const styles = window.getComputedStyle(el);\n      const height = el.offsetHeight;\n      const borderTopWidth = parseFloat(styles.borderTopWidth);\n      const borderBottomWidth = parseFloat(styles.borderBottomWidth);\n      const paddingTop = parseFloat(styles.paddingTop);\n      const paddingBottom = parseFloat(styles.paddingBottom);\n      return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;\n    }\n    // précis à l'entier près (quand `border-box`, son `height - border`; quand `content-box`, son `height + padding`)\n    el.clientHeight;\n    // précis à la décimale près (quand `border-box`, son `height`; quand `content-box`, son `height + padding + border`)\n    el.getBoundingClientRect().height;\n    ```\n\n- [2.3](#2.3) <a name='2.3'></a> Position et offset\n\n  + Position\n\n    Récupère les coordonnées courantes de l'élement relatif à l'offset parent.\n\n    ```js\n    // jQuery\n    $el.position();\n\n    // Natif\n    { left: el.offsetLeft, top: el.offsetTop }\n    ```\n\n  + Offset\n\n    Récupère les coordonnées courantes de l'élement relatif au document.\n\n    ```js\n    // jQuery\n    $el.offset();\n\n    // Natif\n    function getOffset (el) {\n      const box = el.getBoundingClientRect();\n\n      return {\n        top: box.top + window.pageYOffset - document.documentElement.clientTop,\n        left: box.left + window.pageXOffset - document.documentElement.clientLeft\n      }\n    }\n    ```\n\n- [2.4](#2.4) <a name='2.4'></a> Défiler vers le haut\n\n  Récupère la position verticale courante de l'ascenseur pour cet élément.\n\n  ```js\n  // jQuery\n  $(window).scrollTop();\n\n  // Natif\n  (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;\n  ```\n\n**[⬆ remonter](#table-of-contents)**\n\n## Manipulation du DOM\n\n- [3.1](#3.1) <a name='3.1'></a> Supprimer\n\n  Supprime l'élément du DOM.\n\n  ```js\n  // jQuery\n  $el.remove();\n\n  // Natif\n  el.parentNode.removeChild(el);\n  ```\n\n- [3.2](#3.2) <a name='3.2'></a> Texte\n\n  + Obtenir le texte\n\n    Récupère le contenu textuel combiné de l'élément en incluant ses descendants.\n\n    ```js\n    // jQuery\n    $el.text();\n\n    // Natif\n    el.textContent;\n    ```\n\n  + Définir le text\n\n    Définit le contenu de l'élément à partir du texte spécifié.\n\n    ```js\n    // jQuery\n    $el.text(string);\n\n    // Natif\n    el.textContent = string;\n    ```\n\n- [3.3](#3.3) <a name='3.3'></a> HTML\n\n  + Obtenir l'HTML\n\n    ```js\n    // jQuery\n    $el.html();\n\n    // Natif\n    el.innerHTML;\n    ```\n\n  + Définir l'HTML\n\n    ```js\n    // jQuery\n    $el.html(htmlString);\n\n    // Natif\n    el.innerHTML = htmlString;\n    ```\n\n- [3.4](#3.4) <a name='3.4'></a> Ajouter\n\n  Ajouter un élément enfant après le dernier enfant de l'élément parent.\n\n  ```js\n  // jQuery\n  $el.append(\"<div id='container'>hello</div>\");\n\n  // Natif\n  let newEl = document.createElement('div');\n  newEl.setAttribute('id', 'container');\n  newEl.innerHTML = 'hello';\n  el.appendChild(newEl);\n  ```\n\n- [3.5](#3.5) <a name='3.5'></a> Faire précéder\n\n  ```js\n  // jQuery\n  $el.prepend(\"<div id='container'>hello</div>\");\n\n  // Natif\n  let newEl = document.createElement('div');\n  newEl.setAttribute('id', 'container');\n  newEl.innerHTML = 'hello';\n  el.insertBefore(newEl, el.firstChild);\n  ```\n\n- [3.6](#3.6) <a name='3.6'></a> Insérer avant\n\n  Insérer un nouveau noeud avant les éléments sélectionnés.\n\n  ```js\n  // jQuery\n  $newEl.insertBefore(queryString);\n\n  // Natif\n  newEl.insertBefore(document.querySelector(queryString));\n  ```\n\n- [3.7](#3.7) <a name='3.7'></a> Insérer après\n\n  Insérer un nouveau noeud après les noeuds sélectionnés\n\n  ```js\n  // jQuery\n  $newEl.insertAfter(queryString);\n\n  // Natif\n  function insertAfter(newEl, queryString) {\n    const parent = document.querySelector(queryString).parentNode;\n\n    if (parent.lastChild === newEl) {\n      parent.appendChild(newEl);\n    } else {\n      parent.insertBefore(newEl, parent.nextSibling);\n    }\n  },\n  ```\n- [3.8](#3.8) <a name='3.8'></a> est\n\n  Retourne `true` le paramètre correspond à la requête de sélection\n\n  ```js\n  // jQuert - Noter que `is` fonctionne également avec `function` ou `elements` qui ne sont pas concernés ici\n  $el.is(selector);\n\n  // Natif\n  el.matches(selector);\n  ```\n\n- [3.9](#3.9) <a name='3.9'></a> clone\n\n  Créé une copie profonde de cet élément\n\n  ```js\n  // jQuery\n  $el.clone();\n\n  // Natif\n  el.cloneNode();\n\n  // Pour une copie profonde, définir le paramètre à `true`\n  ```\n\n- [3.10](#3.10) <a name='3.10'></a> vider\n\n  Supprime tous les noeuds enfants\n\n  ```js\n  // jQuery\n  $el.empty();\n\n  // Natif\n  el.innerHTML = '';\n  ```\n\n- [3.11](#3.11) <a name='3.11'></a> enrouler\n\n  Enrouler une structure HTML autour de chaque élément\n\n  ```js\n  // jQuery\n  $('.inner').wrap('<div class=\"wrapper\"></div>');\n\n  // Natif\n  [].slice.call(document.querySelectorAll('.inner')).forEach(function(el){\n    var wrapper = document.createElement('div');\n    wrapper.className = 'wrapper';\n    el.parentNode.insertBefore(wrapper, el);\n    el.parentNode.removeChild(el);\n    wrapper.appendChild(el);\n  });\n  ```\n\n- [3.12](#3.12) <a name='3.12'></a> dérouler\n\n  Supprime les parents de la collection des éléments correspondants du DOM\n\n  ```js\n  // jQuery\n  $('.inner').unwrap();\n\n  // Natif\n  [].slice.call(document.querySelectorAll('.inner')).forEach(function(el){\n    [].slice.call(el.childNodes).forEach(function(child){\n      el.parentNode.insertBefore(child, el);\n    });\n    el.parentNode.removeChild(el);\n  });\n  ```\n**[⬆ remonter](#table-of-contents)**\n\n## Ajax\n\n[Fetch API](https://fetch.spec.whatwg.org/) est le nouveau standard qui a pour but de remplacer XMLHttpRequest afin de faire de l'ajax. Il fonctionne sous Chrome et Firefox, il est possible d'utiliser polyfills pour le faire fonctionner sur de vieux navigateurs.\n\nEssayer [github/fetch](http://github.com/github/fetch) sous IE9+ ou [fetch-ie8](https://github.com/camsong/fetch-ie8/) sous IE8+, [fetch-jsonp](https://github.com/camsong/fetch-jsonp) pour construire des requêtes JSONP.\n\n**[⬆ remonter](#table-of-contents)**\n\n## Évènements\n\nPour remplacer complètement jusqu'aux espaces de nom et délégations, se référer à https://github.com/oneuijs/oui-dom-events\n\n- [5.1](#5.1) <a name='5.1'></a> Attacher un événement avec `on`\n\n  ```js\n  // jQuery\n  $el.on(eventName, eventHandler);\n\n  // Natif\n  el.addEventListener(eventName, eventHandler);\n  ```\n\n- [5.2](#5.2) <a name='5.2'></a> Détacher un événement avec `off`\n\n  ```js\n  // jQuery\n  $el.off(eventName, eventHandler);\n\n  // Natif\n  el.removeEventListener(eventName, eventHandler);\n  ```\n\n- [5.3](#5.3) <a name='5.3'></a> Trigger\n\n  ```js\n  // jQuery\n  $(el).trigger('custom-event', {key1: 'data'});\n\n  // Natif\n  if (window.CustomEvent) {\n    const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});\n  } else {\n    const event = document.createEvent('CustomEvent');\n    event.initCustomEvent('custom-event', true, true, {key1: 'data'});\n  }\n\n  el.dispatchEvent(event);\n  ```\n\n**[⬆ remonter](#table-of-contents)**\n\n## Utilitaires\n\nLa plupart des utilitaires se trouvent dans l'API native. D'autres fonctions avancées peuvent être choisies afin de se concentrer sur la cohérence et la performance. Il est recommandé de remplacer par [lodash](https://lodash.com).\n\n- [6.1](#6.1) <a name='6.1'></a> Utilitaires basiques\n\n  + isArray\n\n  Détermine si l'argument est un tableau.\n\n  ```js\n  // jQuery\n  $.isArray(range);\n\n  // Natif\n  Array.isArray(range);\n  ```\n\n  + isWindow\n\n  Détermine si l'argument est une fenêtre.\n\n  ```js\n  // jQuery\n  $.isWindow(obj);\n\n  // Native\n  function isWindow(obj) {\n    return obj != null && obj === obj.window;\n  }\n  ```\n\n  + inArray\n\n  Recherche une valeur spécifique à l'intérieur d'un tableau et retourne son index (ou -1 si rien n'a été trouvé).\n\n  ```js\n  // jQuery\n  $.inArray(item, array);\n\n  // Natif\n  Array.indexOf(item);\n  ```\n\n  + isNumeric\n\n  Détermine si l'argument est un nombre.\n  Utiliser `typeof` pour décider du type. Si nécessaire utiliser une bibliothèque, parfois `typeof` n'est pas exact.\n\n  ```js\n  // jQuery\n  $.isNumeric(item);\n\n  // Natif\n  function isNumeric(item) {\n    return typeof item === 'number';\n  }\n  ```\n\n  + isFunction\n\n  Détermine si l'argument est un objet fonction JavaScript.\n\n  ```js\n  // jQuery\n  $.isFunction(item);\n\n  // Natif\n  function isFunction(item) {\n    return typeof value === 'function';\n  }\n  ```\n\n  + isEmptyObject\n\n  Vérifie si un objet est vide (ne contient aucune propriétés énumérables).\n\n  ```js\n  // jQuery\n  $.isEmptyObject(obj);\n\n  // Natif\n  function isEmptyObject(obj) {\n    for (let key in obj) {\n      return false;\n    }\n    return true;\n  }\n  ```\n\n  + isPlainObject\n\n  Vérifie si un objet est un objet \"plat\" (créé en utilisant \"{}\" ou \"new Object\").\n\n  ```js\n  // jQuery\n  $.isPlainObject(obj);\n\n  // Natif\n  function isPlainObject(obj) {\n    if (typeof (obj) !== 'object' || obj.nodeType || obj != null && obj === obj.window) {\n      return false;\n    }\n\n    if (obj.constructor &&\n        !{}.hasOwnProperty.call(obj.constructor.prototype, 'isPrototypeOf')) {\n      return false;\n    }\n\n    return true;\n  }\n  ```\n\n  + extend\n\n  Fusionne le contenu de deux objets ou plus ensembles en un seul objet.\n  Object.assign fait parti de l'API ES6, il est également possible d'utiliser [polyfill](https://github.com/ljharb/object.assign).\n\n  ```js\n  // jQuery\n  $.extend({}, defaultOpts, opts);\n\n  // Natif\n  Object.assign({}, defaultOpts, opts);\n  ```\n\n  + trim\n\n  Supprime les espaces au début et à la fin d'une chaine de caractères String.\n\n  ```js\n  // jQuery\n  $.trim(string);\n\n  // Natif\n  string.trim();\n  ```\n\n  + map\n\n  Traduit tous les éléments d'un tableau ou d'un objet vers un nouveau tableau d'éléments.\n\n  ```js\n  // jQuery\n  $.map(array, function(value, index) {\n  });\n\n  // Natif\n  array.map(function(value, index) {\n  });\n  ```\n\n  + each\n\n  Une fonction générique d'itération, qui peut être utilisée pour itérer de façon transparente à travers des objets et des tableaux.\n\n  ```js\n  // jQuery\n  $.each(array, function(value, index) {\n  });\n\n  // Natif\n  array.forEach(function(value, index) {\n  });\n  ```\n\n  + grep\n\n  Trouve les éléments d'un tableau qui satisfont avec une fonction filtre.\n\n  ```js\n  // jQuery\n  $.grep(array, function(value, index) {\n  });\n\n  // Natif\n  array.filter(function(value, index) {\n  });\n  ```\n\n  + type\n\n  Détermine la [[Class]] interne JavaScript d'un objet.\n\n  ```js\n  // jQuery\n  $.type(obj);\n\n  // Natif\n  Object.prototype.toString.call(obj).replace(/^\\[object (.+)\\]$/, '$1').toLowerCase();\n  ```\n\n  + merge\n\n  Fusionne le contenu de deux tableau dans un seul tableau.\n\n  ```js\n  // jQuery\n  $.merge(array1, array2);\n\n  // Natif\n  // But concat function don't remove duplicate items.\n  function merge() {\n    return Array.prototype.concat.apply([], arguments)\n  }\n  ```\n\n  + now\n\n  Retourne un nombre représentant l'heure actuelle.\n\n  ```js\n  // jQuery\n  $.now();\n\n  // Natif\n  Date.now();\n  ```\n\n  + proxy\n\n  Prend une fonction et en retourne une nouvelle qui aura toujours un contexte particulier.\n\n  ```js\n  // jQuery\n  $.proxy(fn, context);\n\n  // Natif\n  fn.bind(context);\n  ```\n\n  + makeArray\n\n  Convertit un objet \"array-like\" vers un véritable tableau JavaScript.\n\n  ```js\n  // jQuery\n  $.makeArray(array);\n\n  // Natif\n  [].slice.call(array);\n  ```\n\n- [6.2](#6.2) <a name='6.2'></a> Contient\n\n  Vérifie si un élément du DOM est un descendant d'un autre élément du DOM.\n\n  ```js\n  // jQuery\n  $.contains(el, child);\n\n  // Natif\n  el !== child && el.contains(child);\n  ```\n\n- [6.3](#6.3) <a name='6.3'></a> Globaleval\n\n  Exécute du code JavaScript de manière globale.\n\n  ```js\n  // jQuery\n  $.globaleval(code);\n\n  // Natif\n  function Globaleval(code) {\n    let script = document.createElement('script');\n    script.text = code;\n\n    document.head.appendChild(script).parentNode.removeChild(script);\n  }\n\n  // Utilise eval, mais le contexte d'eval est l'actuel alors que le contexte de $.Globaleval est global.\n  eval(code);\n  ```\n\n- [6.4](#6.4) <a name='6.4'></a> parse\n\n  + parseHTML\n\n  Parse une chaine de caractères vers un tableau de noeuds DOM.\n\n  ```js\n  // jQuery\n  $.parseHTML(htmlString);\n\n  // Natif\n  function parseHTML(string) {\n    const tmp = document.implementation.createHTMLDocument();\n    tmp.body.innerHTML = string;\n    return tmp.body.children;\n  }\n  ```\n\n  + parseJSON\n\n  Prend une chaine JSON correctement formatée et retourne la valeur JavaScript résultante.\n\n  ```js\n  // jQuery\n  $.parseJSON(str);\n\n  // Natif\n  JSON.parse(str);\n  ```\n\n**[⬆ remonter](#table-of-contents)**\n\n## Promesses\n\nUne promesse représente le résultat éventuel d'une opération asynchrone. jQuery a sa propre manière de traiter les promesses. JavaScript natif implémente une API minimale et légère afin de traiter les promesses en accord avec les spécifications [Promises/A+](http://promises-aplus.github.io/promises-spec/).\n\n\n- [7.1](#7.1) <a name='7.1'></a> done, fail, always\n\n  `done` est appelée quand une promesse est résolue, `fail` est appelée quand une promesse est rejetée et `always` est appelée quand une promesse n'est ni résolue ni rejetée.\n\n  ```js\n  // jQuery\n  $promise.done(doneCallback).fail(failCallback).always(alwaysCallback)\n\n  // Natif\n  promise.then(doneCallback, failCallback).then(alwaysCallback, alwaysCallback)\n  ```\n\n- [7.2](#7.2) <a name='7.2'></a> when\n\n  `when` est utilisée pour traiter de multiples promesses. Elle sera résolue quand toutes les promesses le seront, and rejetée si au moins une est rejetée.\n\n  ```js\n  // jQuery\n  $.when($promise1, $promise2).done((promise1Result, promise2Result) => {})\n\n  // Natif\n  Promise.all([$promise1, $promise2]).then([promise1Result, promise2Result] => {});\n  ```\n\n- [7.3](#7.3) <a name='7.3'></a> Deferred\n\n  Deferred est un moyen de créer une promesse.\n\n  ```js\n  // jQuery\n  function asyncFunc() {\n    var d = new $.Deferred();\n    setTimeout(function() {\n      if(true) {\n        d.resolve('some_value_compute_asynchronously');\n      } else {\n        d.reject('failed');\n      }\n    }, 1000);\n    return d.promise();\n  }\n\n  // Natif\n  function asyncFunc() {\n    return new Promise((resolve, reject) => {\n      setTimeout(function() {\n        if (true) {\n          resolve('some_value_compute_asynchronously');\n        } else {\n          reject('failed');\n        }\n      }, 1000);\n    });\n  }\n\n  // Avec deferred\n  function defer() {\n    let resolve, reject;\n    let promise = new Promise(function() {\n      resolve = arguments[0];\n      reject = arguments[1];\n    });\n    return { resolve, reject, promise };\n  }\n  function asyncFunc() {\n    var d = defer();\n    setTimeout(function() {\n      if(true) {\n        d.resolve('some_value_compute_asynchronously');\n      } else {\n        d.reject('failed');\n      }\n    }, 1000);\n    return d.promise;\n  }\n  ```\n\n**[⬆ remonter](#table-of-contents)**\n\n## Animation\n\n- [8.1](#8.1) <a name='8.1'></a> Show & Hide\n\n  ```js\n  // jQuery\n  $el.show();\n  $el.hide();\n\n  // Natif\n  //Pour plus de détails à propos de la méthode show, merci de se référer à https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L363\n\n  el.style.display = ''|'inline'|'inline-block'|'inline-table'|'block';\n  el.style.display = 'none';\n  ```\n\n- [8.2](#8.2) <a name='8.2'></a> Toggle\n\n  Affiche ou cache un élément.\n\n  ```js\n  // jQuery\n  $el.toggle();\n\n  // Natif\n  if (el.ownerDocument.defaultView.getComputedStyle(el, null).display === 'none') {\n    el.style.display = ''|'inline'|'inline-block'|'inline-table'|'block';\n  }\n  else {\n    el.style.display = 'none';\n  }\n  ```\n\n- [8.3](#8.3) <a name='8.3'></a> FadeIn & FadeOut\n\n  ```js\n  // jQuery\n  $el.fadeIn(3000);\n  $el.fadeOut(3000);\n\n  // Natif\n  el.style.transition = 'opacity 3s';\n  // fadeIn\n  el.style.opacity = '1';\n  // fadeOut\n  el.style.opacity = '0';\n  ```\n\n- [8.4](#8.4) <a name='8.4'></a> FadeTo\n\n  Ajuste l'opacité d'un élément.\n\n  ```js\n  // jQuery\n  $el.fadeTo('slow',0.15);\n  // Natif\n  el.style.transition = 'opacity 3s'; // assume que 'slow' vaut 3 seconds\n  el.style.opacity = '0.15';\n  ```\n\n- [8.5](#8.5) <a name='8.5'></a> FadeToggle\n\n  Affiche ou cache un élément en animant son opacité.\n\n  ```js\n  // jQuery\n  $el.fadeToggle();\n\n  // Natif\n  el.style.transition = 'opacity 3s';\n  let { opacity } = el.ownerDocument.defaultView.getComputedStyle(el, null);\n  if (opacity === '1') {\n    el.style.opacity = '0';\n  }\n  else {\n    el.style.opacity = '1';\n  }\n  ```\n\n- [8.6](#8.6) <a name='8.6'></a> SlideUp & SlideDown\n\n  ```js\n  // jQuery\n  $el.slideUp();\n  $el.slideDown();\n\n  // Natif\n  let originHeight = '100px';\n  el.style.transition = 'height 3s';\n  // slideUp\n  el.style.height = '0px';\n  // slideDown\n  el.style.height = originHeight;\n  ```\n\n- [8.7](#8.7) <a name='8.7'></a> SlideToggle\n\n  Affiche ou cache un élément en le faisant glisser.\n\n  ```js\n  // jQuery\n  $el.slideToggle();\n\n  // Natif\n  let originHeight = '100px';\n  el.style.transition = 'height 3s';\n  let { height } = el.ownerDocument.defaultView.getComputedStyle(el, null);\n  if (parseInt(height, 10) === 0) {\n    el.style.height = originHeight;\n  }\n  else {\n   el.style.height = '0px';\n  }\n  ```\n\n- [8.8](#8.8) <a name='8.8'></a> Animate\n\n  Réalise une animation personnaliée à partir d'une collection de propriétés CSS.\n\n  ```js\n  // jQuery\n  $el.animate({params}, speed);\n\n  // Natif\n  el.style.transition = 'all' + speed;\n  Object.keys(params).forEach(function(key) {\n    el.style[key] = params[key];\n  })\n  ```\n\n## Alternatives\n\n* [You Might Not Need jQuery](http://youmightnotneedjquery.com/) - Des exemples sur comment faire un simple évènement, ajax etc avec du javascript pur.\n* [npm-dom](http://github.com/npm-dom) et [webmodules](http://github.com/webmodules) - Modules DOM sur NPM.\n\n## Traductions\n\n* [한국어](./README.ko-KR.md)\n* [简体中文](./README.zh-CN.md)\n* [Bahasa Melayu](./README-my.md)\n* [Bahasa Indonesia](./README-id.md)\n* [Português(PT-BR)](./README.pt-BR.md)\n* [Tiếng Việt Nam](./README-vi.md)\n* [Español](./README-es.md)\n* [Русский](./README-ru.md)\n* [Türkçe](./README-tr.md)\n* [Italian](./README-it.md)\n* [Français](./README-fr.md)\n\n## Navigateurs compatibles\n\n![Chrome](https://raw.github.com/alrra/browser-logos/master/chrome/chrome_48x48.png) | ![Firefox](https://raw.github.com/alrra/browser-logos/master/firefox/firefox_48x48.png) | ![IE](https://raw.github.com/alrra/browser-logos/master/internet-explorer/internet-explorer_48x48.png) | ![Opera](https://raw.github.com/alrra/browser-logos/master/opera/opera_48x48.png) | ![Safari](https://raw.github.com/alrra/browser-logos/master/safari/safari_48x48.png)\n--- | --- | --- | --- | --- |\nPlus récente ✔ | Plus récente ✔ | 10+ ✔ | Plus récente ✔ | 6.1+ ✔ |\n\n# Licence\n\nMIT\n"
  },
  {
    "path": "README-id.md",
    "content": "## Anda tidak memerlukan jQuery\n\nPerkembangan environment frontend sangatlah pesat, dimana banyak browser sudah mengimplementasikan DOM/BOM APIs dengan baik. Kita tidak perlu lagi belajar jQuery dari nol untuk keperluan memanipulasi DOM atau events. Secara bersamaan; dengan berterimakasih kepada library frontend terkini seperti React, Angular dan Vue; Memanipulasi DOM secara langsung telah menjadi anti-pattern atau sesuatu yang tidak perlu dilakukan lagi. Dengan kata lain, jQuery sekarang menjadi semakin tidak diperlukan. Projek ini memberikan informasi mengenai metode alternatif dari jQuery untuk implementasi Native dengan support untuk browser IE 10+.\n\n\n## Daftar Isi\n\n1. [Terjemahan](#translation)\n1. [Query Selector](#query-selector)\n1. [CSS & Style](#css-style)\n1. [DOM Manipulation](#dom-manipulation)\n1. [Ajax](#ajax)\n1. [Events](#events)\n1. [Utilities](#utilities)\n1. [Browser Support](#browser-yang-di-support)\n\n## Terjemahan\n\n* [한국어](./README.ko-KR.md)\n* [正體中文](./README.zh-TW.md)\n* [简体中文](./README.zh-CN.md)\n* [Bahasa Melayu](./README-my.md)\n* [Bahasa Indonesia](./README-id.md)\n* [Português(PT-BR)](./README.pt-BR.md)\n* [Tiếng Việt Nam](./README-vi.md)\n* [Español](./README-es.md)\n* [Русский](./README-ru.md)\n* [Кыргызча](./README-kg.md)\n* [Türkçe](./README-tr.md)\n* [Italiano](./README-it.md)\n* [Français](./README-fr.md)\n* [日本語](./README-ja.md)\n* [Polski](./README-pl.md)\n\n## Query Selector\n\nUntuk selector-selector umum seperti class, id atau attribute, kita dapat menggunakan `document.querySelector` atau `document.querySelectorAll` sebagai pengganti. Perbedaan diantaranya adalah:\n* `document.querySelector` mengembalikan elemen pertama yang cocok\n* `document.querySelectorAll` mengembalikan semua elemen yang cocok sebagai NodeList. Hasilnya bisa dikonversikan menjadi Array `[].slice.call(document.querySelectorAll(selector) || []);`\n* Bila tidak ada hasil balik pada elemen yang cocok, jQuery akan mengembalikan `[]` sedangkan DOM API akan mengembalikan `null`. Mohon diperhatikan mengenai Null Pointer Exception. Anda juga bisa menggunakan operator `||` untuk set nilai awal jika hasil pencarian tidak ditemukan : `document.querySelectorAll(selector) || []`\n\n> Perhatian: `document.querySelector` dan `document.querySelectorAll` sedikit **LAMBAT**. Silahkan menggunakan `getElementById`, `document.getElementsByClassName` atau `document.getElementsByTagName` jika anda menginginkan tambahan performa.\n\n- [1.0](#1.0) <a name='1.0'></a> Query by selector\n\n  ```js\n  // jQuery\n  $('selector');\n\n  // Native\n  document.querySelectorAll('selector');\n  ```\n\n- [1.1](#1.1) <a name='1.1'></a> Query by class\n\n  ```js\n  // jQuery\n  $('.class');\n\n  // Native\n  document.querySelectorAll('.class');\n\n  // or\n  document.getElementsByClassName('class');\n  ```\n\n- [1.2](#1.2) <a name='1.2'></a> Query by id\n\n  ```js\n  // jQuery\n  $('#id');\n\n  // Native\n  document.querySelector('#id');\n\n  // or\n  document.getElementById('id');\n  ```\n\n- [1.3](#1.3) <a name='1.3'></a> Query menggunakan attribute\n\n  ```js\n  // jQuery\n  $('a[target=_blank]');\n\n  // Native\n  document.querySelectorAll('a[target=_blank]');\n  ```\n\n- [1.4](#1.4) <a name='1.4'></a> Pencarian.\n\n  + Mencari nodes\n\n    ```js\n    // jQuery\n    $el.find('li');\n\n    // Native\n    el.querySelectorAll('li');\n    ```\n\n  + Mencari body\n\n    ```js\n    // jQuery\n    $('body');\n\n    // Native\n    document.body;\n    ```\n\n  + Mencari Attribute\n\n    ```js\n    // jQuery\n    $el.attr('foo');\n\n    // Native\n    e.getAttribute('foo');\n    ```\n\n  + Mencari data attribute\n\n    ```js\n    // jQuery\n    $el.data('foo');\n\n    // Native\n    // gunakan getAttribute\n    el.getAttribute('data-foo');\n    // anda juga bisa menggunakan `dataset` bila anda perlu support IE 11+\n    el.dataset['foo'];\n    ```\n\n- [1.5](#1.5) <a name='1.5'></a> Elemen-elemen Sibling/Previous/Next\n\n  + Elemen Sibling\n\n    ```js\n    // jQuery\n    $el.siblings();\n\n    // Native\n    [].filter.call(el.parentNode.children, function(child) {\n      return child !== el;\n    });\n    ```\n\n  + Elemen Previous\n\n    ```js\n    // jQuery\n    $el.prev();\n\n    // Native\n    el.previousElementSibling;\n\n    ```\n\n  + Elemen Next\n\n    ```js\n    // next\n    $el.next();\n    el.nextElementSibling;\n    ```\n\n- [1.6](#1.6) <a name='1.6'></a> Closest\n\n  Mengembalikan elemen sama yang digunakan dari selector pertama, dengan cara mencari elemen-sekarang sampai ke document.\n\n  ```js\n  // jQuery\n  $el.closest(queryString);\n\n  // Native\n  function closest(el, selector) {\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    while (el) {\n      if (matchesSelector.call(el, selector)) {\n        return el;\n      } else {\n        el = el.parentElement;\n      }\n    }\n    return null;\n  }\n  ```\n\n- [1.7](#1.7) <a name='1.7'></a> Parents Until\n\n  Digunakan untuk mendapatkan \"ancestor\" dari setiap elemen yang ditemukan. Namun tidak termasuk elemen-sekarang yang sudah didapat dari pencarian oleh selector, DOM node, atau object jQuery.\n\n  ```js\n  // jQuery\n  $el.parentsUntil(selector, filter);\n\n  // Native\n  function parentsUntil(el, selector, filter) {\n    const result = [];\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    // match start from parent\n    el = el.parentElement;\n    while (el && !matchesSelector.call(el, selector)) {\n      if (!filter) {\n        result.push(el);\n      } else {\n        if (matchesSelector.call(el, filter)) {\n          result.push(el);\n        }\n      }\n      el = el.parentElement;\n    }\n    return result;\n  }\n  ```\n\n- [1.8](#1.8) <a name='1.8'></a> Form\n\n  + Input/Textarea\n\n    ```js\n    // jQuery\n    $('#my-input').val();\n\n    // Native\n    document.querySelector('#my-input').value;\n    ```\n\n  + Get index of e.currentTarget between `.radio`\n\n    ```js\n    // jQuery\n    $(e.currentTarget).index('.radio');\n\n    // Native\n    [].indexOf.call(document.querySelectAll('.radio'), e.currentTarget);\n    ```\n\n- [1.9](#1.9) <a name='1.9'></a> Iframe Contents\n\n  `$('iframe').contents()` mengembalikan `contentDocument`\n\n  + Iframe contents\n\n    ```js\n    // jQuery\n    $iframe.contents();\n\n    // Native\n    iframe.contentDocument;\n    ```\n\n  + Iframe Query\n\n    ```js\n    // jQuery\n    $iframe.contents().find('.css');\n\n    // Native\n    iframe.contentDocument.querySelectorAll('.css');\n    ```\n\n**[⬆ back to top](#daftar-isi)**\n\n## CSS Style\n\n- [2.1](#2.1) <a name='2.1'></a> CSS\n\n  + Get style\n\n    ```js\n    // jQuery\n    $el.css(\"color\");\n\n    // Native\n    // PERHATIAN: ada bug disini, dimana fungsi ini akan mengembalikan nilai 'auto' bila nilai dari atribut style adalah 'auto'\n    const win = el.ownerDocument.defaultView;\n    // null artinya tidak mengembalikan pseudo styles\n    win.getComputedStyle(el, null).color;\n    ```\n\n  + Set style\n\n    ```js\n    // jQuery\n    $el.css({ color: \"#ff0011\" });\n\n    // Native\n    el.style.color = '#ff0011';\n    ```\n\n  + Get/Set Styles\n\n    Mohon dicatat jika anda ingin mengubah style secara bersamaan, anda dapat menemukan referensi di metode [setStyles](https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L194) pada package oui-dom-utils\n\n  + Add class\n\n    ```js\n    // jQuery\n    $el.addClass(className);\n\n    // Native\n    el.classList.add(className);\n    ```\n\n  + Remove class\n\n    ```js\n    // jQuery\n    $el.removeClass(className);\n\n    // Native\n    el.classList.remove(className);\n    ```\n\n  + has class\n\n    ```js\n    // jQuery\n    $el.hasClass(className);\n\n    // Native\n    el.classList.contains(className);\n    ```\n\n  + Toggle class\n\n    ```js\n    // jQuery\n    $el.toggleClass(className);\n\n    // Native\n    el.classList.toggle(className);\n    ```\n\n- [2.2](#2.2) <a name='2.2'></a> Width & Height\n\n  Secara teori, width dan height identik, contohnya Height:\n\n  + Window height\n\n    ```js\n    // window height\n    $(window).height();\n    // without scrollbar, behaves like jQuery\n    window.document.documentElement.clientHeight;\n    // with scrollbar\n    window.innerHeight;\n    ```\n\n  + Document height\n\n    ```js\n    // jQuery\n    $(document).height();\n\n    // Native\n    document.documentElement.scrollHeight;\n    ```\n\n  + Element height\n\n    ```js\n    // jQuery\n    $el.height();\n\n    // Native\n    function getHeight(el) {\n      const styles = this.getComputedStyles(el);\n      const height = el.offsetHeight;\n      const borderTopWidth = parseFloat(styles.borderTopWidth);\n      const borderBottomWidth = parseFloat(styles.borderBottomWidth);\n      const paddingTop = parseFloat(styles.paddingTop);\n      const paddingBottom = parseFloat(styles.paddingBottom);\n      return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;\n    }\n    // accurate to integer（when `border-box`, it's `height - border`; when `content-box`, it's `height + padding`）\n    el.clientHeight;\n    // accurate to decimal（when `border-box`, it's `height`; when `content-box`, it's `height + padding + border`）\n    el.getBoundingClientRect().height;\n    ```\n\n- [2.3](#2.3) <a name='2.3'></a> Position & Offset\n\n  + Position\n\n    ```js\n    // jQuery\n    $el.position();\n\n    // Native\n    { left: el.offsetLeft, top: el.offsetTop }\n    ```\n\n  + Offset\n\n    ```js\n    // jQuery\n    $el.offset();\n\n    // Native\n    function getOffset (el) {\n      const box = el.getBoundingClientRect();\n\n      return {\n        top: box.top + window.pageYOffset - document.documentElement.clientTop,\n        left: box.left + window.pageXOffset - document.documentElement.clientLeft\n      }\n    }\n    ```\n\n- [2.4](#2.4) <a name='2.4'></a> Scroll Top\n\n  ```js\n  // jQuery\n  $(window).scrollTop();\n\n  // Native\n  (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;\n  ```\n\n**[⬆ back to top](#daftar-isi)**\n\n## DOM Manipulation\n\n- [3.1](#3.1) <a name='3.1'></a> Remove\n  ```js\n  // jQuery\n  $el.remove();\n\n  // Native\n  el.parentNode.removeChild(el);\n  ```\n\n- [3.2](#3.2) <a name='3.2'></a> Text\n\n  + Get text\n\n    ```js\n    // jQuery\n    $el.text();\n\n    // Native\n    el.textContent;\n    ```\n\n  + Set text\n\n    ```js\n    // jQuery\n    $el.text(string);\n\n    // Native\n    el.textContent = string;\n    ```\n\n- [3.3](#3.3) <a name='3.3'></a> HTML\n\n  + Get HTML\n\n    ```js\n    // jQuery\n    $el.html();\n\n    // Native\n    el.innerHTML;\n    ```\n\n  + Set HTML\n\n    ```js\n    // jQuery\n    $el.html(htmlString);\n\n    // Native\n    el.innerHTML = htmlString;\n    ```\n\n- [3.4](#3.4) <a name='3.4'></a> Append\n\n  Menambahkan elemen-anak setelah anak terakhir dari elemen-parent\n\n  ```js\n  // jQuery\n  $el.append(\"<div id='container'>hello</div>\");\n\n  // Native\n  let newEl = document.createElement('div');\n  newEl.setAttribute('id', 'container');\n  newEl.innerHTML = 'hello';\n  el.appendChild(newEl);\n  ```\n\n- [3.5](#3.5) <a name='3.5'></a> Prepend\n\n  ```js\n  // jQuery\n  $el.prepend(\"<div id='container'>hello</div>\");\n\n  // Native\n  let newEl = document.createElement('div');\n  newEl.setAttribute('id', 'container');\n  newEl.innerHTML = 'hello';\n  el.insertBefore(newEl, el.firstChild);\n  ```\n\n- [3.6](#3.6) <a name='3.6'></a> insertBefore\n\n  Memasukkan node baru sebelum elemen yang dipilih.\n\n  ```js\n  // jQuery\n  $newEl.insertBefore(queryString);\n\n  // Native\n  const target = document.querySelector(queryString);\n  target.parentNode.insertBefore(newEl, target);\n  ```\n\n- [3.7](#3.7) <a name='3.7'></a> insertAfter\n\n  Memasukkan node baru sesudah elemen yang dipilih.\n\n  ```js\n  // jQuery\n  $newEl.insertAfter(queryString);\n\n  // Native\n  const target = document.querySelector(queryString);\n  target.parentNode.insertBefore(newEl, target.nextSibling);\n  ```\n\n**[⬆ back to top](#daftar-isi)**\n\n## Ajax\n\nGantikan dengan [fetch](https://github.com/camsong/fetch-ie8) dan [fetch-jsonp](https://github.com/camsong/fetch-jsonp)\n\n**[⬆ back to top](#daftar-isi)**\n\n## Events\n\nUntuk penggantian secara menyeluruh dengan namespace dan delegation, lihat ke https://github.com/oneuijs/oui-dom-events\n\n- [5.1](#5.1) <a name='5.1'></a> Bind event dengan menggunakan on\n\n  ```js\n  // jQuery\n  $el.on(eventName, eventHandler);\n\n  // Native\n  el.addEventListener(eventName, eventHandler);\n  ```\n\n- [5.2](#5.2) <a name='5.2'></a> Unbind event dengan menggunakan off\n\n  ```js\n  // jQuery\n  $el.off(eventName, eventHandler);\n\n  // Native\n  el.removeEventListener(eventName, eventHandler);\n  ```\n\n- [5.3](#5.3) <a name='5.3'></a> Trigger\n\n  ```js\n  // jQuery\n  $(el).trigger('custom-event', {key1: 'data'});\n\n  // Native\n  if (window.CustomEvent) {\n    const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});\n  } else {\n    const event = document.createEvent('CustomEvent');\n    event.initCustomEvent('custom-event', true, true, {key1: 'data'});\n  }\n\n  el.dispatchEvent(event);\n  ```\n\n**[⬆ back to top](#daftar-isi)**\n\n## Utilities\n\n- [6.1](#6.1) <a name='6.1'></a> isArray\n\n  ```js\n  // jQuery\n  $.isArray(range);\n\n  // Native\n  Array.isArray(range);\n  ```\n\n- [6.2](#6.2) <a name='6.2'></a> Trim\n\n  ```js\n  // jQuery\n  $.trim(string);\n\n  // Native\n  string.trim();\n  ```\n\n- [6.3](#6.3) <a name='6.3'></a> Object Assign\n\n  Extend, use object.assign polyfill https://github.com/ljharb/object.assign\n\n  ```js\n  // jQuery\n  $.extend({}, defaultOpts, opts);\n\n  // Native\n  Object.assign({}, defaultOpts, opts);\n  ```\n\n- [6.4](#6.4) <a name='6.4'></a> Contains\n\n  ```js\n  // jQuery\n  $.contains(el, child);\n\n  // Native\n  el !== child && el.contains(child);\n  ```\n\n**[⬆ back to top](#daftar-isi)**\n\n## Browser yang di Support\n\n![Chrome](https://raw.github.com/alrra/browser-logos/master/chrome/chrome_48x48.png) | ![Firefox](https://raw.github.com/alrra/browser-logos/master/firefox/firefox_48x48.png) | ![IE](https://raw.github.com/alrra/browser-logos/master/internet-explorer/internet-explorer_48x48.png) | ![Opera](https://raw.github.com/alrra/browser-logos/master/opera/opera_48x48.png) | ![Safari](https://raw.github.com/alrra/browser-logos/master/safari/safari_48x48.png)\n--- | --- | --- | --- | --- |\nLatest ✔ | Latest ✔ | 10+ ✔ | Latest ✔ | 6.1+ ✔ |\n\n# License\n\nMIT\n"
  },
  {
    "path": "README-it.md",
    "content": "## Non hai bisogno di jQuery\n\nIl mondo del Frontend si evolve rapidamente oggigiorno, i browsers moderni hanno gia' implementato un'ampia gamma di DOM/BOM API soddisfacenti. Non dobbiamo imparare jQuery dalle fondamenta per la manipolazione del DOM o di eventi. Nel frattempo, grazie al prevalicare di librerie per il frontend come React, Angular a Vue, manipolare il DOM direttamente diventa un anti-pattern, di consequenza jQuery non e' mai stato meno importante. Questo progetto sommarizza la maggior parte dei metodi e implementazioni alternative a jQuery, con il supporto di IE 10+.\n\n## Tabella contenuti\n\n1. [Traduzioni](#traduzioni)\n1. [Query Selector](#query-selector)\n1. [CSS & Style](#css--style)\n1. [Manipolazione DOM](#manipolazione-dom)\n1. [Ajax](#ajax)\n1. [Eventi](#eventi)\n1. [Utilities](#utilities)\n1. [Alternative](#alternative)\n1. [Supporto Browsers](#supporto-browsers)\n\n## Traduzioni\n\n* [한국어](./README.ko-KR.md)\n* [正體中文](./README.zh-TW.md)\n* [简体中文](./README.zh-CN.md)\n* [Bahasa Melayu](./README-my.md)\n* [Bahasa Indonesia](./README-id.md)\n* [Português(PT-BR)](./README.pt-BR.md)\n* [Tiếng Việt Nam](./README-vi.md)\n* [Español](./README-es.md)\n* [Русский](./README-ru.md)\n* [Кыргызча](./README-kg.md)\n* [Türkçe](./README-tr.md)\n* [Italiano](./README-it.md)\n* [Français](./README-fr.md)\n* [日本語](./README-ja.md)\n* [Polski](./README-pl.md)\n\n## Query Selector\n\nAl posto di comuni selettori come class, id o attributi possiamo usare `document.querySelector` o `document.querySelectorAll` per sostituzioni. La differenza risiede in:\n* `document.querySelector` restituisce il primo elemento combiaciante\n* `document.querySelectorAll` restituisce tutti gli elementi combiacianti della NodeList. Puo' essere convertito in Array usando `[].slice.call(document.querySelectorAll(selector) || []);`\n* Se nessun elemento combiacia, jQuery restituitirebbe `[]` li' dove il DOM API ritornera' `null`. Prestate attenzione al Null Pointer Exception. Potete anche usare `||` per settare valori di default se non trovato, come `document.querySelectorAll(selector) || []`\n\n> Notare: `document.querySelector` e `document.querySelectorAll` sono abbastanza **SLOW**, provate ad usare `getElementById`, `document.getElementsByClassName` o `document.getElementsByTagName` se volete avere un bonus in termini di performance.\n\n- [1.0](#1.0) <a name='1.0'></a> Query da selettore\n\n  ```js\n  // jQuery\n  $('selector');\n\n  // Nativo\n  document.querySelectorAll('selector');\n  ```\n\n- [1.1](#1.1) <a name='1.1'></a> Query da classe\n\n  ```js\n  // jQuery\n  $('.class');\n\n  // Nativo\n  document.querySelectorAll('.class');\n\n  // or\n  document.getElementsByClassName('class');\n  ```\n\n- [1.2](#1.2) <a name='1.2'></a> Query da id\n\n  ```js\n  // jQuery\n  $('#id');\n\n  // Nativo\n  document.querySelector('#id');\n\n  // o\n  document.getElementById('id');\n  ```\n\n- [1.3](#1.3) <a name='1.3'></a> Query da attributo\n\n  ```js\n  // jQuery\n  $('a[target=_blank]');\n\n  // Nativo\n  document.querySelectorAll('a[target=_blank]');\n  ```\n\n- [1.4](#1.4) <a name='1.4'></a> Trovare qualcosa.\n\n  + Trovare nodes\n\n    ```js\n    // jQuery\n    $el.find('li');\n\n    // Nativo\n    el.querySelectorAll('li');\n    ```\n\n  + Trovare body\n\n    ```js\n    // jQuery\n    $('body');\n\n    // Nativo\n    document.body;\n    ```\n\n  + Trovare Attributi\n\n    ```js\n    // jQuery\n    $el.attr('foo');\n\n    // Nativo\n    e.getAttribute('foo');\n    ```\n\n  + Trovare attributo data\n\n    ```js\n    // jQuery\n    $el.data('foo');\n\n    // Nativo\n    // using getAttribute\n    el.getAttribute('data-foo');\n    // potete usare `dataset` solo se supportate IE 11+\n    el.dataset['foo'];\n    ```\n\n- [1.5](#1.5) <a name='1.5'></a> Fratelli/Precedento/Successivo Elemento\n\n  + Elementi fratelli\n\n    ```js\n    // jQuery\n    $el.siblings();\n\n    // Nativo\n    [].filter.call(el.parentNode.children, function(child) {\n      return child !== el;\n    });\n    ```\n\n  + Elementi precedenti\n\n    ```js\n    // jQuery\n    $el.prev();\n\n    // Nativo\n    el.previousElementSibling;\n    ```\n\n  + Elementi successivi\n\n    ```js\n    // jQuery\n    $el.next();\n\n    // Nativo\n    el.nextElementSibling;\n    ```\n\n- [1.6](#1.6) <a name='1.6'></a> Il piu' vicino\n\n  Restituisce il primo elementi combiaciante il selettore fornito, attraversando dall'elemento corrente fino al document .\n\n  ```js\n  // jQuery\n  $el.closest(queryString);\n\n  // Nativo - Solo ultimo, NO IE\n  el.closest(selector);\n\n  // Nativo - IE10+\n  function closest(el, selector) {\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    while (el) {\n      if (matchesSelector.call(el, selector)) {\n        return el;\n      } else {\n        el = el.parentElement;\n      }\n    }\n    return null;\n  }\n  ```\n\n- [1.7](#1.7) <a name='1.7'></a> Fino a parenti\n\n  Ottiene il parente di ogni elemento nel set corrente di elementi combiacianti, fino a ma non incluso, l'elemento combiaciante il selettorer, DOM node, o jQuery object.\n\n  ```js\n  // jQuery\n  $el.parentsUntil(selector, filter);\n\n  // Nativo\n  function parentsUntil(el, selector, filter) {\n    const result = [];\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    // il match parte dal parente\n    el = el.parentElement;\n    while (el && !matchesSelector.call(el, selector)) {\n      if (!filter) {\n        result.push(el);\n      } else {\n        if (matchesSelector.call(el, filter)) {\n          result.push(el);\n        }\n      }\n      el = el.parentElement;\n    }\n    return result;\n  }\n  ```\n\n- [1.8](#1.8) <a name='1.8'></a> Form\n\n  + Input/Textarea\n\n    ```js\n    // jQuery\n    $('#my-input').val();\n\n    // Native\n    document.querySelector('#my-input').value;\n    ```\n\n  + Get index of e.currentTarget between `.radio`\n\n    ```js\n    // jQuery\n    $(e.currentTarget).index('.radio');\n\n    // Nativo\n    [].indexOf.call(document.querySelectAll('.radio'), e.currentTarget);\n    ```\n\n- [1.9](#1.9) <a name='1.9'></a> Iframe Contents\n\n  `$('iframe').contents()` restituisce `contentDocument` per questo specifico iframe\n\n  + Iframe contenuti\n\n    ```js\n    // jQuery\n    $iframe.contents();\n\n    // Nativo\n    iframe.contentDocument;\n    ```\n\n  + Iframe Query\n\n    ```js\n    // jQuery\n    $iframe.contents().find('.css');\n\n    // Nativo\n    iframe.contentDocument.querySelectorAll('.css');\n    ```\n\n**[⬆ back to top](#table-of-contents)**\n\n## CSS & Style\n\n- [2.1](#2.1) <a name='2.1'></a> CSS\n\n  + Ottenere style\n\n    ```js\n    // jQuery\n    $el.css(\"color\");\n\n    // Nativo\n    // NOTA: Bug conosciuto, restituira' 'auto' se il valore di style e' 'auto'\n    const win = el.ownerDocument.defaultView;\n    // null significa che non restituira' lo psuedo style\n    win.getComputedStyle(el, null).color;\n    ```\n\n  + Settare style\n\n    ```js\n    // jQuery\n    $el.css({ color: \"#ff0011\" });\n\n    // Nativo\n    el.style.color = '#ff0011';\n    ```\n\n  + Ottenere/Settare Styles\n\n    Nota che se volete settare styles multipli in una sola volta, potete riferire [setStyles](https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L194) metodo in oui-dom-utils package.\n\n\n  + Aggiungere classe\n\n    ```js\n    // jQuery\n    $el.addClass(className);\n\n    // Nativo\n    el.classList.add(className);\n    ```\n\n  + Rimouvere class\n\n    ```js\n    // jQuery\n    $el.removeClass(className);\n\n    // Nativo\n    el.classList.remove(className);\n    ```\n\n  + has class\n\n    ```js\n    // jQuery\n    $el.hasClass(className);\n\n    // Nativo\n    el.classList.contains(className);\n    ```\n\n  + Toggle class\n\n    ```js\n    // jQuery\n    $el.toggleClass(className);\n\n    // Nativo\n    el.classList.toggle(className);\n    ```\n\n- [2.2](#2.2) <a name='2.2'></a> Width & Height\n\n  Width e Height sono teoricamente identici, prendendo Height come esempio:\n\n  + Window height\n\n    ```js\n    // window height\n    $(window).height();\n    // senza scrollbar, si comporta comporta jQuery\n    window.document.documentElement.clientHeight;\n    // con scrollbar\n    window.innerHeight;\n    ```\n\n  + Document height\n\n    ```js\n    // jQuery\n    $(document).height();\n\n    // Nativo\n    document.documentElement.scrollHeight;\n    ```\n\n  + Element height\n\n    ```js\n    // jQuery\n    $el.height();\n\n    // Nativo\n    function getHeight(el) {\n      const styles = this.getComputedStyles(el);\n      const height = el.offsetHeight;\n      const borderTopWidth = parseFloat(styles.borderTopWidth);\n      const borderBottomWidth = parseFloat(styles.borderBottomWidth);\n      const paddingTop = parseFloat(styles.paddingTop);\n      const paddingBottom = parseFloat(styles.paddingBottom);\n      return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;\n    }\n    // preciso a intero（quando `border-box`, e' `height - border`; quando `content-box`, e' `height + padding`）\n    el.clientHeight;\n    // preciso a decimale（quando `border-box`, e' `height`; quando `content-box`, e' `height + padding + border`）\n    el.getBoundingClientRect().height;\n    ```\n\n- [2.3](#2.3) <a name='2.3'></a> Position & Offset\n\n  + Position\n\n    ```js\n    // jQuery\n    $el.position();\n\n    // Nativo\n    { left: el.offsetLeft, top: el.offsetTop }\n    ```\n\n  + Offset\n\n    ```js\n    // jQuery\n    $el.offset();\n\n    // Nativo\n    function getOffset (el) {\n      const box = el.getBoundingClientRect();\n\n      return {\n        top: box.top + window.pageYOffset - document.documentElement.clientTop,\n        left: box.left + window.pageXOffset - document.documentElement.clientLeft\n      }\n    }\n    ```\n\n- [2.4](#2.4) <a name='2.4'></a> Scroll Top\n\n  ```js\n  // jQuery\n  $(window).scrollTop();\n\n  // Nativo\n  (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;\n  ```\n\n**[⬆ back to top](#table-of-contents)**\n\n## Manipolazione DOM\n\n- [3.1](#3.1) <a name='3.1'></a> Remove\n  ```js\n  // jQuery\n  $el.remove();\n\n  // Nativo\n  el.parentNode.removeChild(el);\n  ```\n\n- [3.2](#3.2) <a name='3.2'></a> Text\n\n  + Get text\n\n    ```js\n    // jQuery\n    $el.text();\n\n    // Nativo\n    el.textContent;\n    ```\n\n  + Set text\n\n    ```js\n    // jQuery\n    $el.text(string);\n\n    // Nativo\n    el.textContent = string;\n    ```\n\n- [3.3](#3.3) <a name='3.3'></a> HTML\n\n  + Ottenere HTML\n\n    ```js\n    // jQuery\n    $el.html();\n\n    // Nativo\n    el.innerHTML;\n    ```\n\n  + Settare HTML\n\n    ```js\n    // jQuery\n    $el.html(htmlString);\n\n    // Nativo\n    el.innerHTML = htmlString;\n    ```\n\n- [3.4](#3.4) <a name='3.4'></a> Append\n\n  appendere elemento figlio dopo l'ultimo elemento figlio del genitore\n\n  ```js\n  // jQuery\n  $el.append(\"<div id='container'>hello</div>\");\n\n  // Nativo\n  el.insertAdjacentHTML(\"beforeend\",\"<div id='container'>hello</div>\");\n  ```\n\n- [3.5](#3.5) <a name='3.5'></a> Prepend\n\n  ```js\n  // jQuery\n  $el.prepend(\"<div id='container'>hello</div>\");\n\n  // Nativo\n  el.insertAdjacentHTML(\"afterbegin\",\"<div id='container'>hello</div>\");\n  ```\n\n- [3.6](#3.6) <a name='3.6'></a> insertBefore\n\n  Inserire un nuovo node dopo l'elmento selezionato\n\n  ```js\n  // jQuery\n  $newEl.insertBefore(queryString);\n\n  // Nativo\n  const target = document.querySelector(queryString);\n  target.parentNode.insertBefore(newEl, target);\n  ```\n\n- [3.7](#3.7) <a name='3.7'></a> insertAfter\n\n  Insert a new node after the selected elements\n\n  ```js\n  // jQuery\n  $newEl.insertAfter(queryString);\n\n  // Nativo\n  const target = document.querySelector(queryString);\n  target.parentNode.insertBefore(newEl, target.nextSibling);\n  ```\n\n- [3.8](#3.8) <a name='3.8'></a> is\n\n  Restituisce `true` se combacia con l'elemento selezionato\n\n  ```js\n  // jQuery - Notare `is` funziona anche con `function` o `elements` non di importanza qui\n  $el.is(selector);\n\n  // Nativo\n  el.matches(selector);\n  ```\n\n**[⬆ back to top](#table-of-contents)**\n\n## Ajax\n\nSostituire con [fetch](https://github.com/camsong/fetch-ie8) and [fetch-jsonp](https://github.com/camsong/fetch-jsonp)\n\n**[⬆ back to top](#table-of-contents)**\n\n## Eventi\n\nPer una completa sostituzione con namespace e delegation, riferire a https://github.com/oneuijs/oui-dom-events\n\n- [5.1](#5.1) <a name='5.1'></a> Bind un evento con on\n\n  ```js\n  // jQuery\n  $el.on(eventName, eventHandler);\n\n  // Nativo\n  el.addEventListener(eventName, eventHandler);\n  ```\n\n- [5.2](#5.2) <a name='5.2'></a> Unbind an event with off\n\n  ```js\n  // jQuery\n  $el.off(eventName, eventHandler);\n\n  // Nativo\n  el.removeEventListener(eventName, eventHandler);\n  ```\n\n- [5.3](#5.3) <a name='5.3'></a> Trigger\n\n  ```js\n  // jQuery\n  $(el).trigger('custom-event', {key1: 'data'});\n\n  // Nativo\n  if (window.CustomEvent) {\n    const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});\n  } else {\n    const event = document.createEvent('CustomEvent');\n    event.initCustomEvent('custom-event', true, true, {key1: 'data'});\n  }\n\n  el.dispatchEvent(event);\n  ```\n\n**[⬆ back to top](#table-of-contents)**\n\n## Utilities\n\n- [6.1](#6.1) <a name='6.1'></a> isArray\n\n  ```js\n  // jQuery\n  $.isArray(range);\n\n  // Nativo\n  Array.isArray(range);\n  ```\n\n- [6.2](#6.2) <a name='6.2'></a> Trim\n\n  ```js\n  // jQuery\n  $.trim(string);\n\n  // Nativo\n  string.trim();\n  ```\n\n- [6.3](#6.3) <a name='6.3'></a> Object Assign\n\n  Extend, usa object.assign polyfill https://github.com/ljharb/object.assign\n\n  ```js\n  // jQuery\n  $.extend({}, defaultOpts, opts);\n\n  // Nativo\n  Object.assign({}, defaultOpts, opts);\n  ```\n\n- [6.4](#6.4) <a name='6.4'></a> Contains\n\n  ```js\n  // jQuery\n  $.contains(el, child);\n\n  // Nativo\n  el !== child && el.contains(child);\n  ```\n\n**[⬆ back to top](#table-of-contents)**\n\n## Alternative\n\n* [Forse non hai bisogno di jQuery](http://youmightnotneedjquery.com/) - Esempi di come creare eventi comuni, elementi, ajax etc usando puramente javascript.\n* [npm-dom](http://github.com/npm-dom) e [webmodules](http://github.com/webmodules) - Organizzazione dove puoi trovare moduli per il DOM individuale su NPM\n\n## Supporto Browsers\n\n![Chrome](https://raw.github.com/alrra/browser-logos/master/chrome/chrome_48x48.png) | ![Firefox](https://raw.github.com/alrra/browser-logos/master/firefox/firefox_48x48.png) | ![IE](https://raw.github.com/alrra/browser-logos/master/internet-explorer/internet-explorer_48x48.png) | ![Opera](https://raw.github.com/alrra/browser-logos/master/opera/opera_48x48.png) | ![Safari](https://raw.github.com/alrra/browser-logos/master/safari/safari_48x48.png)\n--- | --- | --- | --- | --- |\nUltimo ✔ | Ultimo ✔ | 10+ ✔ | Ultimo ✔ | 6.1+ ✔ |\n\n# Licenza\n\nMIT\n"
  },
  {
    "path": "README-ja.md",
    "content": "## jQueryは必要ない（You Don't Need jQuery）\r\n\r\n\r\nフロントエンドの開発環境はめまぐるしく進化していて、最近のブラウザでは十分な質、量のDOM/BOM APIが実装されています。もうDOM操作やイベント処理のためにjQueryを覚える必要はありません。また、ReactやAngularそしてVueなどのフロントエンドライブラリの流行により、DOMを直接操作することはアンチパターンとなりました。jQueryはそれほど重要ではなくなったのです。このプロジェクトは、jQueryでの書き方の代わりとなるネイティブでの書き方(IE10以上)をまとめます。\r\n\r\n## 目次\r\n\r\n1. [Translations](#translations)\r\n1. [セレクタ](#セレクタ)\r\n1. [CSSとスタイル](#cssとスタイル)\r\n1. [DOM操作](#dom操作)\r\n1. [Ajax](#ajax)\r\n1. [イベント](#イベント)\r\n1. [ユーティリティ関数](#ユーティリティ関数)\r\n1. [Promise](#promise)\r\n1. [アニメーション](#アニメーション)\r\n1. [選択肢](#選択肢)\r\n1. [対応ブラウザ](#対応ブラウザ)\r\n\r\n\r\n## Translations\r\n\r\n* [한국어](./README.ko-KR.md)\r\n* [正體中文](./README.zh-TW.md)\r\n* [简体中文](./README.zh-CN.md)\r\n* [Bahasa Melayu](./README-my.md)\r\n* [Bahasa Indonesia](./README-id.md)\r\n* [Português(PT-BR)](./README.pt-BR.md)\r\n* [Tiếng Việt Nam](./README-vi.md)\r\n* [Español](./README-es.md)\r\n* [Русский](./README-ru.md)\r\n* [Кыргызча](./README-kg.md)\r\n* [Türkçe](./README-tr.md)\r\n* [Italiano](./README-it.md)\r\n* [Français](./README-fr.md)\r\n* [Polski](./README-pl.md)\r\n\r\n## セレクタ\r\n\r\nclassセレクタ、idセレクタ、属性セレクタのような主要セレクタは`document.querySelector`もしくは`document.querySelectorAll`で代替できます。\r\n\r\njQueryのセレクタと比べて以下の違いがあります。\r\n\r\n* `document.querySelector`はセレクタにマッチする最初のエレメントを返す\r\n* `document.querySelectorAll`はセレクタにマッチする全てのエレメントのNodeListを返す。`Array.prototype.slice.call(document.querySelectorAll(selector) || []);`で配列に変換できる。\r\n* セレクタにマッチする要素がなかった場合、jQueryは`[]`を返すが、DOM APIは`null`を返す。したがってNull Pointer Exceptionに注意する必要がある。もしくは`document.querySelectorAll(selector) || []`のように`||`を使ってデフォルト値を指定しておく。\r\n\r\n> 注意：`document.querySelector`と`document.querySelectorAll`はかなり**遅い**です。もし、パフォーマンスが必要なら`document.getElementById`や`document.getElementsByClassName`、`document.getElementsByTagName`を使ってください。\r\n\r\n\r\n- [1.0](#1.0) <a name='1.0'></a> セレクタによる選択\r\n\r\n  ```js\r\n  // jQuery\r\n  $('selector');\r\n\r\n  // Native\r\n  document.querySelectorAll('selector');\r\n  ```\r\n\r\n- [1.1](#1.1) <a name='1.1'></a> クラス名による選択\r\n\r\n  ```js\r\n  // jQuery\r\n  $('.class');\r\n\r\n  // Native\r\n  document.querySelectorAll('.class');\r\n\r\n  // or\r\n  document.getElementsByClassName('class');\r\n  ```\r\n\r\n- [1.2](#1.2) <a name='1.2'></a> idによる選択\r\n\r\n  ```js\r\n  // jQuery\r\n  $('#id');\r\n\r\n  // Native\r\n  document.querySelector('#id');\r\n\r\n  // or\r\n  document.getElementById('id');\r\n  ```\r\n\r\n- [1.3](#1.3) <a name='1.3'></a> 属性による選択\r\n\r\n  ```js\r\n  // jQuery\r\n  $('a[target=_blank]');\r\n\r\n  // Native\r\n  document.querySelectorAll('a[target=_blank]');\r\n  ```\r\n\r\n- [1.4](#1.4) <a name='1.4'></a> 子孫要素の選択\r\n\r\n  ```js\r\n  // jQuery\r\n  $el.find('li');\r\n\r\n  // Native\r\n  el.querySelectorAll('li');\r\n  ```  \r\n\r\n- [1.5](#1.5) <a name='1.5'></a> 兄弟要素の選択\r\n\r\n  + 兄弟要素\r\n\r\n    ```js\r\n    // jQuery\r\n    $el.siblings();\r\n\r\n    // Native\r\n    Array.prototype.filter.call(el.parentNode.children, function(child) {\r\n      return child !== el;\r\n    });\r\n    ```\r\n\r\n  + 直前の兄弟要素\r\n\r\n    ```js\r\n    // jQuery\r\n    $el.prev();\r\n\r\n    // Native\r\n    el.previousElementSibling;\r\n    ```\r\n\r\n  + 直後の兄弟要素\r\n\r\n    ```js\r\n    // jQuery\r\n    $el.next();\r\n\r\n    // Native\r\n    el.nextElementSibling;\r\n    ```\r\n\r\n- [1.6](#1.6) <a name='1.6'></a> 祖先要素の選択\r\n\r\n  指定要素からdocument方向に遡って走査し、セレクタにマッチする最初の祖先要素を返します。\r\n\r\n  ```js\r\n  // jQuery\r\n  $el.closest(selector);\r\n\r\n  // Native - 最近のブラウザのみ。IEでは動かない。\r\n  el.closest(selector);\r\n\r\n  // Native - IE10+\r\n  function closest(el, selector) {\r\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\r\n\r\n    while (el) {\r\n      if (matchesSelector.call(el, selector)) {\r\n        return el;\r\n      } else {\r\n        el = el.parentElement;\r\n      }\r\n    }\r\n    return null;\r\n  }\r\n  ```\r\n\r\n- [1.7](#1.7) <a name='1.7'></a> Parents Until\r\n\r\n  指定要素からセレクタにマッチする祖先要素までdocument方向に遡って走査し、フィルタにマッチする祖先要素を全て取得します。ただし、セレクタで指定された要素は含みません。\r\n\r\n  ```js\r\n  // jQuery\r\n  $el.parentsUntil(selector, filter);\r\n\r\n  // Native\r\n  function parentsUntil(el, selector, filter) {\r\n    const result = [];\r\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\r\n\r\n    // parentから走査を開始する\r\n    el = el.parentElement;\r\n    while (el && !matchesSelector.call(el, selector)) {\r\n      if (!filter) {\r\n        result.push(el);\r\n      } else {\r\n        if (matchesSelector.call(el, filter)) {\r\n          result.push(el);\r\n        }\r\n      }\r\n      el = el.parentElement;\r\n    }\r\n    return result;\r\n  }\r\n  ```\r\n\r\n- [1.8](#1.8) <a name='1.8'></a> フォーム\r\n\r\n  + input/textarea\r\n\r\n    ```js\r\n    // jQuery\r\n    $('#my-input').val();\r\n\r\n    // Native\r\n    document.querySelector('#my-input').value;\r\n    ```\r\n\r\n  + `.radio`内での`e.currentTarget`のインデックスを返す\r\n\r\n    ```js\r\n    // jQuery\r\n    $(e.currentTarget).index('.radio');\r\n\r\n    // Native\r\n    Array.prototype.indexOf.call(document.querySelectorAll('.radio'), e.currentTarget);\r\n    ```\r\n\r\n- [1.9](#1.9) <a name='1.9'></a> iframeのコンテンツ\r\n\r\n  `$('iframe').contents()`はiframeの`contentDocument`を返します。\r\n\r\n  + Iframe contents\r\n\r\n    ```js\r\n    // jQuery\r\n    $iframe.contents();\r\n\r\n    // Native\r\n    iframe.contentDocument;\r\n    ```\r\n\r\n  + Iframe Query\r\n\r\n    ```js\r\n    // jQuery\r\n    $iframe.contents().find('.css');\r\n\r\n    // Native\r\n    iframe.contentDocument.querySelectorAll('.css');\r\n    ```\r\n\r\n- [1.10](#1.10) <a name='1.10'></a> bodyを取得する\r\n\r\n  ```js\r\n  // jQuery\r\n  $('body');\r\n\r\n  // Native\r\n  document.body;\r\n  ```\r\n\r\n- [1.11](#1.11) <a name='1.11'></a> 属性の設定、取得\r\n\r\n  + 属性値を取得する\r\n\r\n    ```js\r\n    // jQuery\r\n    $el.attr('foo');\r\n\r\n    // Native\r\n    el.getAttribute('foo');\r\n    ```\r\n  + 属性値を設定する\r\n\r\n    ```js\r\n    // jQuery, DOMを変化させずメモリ上で動作することに注意\r\n    $el.attr('foo', 'bar');\r\n\r\n    // Native\r\n    el.setAttribute('foo', 'bar');\r\n    ```\r\n\r\n  + `data-`属性を取得する\r\n\r\n    ```js\r\n    // jQuery\r\n    $el.data('foo');\r\n\r\n    // Native (`getAttribute`を使う)\r\n    el.getAttribute('data-foo');\r\n    // Native (IE11以上のサポートなら`dataset`を使ってもよい)\r\n    el.dataset['foo'];\r\n    ```\r\n\r\n**[⬆ back to top](#目次)**\r\n\r\n## CSSとスタイル\r\n\r\n- [2.1](#2.1) <a name='2.1'></a> CSS\r\n\r\n  + スタイルを取得する\r\n\r\n    ```js\r\n    // jQuery\r\n    $el.css(\"color\");\r\n\r\n    // Native\r\n    // NOTE: 既知のバグ デフォルト値が'auto'の場合、値が指定されていなくても'auto'が返る\r\n    const win = el.ownerDocument.defaultView;\r\n    // nullは疑似要素でないことを示している\r\n    win.getComputedStyle(el, null).color;\r\n    ```\r\n\r\n  + スタイルを設定する\r\n\r\n    ```js\r\n    // jQuery\r\n    $el.css({ color: \"#ff0011\" });\r\n\r\n    // Native\r\n    el.style.color = '#ff0011';\r\n    ```\r\n\r\n  + スタイルを一括取得、一括設定する\r\n\r\n\t複数のスタイルを一括で設定したいなら、oui-dom-utilsの[setStyles](https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L194)関数を参考にすると良いでしょう。\r\n\r\n  + クラスを追加する\r\n    ```js\r\n    // jQuery\r\n    $el.addClass(className);\r\n\r\n    // Native\r\n    el.classList.add(className);\r\n    ```\r\n\r\n  + クラスを削除する\r\n\r\n    ```js\r\n    // jQuery\r\n    $el.removeClass(className);\r\n\r\n    // Native\r\n    el.classList.remove(className);\r\n    ```\r\n\r\n  + クラスの有無をチェックする\r\n\r\n    ```js\r\n    // jQuery\r\n    $el.hasClass(className);\r\n\r\n    // Native\r\n    el.classList.contains(className);\r\n    ```\r\n\r\n  + クラスの有無を切り替える\r\n\r\n    ```js\r\n    // jQuery\r\n    $el.toggleClass(className);\r\n\r\n    // Native\r\n    el.classList.toggle(className);\r\n    ```\r\n\r\n- [2.2](#2.2) <a name='2.2'></a> 横幅と高さ\r\n\r\n  横幅(width)と高さ(height)の書き方はほぼ同じなので、高さ（height）の例のみを示します。\r\n\r\n  + ウィンドウの高さ\r\n\r\n    ```js\r\n    // window height\r\n    $(window).height();\r\n    // jQueryのようにスクロールバーを除いた高さ\r\n    window.document.documentElement.clientHeight;\r\n    // スクロールバーを含めるなら\r\n    window.innerHeight;\r\n    ```\r\n\r\n  + ドキュメントの高さ\r\n\r\n    ```js\r\n    // jQuery\r\n    $(document).height();\r\n\r\n    // Native\r\n    document.documentElement.scrollHeight;\r\n    ```\r\n\r\n  + エレメントの高さ\r\n\r\n    ```js\r\n    // jQuery\r\n    $el.height();\r\n\r\n    // Native\r\n    function getHeight(el) {\r\n      const styles = window.getComputedStyle(el);\r\n      const height = el.offsetHeight;\r\n      const borderTopWidth = parseFloat(styles.borderTopWidth);\r\n      const borderBottomWidth = parseFloat(styles.borderBottomWidth);\r\n      const paddingTop = parseFloat(styles.paddingTop);\r\n      const paddingBottom = parseFloat(styles.paddingBottom);\r\n      return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;\r\n    }\r\n    // integerで取得（`border-box`の時は`height - border`が、`content-box`の時は`height + padding`が返る）\r\n    el.clientHeight;\r\n    // decimalで取得（`border-box`の時は`height`が、`content-box`の時は`height + padding + border`が返る）\r\n    el.getBoundingClientRect().height;\r\n    ```\r\n\r\n- [2.3](#2.3) <a name='2.3'></a> PositionとOffset\r\n\r\n  + Position\r\n\r\n    offset parentを起点として、エレメントの座標を取得する。\r\n\r\n    ```js\r\n    // jQuery\r\n    $el.position();\r\n\r\n    // Native\r\n    { left: el.offsetLeft, top: el.offsetTop }\r\n    ```\r\n\r\n  + Offset\r\n\r\n    documentを起点として、エレメントの座標を取得する。\r\n\r\n    ```js\r\n    // jQuery\r\n    $el.offset();\r\n\r\n    // Native\r\n    function getOffset (el) {\r\n      const box = el.getBoundingClientRect();\r\n\r\n      return {\r\n        top: box.top + window.pageYOffset - document.documentElement.clientTop,\r\n        left: box.left + window.pageXOffset - document.documentElement.clientLeft\r\n      }\r\n    }\r\n    ```\r\n\r\n- [2.4](#2.4) <a name='2.4'></a> スクロール位置\r\n\r\n  縦スクロールバーの位置を取得する。\r\n\r\n  ```js\r\n  // jQuery\r\n  $(window).scrollTop();\r\n\r\n  // Native\r\n  (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;\r\n  ```\r\n\r\n**[⬆ back to top](#目次)**\r\n\r\n## DOM操作\r\n\r\n- [3.1](#3.1) <a name='3.1'></a> Remove\r\n\r\n  DOMからエレメントを削除する。\r\n\r\n  ```js\r\n  // jQuery\r\n  $el.remove();\r\n\r\n  // Native\r\n  el.parentNode.removeChild(el);\r\n  ```\r\n\r\n- [3.2](#3.2) <a name='3.2'></a> Text\r\n\r\n  + テキストを取得する\r\n\r\n    子孫エレメントも含めた全テキスト内容を取得する。\r\n\r\n    ```js\r\n    // jQuery\r\n    $el.text();\r\n\r\n    // Native\r\n    el.textContent;\r\n    ```\r\n\r\n  + テキストを設定する\r\n\r\n    エレメントのコンテントを指定されたテキストに設定する。\r\n\r\n    ```js\r\n    // jQuery\r\n    $el.text(string);\r\n\r\n    // Native\r\n    el.textContent = string;\r\n    ```\r\n\r\n- [3.3](#3.3) <a name='3.3'></a> HTML\r\n\r\n  + HTMLを取得する\r\n\r\n    ```js\r\n    // jQuery\r\n    $el.html();\r\n\r\n    // Native\r\n    el.innerHTML;\r\n    ```\r\n\r\n  + HTMLを設定する\r\n\r\n    ```js\r\n    // jQuery\r\n    $el.html(htmlString);\r\n\r\n    // Native\r\n    el.innerHTML = htmlString;\r\n    ```\r\n\r\n- [3.4](#3.4) <a name='3.4'></a> Append\r\n\r\n  最後の子要素としてエレメントを追加する。\r\n\r\n  ```js\r\n  // jQuery\r\n  $el.append(\"<div id='container'>hello</div>\");\r\n\r\n  // Native\r\n  el.insertAdjacentHTML(\"beforeend\",\"<div id='container'>hello</div>\");\r\n  ```\r\n\r\n- [3.5](#3.5) <a name='3.5'></a> Prepend\r\n\r\n  最初の子要素としてエレメントを追加する。\r\n\r\n  ```js\r\n  // jQuery\r\n  $el.prepend(\"<div id='container'>hello</div>\");\r\n\r\n  // Native\r\n  el.insertAdjacentHTML(\"afterbegin\",\"<div id='container'>hello</div>\");\r\n  ```\r\n\r\n- [3.6](#3.6) <a name='3.6'></a> insertBefore\r\n\r\n  指定要素の後ろに新しいノードを追加する。\r\n\r\n  ```js\r\n  // jQuery\r\n  $newEl.insertBefore(queryString);\r\n\r\n  // Native\r\n  const target = document.querySelector(queryString);\r\n  target.parentNode.insertBefore(newEl, target);\r\n  ```\r\n\r\n- [3.7](#3.7) <a name='3.7'></a> insertAfter\r\n\r\n  指定要素の前に新しいノードを追加する。\r\n\r\n  ```js\r\n  // jQuery\r\n  $newEl.insertAfter(queryString);\r\n\r\n  // Native\r\n  const target = document.querySelector(queryString);\r\n  target.parentNode.insertBefore(newEl, target.nextSibling);\r\n  ```\r\n\r\n- [3.8](#3.8) <a name='3.8'></a> is\r\n\r\n  セレクタにマッチするなら`true`を返す。\r\n\r\n  ```js\r\n  // is関数は複数エレメントや関数にも対応するが、matches関数は単一エレメントのみに使える\r\n  $el.is(selector);\r\n\r\n  // Native\r\n  el.matches(selector);\r\n  ```\r\n- [3.9](#3.9) <a name='3.9'></a> clone\r\n\r\n  エレメントのディープコピーを生成する。\r\n\r\n  ```js\r\n  // jQuery\r\n  $el.clone();\r\n\r\n  // Native\r\n  el.cloneNode();\r\n\r\n  //  パラメータには`true`が渡され、深い複製を生成します。\r\n  // 浅い複製を生成するには、`false`を渡します。\r\n  ```\r\n\r\n- [3.10](#3.10) <a name='3.10'></a> empty\r\n\r\n  全ての子ノードを削除する。\r\n\r\n  ```js\r\n  // jQuery\r\n  $el.empty();\r\n\r\n  // Native\r\n  el.innerHTML = '';\r\n  ```\r\n\r\n- [3.11](#3.11) <a name='3.11'></a> wrap\r\n\r\n  エレメントを指定のHTMLで囲む。\r\n\r\n  ```js\r\n  // jQuery\r\n  $('.inner').wrap('<div class=\"wrapper\"></div>');\r\n\r\n  // Native\r\n  Array.prototype.slice.call(document.querySelectorAll('.inner')).forEach(function(el){\r\n    var wrapper = document.createElement('div');\r\n    wrapper.className = 'wrapper';\r\n    el.parentNode.insertBefore(wrapper, el);\r\n    el.parentNode.removeChild(el);\r\n    wrapper.appendChild(el);\r\n  });\r\n  ```\r\n\r\n- [3.12](#3.12) <a name='3.12'></a> unwrap\r\n\r\n  セレクタにマッチしたエレメントの親要素をDOMから削除する。マッチしたエレメント自体は残す。\r\n\r\n  ```js\r\n  // jQuery\r\n  $('.inner').unwrap();\r\n\r\n  // Native\r\n  Array.prototype.slice.call(document.querySelectorAll('.inner')).forEach(function(el){\r\n    Array.prototype.slice.call(el.childNodes).forEach(function(child){\r\n      el.parentNode.insertBefore(child, el);\r\n    });\r\n    el.parentNode.removeChild(el);\r\n  });\r\n  ```\r\n\r\n- [3.13](#3.13) <a name='3.13'></a> replaceWith\r\n\r\n  セレクタにマッチしたエレメントの内容を与えられた内容に置き換える。\r\n\r\n  ```js\r\n  // jQuery\r\n  $('.inner').replaceWith('<div class=\"outer\"></div>');\r\n\r\n  // Native\r\n  Array.prototype.slice.call(document.querySelectorAll('.inner')).forEach(function(el){\r\n    var outer = document.createElement('div');\r\n    outer.className = 'outer';\r\n    el.parentNode.insertBefore(outer, el);\r\n    el.parentNode.removeChild(el);\r\n  });\r\n  ```\r\n\r\n\r\n**[⬆ back to top](#目次)**\r\n\r\n## Ajax\r\n\r\n[Fetch API](https://fetch.spec.whatwg.org/)はXMLHttpRequestを置き換える新たな規格です。ChromeとFirefoxで動きます。レガシーなブラウザでもpolyfillを使えます。\r\n\r\nIE9以上なら[github/fetch](http://github.com/github/fetch)、IE8以上なら[fetch-ie8](https://github.com/camsong/fetch-ie8/)、jsonpを利用したいなら[fetch-jsonp](https://github.com/camsong/fetch-jsonp)を試してみてください。\r\n\r\n- [4.1](#4.1) <a name='4.1'></a> マッチしたエレメントをサーバから取得したHTMLに置き換える。\r\n\r\n  ```js\r\n  // jQuery\r\n  $(selector).load(url, completeCallback)\r\n\r\n  // Native\r\n  fetch(url).then(data => data.text()).then(data => {\r\n    document.querySelector(selector).innerHTML = data\r\n  }).then(completeCallback)\r\n  ```\r\n\r\n**[⬆ back to top](#目次)**\r\n\r\n## イベント\r\n\r\n名前空間(namespace)と委譲（delegation）を利用した完全な代替手段が必要なら、 https://github.com/oneuijs/oui-dom-events を参照してください。\r\n\r\n- [5.0](#5.0) <a name='5.0'></a> ドキュメントが読み込まれたときの動作(`DOMContentLoaded`)\r\n\r\n  ```js\r\n  // jQuery\r\n  $(document).ready(eventHandler);\r\n\r\n  // Native\r\n  // DOMContentLoadedがすでに完了していないか確認する\r\n  if (document.readyState !== 'loading') {\r\n    eventHandler();\r\n  } else {\r\n    document.addEventListener('DOMContentLoaded', eventHandler);\r\n  }\r\n  ```\r\n\r\n- [5.1](#5.1) <a name='5.1'></a> イベントをバインドする(`on`)\r\n\r\n  ```js\r\n  // jQuery\r\n  $el.on(eventName, eventHandler);\r\n\r\n  // Native\r\n  el.addEventListener(eventName, eventHandler);\r\n  ```\r\n\r\n- [5.2](#5.2) <a name='5.2'></a> イベントをアンバインドする(`off`)\r\n\r\n  ```js\r\n  // jQuery\r\n  $el.off(eventName, eventHandler);\r\n\r\n  // Native\r\n  el.removeEventListener(eventName, eventHandler);\r\n  ```\r\n\r\n- [5.3](#5.3) <a name='5.3'></a> イベントを発火させる(`trigger`)\r\n\r\n  ```js\r\n  // jQuery\r\n  $(el).trigger('custom-event', {key1: 'data'});\r\n\r\n  // Native\r\n  if (window.CustomEvent) {\r\n    const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});\r\n  } else {\r\n    const event = document.createEvent('CustomEvent');\r\n    event.initCustomEvent('custom-event', true, true, {key1: 'data'});\r\n  }\r\n\r\n  el.dispatchEvent(event);\r\n  ```\r\n\r\n**[⬆ back to top](#目次)**\r\n\r\n## ユーティリティ関数\r\n\r\n殆どのユーティリティ関数はネイティブのAPIで置き換えることができます。表記の一貫性やパフォーマンスを重視した他のライブラリを使う選択肢もあります。[lodash](https://lodash.com)がおすすめです。\r\n\r\n\r\n- [6.1](#6.1) <a name='6.1'></a> 基本的なユーティリティ関数\r\n\r\n  + isArray\r\n\r\n  配列かどうか判定する。\r\n\r\n  ```js\r\n  // jQuery\r\n  $.isArray(array);\r\n\r\n  // Native\r\n  Array.isArray(array);\r\n  ```\r\n\r\n  + isWindow\r\n\r\n  windowかどうか判定する。\r\n\r\n  ```js\r\n  // jQuery\r\n  $.isWindow(obj);\r\n\r\n  // Native\r\n  function isWindow(obj) {\r\n    return obj != null && obj === obj.window;\r\n  }\r\n  ```\r\n\r\n  + inArray\r\n\r\n  配列の中で、指定された値が最初に現れたインデックスを返す。（見つからなければ-1を返す）。\r\n\r\n  ```js\r\n  // jQuery\r\n  $.inArray(item, array);\r\n\r\n  // Native\r\n  Array.indexOf(item);\r\n  ```\r\n\r\n  + isNumeric\r\n\r\n  数値かどうか判定する。\r\n  `typeof`を使ってください。ライブラリを使う場合、`typeof`は正確でない場合があります。\r\n\r\n  ```js\r\n  // jQuery\r\n  $.isNumeric(item);\r\n\r\n  // Native\r\n  function isNumeric(item) {\r\n    return typeof item === 'number';\r\n  }\r\n  ```\r\n\r\n  + isFunction\r\n\r\n  JavaScript関数オブジェクトかどうか判定する。\r\n\r\n  ```js\r\n  // jQuery\r\n  $.isFunction(item);\r\n\r\n  // Native\r\n  function isFunction(item) {\r\n    return typeof item === 'function';\r\n  }\r\n  ```\r\n\r\n  + isEmptyObject\r\n\r\n  空のオブジェクトである（列挙できる要素がない）か判定する。\r\n\r\n  ```js\r\n  // jQuery\r\n  $.isEmptyObject(obj);\r\n\r\n  // Native\r\n  function isEmptyObject(obj) {\r\n    for (let key in obj) {\r\n      return false;\r\n    }\r\n    return true;\r\n  }\r\n  ```\r\n\r\n  + isPlainObject\r\n\r\n  `{}`もしくは`new Object`で生成されたオブジェクトであるか判定する。\r\n\r\n  ```js\r\n  // jQuery\r\n  $.isPlainObject(obj);\r\n\r\n  // Native\r\n  function isPlainObject(obj) {\r\n    if (typeof (obj) !== 'object' || obj.nodeType || obj != null && obj === obj.window) {\r\n      return false;\r\n    }\r\n\r\n    if (obj.constructor &&\r\n        !{}.hasOwnProperty.call(obj.constructor.prototype, 'isPrototypeOf')) {\r\n      return false;\r\n    }\r\n\r\n    return true;\r\n  }\r\n  ```\r\n\r\n  + extend\r\n\r\n  二つ以上のオブジェクトをマージする。\r\n  `object.assign`はECMAScript6のAPIですが、[polyfill](https://github.com/ljharb/object.assign)も利用できます。\r\n\r\n  ```js\r\n  // jQuery\r\n  $.extend({}, defaultOpts, opts);\r\n\r\n  // Native\r\n  Object.assign({}, defaultOpts, opts);\r\n  ```\r\n\r\n  + trim\r\n\r\n  前後の空白を除去する。\r\n\r\n  ```js\r\n  // jQuery\r\n  $.trim(string);\r\n\r\n  // Native\r\n  string.trim();\r\n  ```\r\n\r\n  + map\r\n\r\n  配列やオブジェクトを新しい配列に変換する。\r\n\r\n  ```js\r\n  // jQuery\r\n  $.map(array, function(value, index) {\r\n  });\r\n\r\n  // Native\r\n  array.map(function(value, index) {\r\n  });\r\n  ```\r\n\r\n  + each\r\n\r\n  配列やオブジェクトに対して繰り返し処理を行う。\r\n\r\n  ```js\r\n  // jQuery\r\n  $.each(array, function(value, index) {\r\n  });\r\n\r\n  // Native\r\n  array.forEach(function(value, index) {\r\n  });\r\n  ```\r\n\r\n  + grep\r\n\r\n  フィルター関数に合致したエレメントだけを返す。\r\n\r\n  ```js\r\n  // jQuery\r\n  $.grep(array, function(value, index) {\r\n  });\r\n\r\n  // Native\r\n  array.filter(function(value, index) {\r\n  });\r\n  ```\r\n\r\n  + type\r\n\r\n  JavaScript「クラス」名を判定します。\r\n\r\n  ```js\r\n  // jQuery\r\n  $.type(obj);\r\n\r\n  // Native\r\n  Object.prototype.toString.call(obj).replace(/^\\[object (.+)\\]$/, '$1').toLowerCase();\r\n  ```\r\n\r\n  + merge\r\n\r\n  二つの配列をマージする。\r\n\r\n  ```js\r\n  // jQuery\r\n  $.merge(array1, array2);\r\n\r\n  // Native\r\n  // 重複した要素は削除されない\r\n  function merge() {\r\n    return Array.prototype.concat.apply([], arguments)\r\n  }\r\n  ```\r\n\r\n  + now\r\n\r\n  現在の時刻を返す。\r\n\r\n  ```js\r\n  // jQuery\r\n  $.now();\r\n\r\n  // Native\r\n  Date.now();\r\n  ```\r\n\r\n  + proxy\r\n\r\n  関数内で実行されるthisを任意のオブジェクトに変更する。\r\n\r\n  ```js\r\n  // jQuery\r\n  $.proxy(fn, context);\r\n\r\n  // Native\r\n  fn.bind(context);\r\n  ```\r\n\r\n  + makeArray\r\n\r\n  配列形式のオブジェクトを配列に変換する。\r\n\r\n  ```js\r\n  // jQuery\r\n  $.makeArray(arrayLike);\r\n\r\n  // Native\r\n  Array.prototype.slice.call(arrayLike);\r\n\r\n  // ES6なら\r\n  Array.from(arrayLike);\r\n  ```\r\n\r\n- [6.2](#6.2) <a name='6.2'></a> contains\r\n\r\n  ある要素が他の要素の子孫であるか判定する。\r\n\r\n  ```js\r\n  // jQuery\r\n  $.contains(el, child);\r\n\r\n  // Native\r\n  el !== child && el.contains(child);\r\n  ```\r\n\r\n- [6.3](#6.3) <a name='6.3'></a> globaleval\r\n\r\n  JavaScriptコードをグローバル空間で実行する。\r\n\r\n  ```js\r\n  // jQuery\r\n  $.globaleval(code);\r\n\r\n  // Native\r\n  function Globaleval(code) {\r\n    let script = document.createElement('script');\r\n    script.text = code;\r\n\r\n    document.head.appendChild(script).parentNode.removeChild(script);\r\n  }\r\n\r\n  // evalはcurrentコンテキストで実行される。$.globalevalのコンテキストはグローバルである。\r\n  eval(code);\r\n  ```\r\n\r\n- [6.4](#6.4) <a name='6.4'></a> parse\r\n\r\n  + parseHTML\r\n\r\n  文字列をDOM nodeの配列として返します。\r\n\r\n  ```js\r\n  // jQuery\r\n  $.parseHTML(htmlString);\r\n\r\n  // Native\r\n  function parseHTML(string) {\r\n    const tmp = document.implementation.createHTMLDocument();\r\n    tmp.body.innerHTML = string;\r\n    return tmp.body.children;\r\n  }\r\n  ```\r\n\r\n  + parseJSON\r\n\r\n  JSON文字列をJavaScriptに変換します。\r\n\r\n  ```js\r\n  // jQuery\r\n  $.parseJSON(str);\r\n\r\n  // Native\r\n  JSON.parse(str);\r\n  ```\r\n\r\n**[⬆ back to top](#目次)**\r\n\r\n## Promise\r\n\r\npromiseは非同期処理の最終的な処理結果を表します。jQueryにはpromiseを扱うための独自の方法があります。ネイティブのJavaScriptでは[Promises/A+](http://promises-aplus.github.io/promises-spec/)規格に則り、薄く、最小限のAPIを実装しています。\r\n\r\n- [7.1](#7.1) <a name='7.1'></a> done, fail, always\r\n\r\n  `done`はpromiseが成功(resolved)したとき、`fall`は失敗(rejected)したとき、`always`はどちらの場合も呼び出されます。\r\n\r\n  ```js\r\n  // jQuery\r\n  $promise.done(doneCallback).fail(failCallback).always(alwaysCallback)\r\n\r\n  // Native\r\n  promise.then(doneCallback, failCallback).then(alwaysCallback, alwaysCallback)\r\n  ```\r\n\r\n- [7.2](#7.2) <a name='7.2'></a> when\r\n\r\n  `when`は複数のpromiseを扱うときに使います。すべてのpromiseの結果が返ったときに成功となります（失敗が含まれてても成功となります）。\r\n\r\n  ```js\r\n  // jQuery\r\n  $.when($promise1, $promise2).done((promise1Result, promise2Result) => {})\r\n\r\n  // Native\r\n  Promise.all([$promise1, $promise2]).then([promise1Result, promise2Result] => {});\r\n  ```\r\n\r\n- [7.3](#7.3) <a name='7.3'></a> Deferred\r\n\r\n  `Deferred`はpromiseを作成する方法の一つです。\r\n\r\n  ```js\r\n  // jQuery\r\n  function asyncFunc() {\r\n    var d = new $.Deferred();\r\n    setTimeout(function() {\r\n      if(true) {\r\n        d.resolve('some_value_compute_asynchronously');\r\n      } else {\r\n        d.reject('failed');\r\n      }\r\n    }, 1000);\r\n    return d.promise();\r\n  }\r\n\r\n  // Native\r\n  function asyncFunc() {\r\n    return new Promise((resolve, reject) => {\r\n      setTimeout(function() {\r\n        if (true) {\r\n          resolve('some_value_compute_asynchronously');\r\n        } else {\r\n          reject('failed');\r\n        }\r\n      }, 1000);\r\n    });\r\n  }\r\n\r\n  // Deferred way\r\n  function defer() {\r\n    let resolve, reject;\r\n    let promise = new Promise(function() {\r\n      resolve = arguments[0];\r\n      reject = arguments[1];\r\n    });\r\n    return { resolve, reject, promise };\r\n  }\r\n  function asyncFunc() {\r\n    var d = defer();\r\n    setTimeout(function() {\r\n      if(true) {\r\n        d.resolve('some_value_compute_asynchronously');\r\n      } else {\r\n        d.reject('failed');\r\n      }\r\n    }, 1000);\r\n    return d.promise;\r\n  }\r\n  ```\r\n\r\n**[⬆ back to top](#目次)**\r\n\r\n## アニメーション\r\n\r\n- [8.1](#8.1) <a name='8.1'></a> show、hide\r\n\r\n  ```js\r\n  // jQuery\r\n  $el.show();\r\n  $el.hide();\r\n\r\n  // Native\r\n  // show関数の詳細を見たければ次のURLを参照してください\r\n  // https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L363\r\n  el.style.display = ''|'inline'|'inline-block'|'inline-table'|'block';\r\n  el.style.display = 'none';\r\n  ```\r\n\r\n- [8.2](#8.2) <a name='8.2'></a> toggle\r\n\r\n  エレメントが表示されていないなら表示し、表示されているなら非表示にします。\r\n\r\n  ```js\r\n  // jQuery\r\n  $el.toggle();\r\n\r\n  // Native\r\n  if (el.ownerDocument.defaultView.getComputedStyle(el, null).display === 'none') {\r\n    el.style.display = ''|'inline'|'inline-block'|'inline-table'|'block';\r\n  }\r\n  else {\r\n    el.style.display = 'none';\r\n  }\r\n  ```\r\n\r\n- [8.3](#8.3) <a name='8.3'></a> fadeIn、fadeOut\r\n\r\n  ```js\r\n  // jQuery\r\n  $el.fadeIn(3000);\r\n  $el.fadeOut(3000);\r\n\r\n  // Native\r\n  el.style.transition = 'opacity 3s';\r\n  // fadeIn\r\n  el.style.opacity = '1';\r\n  // fadeOut\r\n  el.style.opacity = '0';\r\n  ```\r\n\r\n- [8.4](#8.4) <a name='8.4'></a> fadeTo\r\n\r\n  エレメントのopacityを調整してください。\r\n\r\n  ```js\r\n  // jQuery\r\n  $el.fadeTo('slow',0.15);\r\n  // Native\r\n  el.style.transition = 'opacity 3s'; // 'slow'は3秒だということにしている\r\n  el.style.opacity = '0.15';\r\n  ```\r\n\r\n- [8.5](#8.5) <a name='8.5'></a> fadeToggle\r\n\r\n  フェードイン・フェードアウトを伴ってエレメントの表示・非表示を切り替えます。\r\n\r\n  ```js\r\n  // jQuery\r\n  $el.fadeToggle();\r\n\r\n  // Native\r\n  el.style.transition = 'opacity 3s';\r\n  let { opacity } = el.ownerDocument.defaultView.getComputedStyle(el, null);\r\n  if (opacity === '1') {\r\n    el.style.opacity = '0';\r\n  }\r\n  else {\r\n    el.style.opacity = '1';\r\n  }\r\n  ```\r\n\r\n- [8.6](#8.6) <a name='8.6'></a> スライドアップ、スライドダウン\r\n\r\n  ```js\r\n  // jQuery\r\n  $el.slideUp();\r\n  $el.slideDown();\r\n\r\n  // Native\r\n  let originHeight = '100px';\r\n  el.style.transition = 'height 3s';\r\n  // slideUp\r\n  el.style.height = '0px';\r\n  // slideDown\r\n  el.style.height = originHeight;\r\n  ```\r\n\r\n- [8.7](#8.7) <a name='8.7'></a> slideToggle\r\n\r\n  スライドを伴って、エレメントの表示・非表示を切り替えます。\r\n\r\n  ```js\r\n  // jQuery\r\n  $el.slideToggle();\r\n\r\n  // Native\r\n  let originHeight = '100px';\r\n  el.style.transition = 'height 3s';\r\n  let { height } = el.ownerDocument.defaultView.getComputedStyle(el, null);\r\n  if (parseInt(height, 10) === 0) {\r\n    el.style.height = originHeight;\r\n  }\r\n  else {\r\n   el.style.height = '0px';\r\n  }\r\n  ```\r\n\r\n- [8.8](#8.8) <a name='8.8'></a> animate\r\n\r\n  CSSプロパティで定義されたアニメーションを表示します。\r\n\r\n  ```js\r\n  // jQuery\r\n  $el.animate({params}, speed);\r\n\r\n  // Native\r\n  el.style.transition = 'all' + speed;\r\n  Object.keys(params).forEach(function(key) {\r\n    el.style[key] = params[key];\r\n  })\r\n  ```\r\n\r\n## 選択肢\r\n\r\n* [You Might Not Need jQuery](http://youmightnotneedjquery.com/) - ネイティブのJavaScriptでイベント、エレメント、Ajaxを扱うサンプル集(英語)\r\n* [npm-dom](http://github.com/npm-dom) and [webmodules](http://github.com/webmodules) - npmで利用できるDOMモジュールを集めたOrganizationです\r\n\r\n## 対応ブラウザ\r\n\r\n![Chrome][chrome-image] | ![Firefox][firefox-image] | ![IE][ie-image] | ![Opera][opera-image] | ![Safari][safari-image]\r\n--- | --- | --- | --- | ---\r\nLatest ✔ | Latest ✔ | 10+ ✔ | Latest ✔ | 6.1+ ✔\r\n\r\n# ライセンス\r\n\r\nMIT\r\n\r\n[chrome-image]: https://raw.github.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png\r\n[firefox-image]: https://raw.github.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png\r\n[ie-image]: https://raw.github.com/alrra/browser-logos/master/src/archive/internet-explorer_9-11/internet-explorer_9-11_48x48.png\r\n[opera-image]: https://raw.github.com/alrra/browser-logos/master/src/opera/opera_48x48.png\r\n[safari-image]: https://raw.github.com/alrra/browser-logos/master/src/safari/safari_48x48.png\r\n"
  },
  {
    "path": "README-kg.md",
    "content": "## jQuery'ге муктаждыгынар жок\n\n\nБиздин убакта фронт-энд чөйрөсү абдан ылдам өнүгүп жатат, ошонун менен бирге заманбап браузерлер көптөгөн DOM/BOM API жагын ишке ашырды. Бул абдан жакшы көрүнүш. Анткени, силер DOM'ду манипуляциялоо же  окуялардын объектерин иштешиш үчүн jQuery'ни башынан үйрөнүнөрдүн кажети калбайт.Ошонун менен бирге,  алдыда келе жаткан React, Angular жана  Vue фронт-энд библиотекалардын жардамы менен, DOM'ду түздөн-түз манипуляциялоо өзүнчө бир антипаттернге айланды.Бул проект көптөгөн jQuery методдорун нативдуу аткаруусу  жана IE 10+ колдоосу менен кошулган көптөгөн альтернативаларды өзүнө камтыйт.\n## Мазмуну\n\n1. [Котормолор](#Котормолор)\n1. [Query Selector](#query-selector)\n1. [CSS & Style](#css--style)\n1. [DOM манипуляциясы](#DOM-манипуляциясы)\n1. [Ajax](#ajax)\n1. [Окуялар](#Окуялар)\n1. [Утилиталар](#Утилиталар)\n1. [Альтернативалар](#Альтернативалар)\n1. [Браузерлердин колдоосу](#Браузерлердин-колдоосу)\n\n## Котормолор\n\n* [한국어](./README.ko-KR.md)\n* [正體中文](./README.zh-TW.md)\n* [简体中文](./README.zh-CN.md)\n* [Bahasa Melayu](./README-my.md)\n* [Bahasa Indonesia](./README-id.md)\n* [Português(PT-BR)](./README.pt-BR.md)\n* [Tiếng Việt Nam](./README-vi.md)\n* [Español](./README-es.md)\n* [Русский](./README-ru.md)\n* [Кыргызча](./README-kg.md)\n* [Türkçe](./README-tr.md)\n* [Italiano](./README-it.md)\n* [Français](./README-fr.md)\n* [日本語](./README-ja.md)\n* [Polski](./README-pl.md)\n\n## Query selector\n\n Көп колдонулган class, id же болбосо attribute сыяктуу селекторлор үчүн биз  `document.querySelector` же  `document.querySelectorAll` колдонсок болот. Айырмасы төмөнкүдөй:\n* `document.querySelector` биринчи дал келген элементти кайтарат.\n* `document.querySelectorAll` баардык дал келген элементтерди  түйүндөр коллекциялары(NodeList) сыяктуу кайтарат. Аны  `[].slice.call(document.querySelectorAll(selector) || []);` аркылуу  массивге конвертация кылууга болот.\n* Эгерде эч элементтер дал келбесе, анда  DOM API  `null` кайтарганда  jQuery  `[]` кайтарат. Null (Null Pointer Exception) чыгаруунун көрсөткүчүнө  көнүл бургула.  Эгерде дал келүүлөр  кездешбесе, анда силер жарыяланбаган маани үчүн `||` колдонсонор болот `document.querySelectorAll(selector) || []`\n\n> Белгилөө: `document.querySelector` жана `document.querySelectorAll` чыныгы **ЖАЙ**,  колдон келишинче кирешелүүлүктү жакшыртуу максатында `getElementById`, `document.getElementsByClassName` же `document.getElementsByTagName`  колдонго аракет кылгыла.\n\n- [1.0](#1.0) <a name='1.0'></a> Селектор аркылуу издөө\n\n  ```js\n  // jQuery\n  $('selector');\n\n  // Нативдүү түрү\n  document.querySelectorAll('selector');\n  ```\n\n- [1.1](#1.1) <a name='1.1'></a>  Класс боюнча кайрылуу\n\n  ```js\n  // jQuery\n  $('.class');\n\n  // Нативдүү түрү\n  document.querySelectorAll('.class');\n\n  // же\n  document.getElementsByClassName('class');\n  ```\n\n- [1.2](#1.2) <a name='1.2'></a>  ID боюнча кайрылуу\n\n  ```js\n  // jQuery\n  $('#id');\n\n  // Нативдүү түрү\n  document.querySelector('#id');\n\n  // же\n  document.getElementById('id');\n  ```\n\n- [1.3](#1.3) <a name='1.3'></a> Атрибут боюнча кайрылуу\n\n  ```js\n  // jQuery\n  $('a[target=_blank]');\n\n  // Нативдүү түрү\n  document.querySelectorAll('a[target=_blank]');\n  ```\n\n- [1.4](#1.4) <a name='1.4'></a> Тукумдардын арасында издөө\n\n  ```js\n  // jQuery\n  $el.find('li');\n\n  // Нативдүү түрү\n  el.querySelectorAll('li');\n  ```\n\n- [1.5](#1.5) <a name='1.5'></a> Бекем байланышкан/Мурунку/Кийинки элементтер\n\n  + Бекем байланышкан элементтер\n\n    ```js\n    // jQuery\n    $el.siblings();\n\n    // Нативдүү түрү\n    [].filter.call(el.parentNode.children, function(child) {\n      return child !== el;\n    });\n    ```\n\n  + Мурунку элементтер\n\n    ```js\n    // jQuery\n    $el.prev();\n\n    // Нативдүү түрү\n    el.previousElementSibling;\n    ```\n\n  + Кийинки элементтер\n\n    ```js\n    // jQuery\n    $el.next();\n\n    // Нативдүү түрү\n    el.nextElementSibling;\n    ```\n\n- [1.6](#1.6) <a name='1.6'></a> Жакынкы\n\n  Берилген селектор аркылуу биринчи дал келген элементти кайтарат.\n\n  ```js\n  // jQuery\n  $el.closest(selector);\n\n  // Нативдүү түрү - Only latest, NO IE\n  el.closest(selector);\n\n  // Нативдүү түрү - IE10+\n  function closest(el, selector) {\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    while (el) {\n      if (matchesSelector.call(el, selector)) {\n        return el;\n      } else {\n        el = el.parentElement;\n      }\n    }\n    return null;\n  }\n  ```\n\n- [1.7](#1.7) <a name='1.7'></a> Ата-энеге чейин\n     Бир бирине   жана селекторго дал келген, DOM'дун узели жана jquery'нин объектинен тышкары  элементтерлин сетинде жайгашкан ар-бир элементтин ата-энесин кайтарат.\n\n  ```js\n  // jQuery\n  $el.parentsUntil(selector, filter);\n\n  // Нативдүү түрү\n  function parentsUntil(el, selector, filter) {\n    const result = [];\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    // Ата-энеден баштап дал келүү\n    el = el.parentElement;\n    while (el && !matchesSelector.call(el, selector)) {\n      if (!filter) {\n        result.push(el);\n      } else {\n        if (matchesSelector.call(el, filter)) {\n          result.push(el);\n        }\n      }\n      el = el.parentElement;\n    }\n    return result;\n  }\n  ```\n\n- [1.8](#1.8) <a name='1.8'></a> От\n\n  + Input/Textarea\n\n    ```js\n    // jQuery\n    $('#my-input').val();\n\n    // Нативдүү түрү\n    document.querySelector('#my-input').value;\n    ```\n\n  + e.currentTarget жана  `.radio` индексин алуу\n\n    ```js\n    // jQuery\n    $(e.currentTarget).index('.radio');\n\n    // Нативдүү түрү\n    [].indexOf.call(document.querySelectorAll('.radio'), e.currentTarget);\n    ```\n\n- [1.9](#1.9) <a name='1.9'></a>  Iframe Контенти\n\n  `$('iframe').contents()` 'дин  `contentDocument`'н кайтарат.\n\n  +  Iframe'дин контенти\n\n    ```js\n    // jQuery\n    $iframe.contents();\n\n    // Нативдүү түрү\n    iframe.contentDocument;\n    ```\n\n  + Iframe Кайрылуу\n\n    ```js\n    // jQuery\n    $iframe.contents().find('.css');\n\n    // Нативдүү түрү\n    iframe.contentDocument.querySelectorAll('.css');\n    ```\n\n- [1.10](#1.10) <a name='1.10'></a>  body'ни табуу\n\n  ```js\n  // jQuery\n  $('body');\n\n  // Нативдүү түрү\n  document.body;\n  ```\n\n- [1.11](#1.11) <a name='1.11'></a>Атрибутту алуу жана аны  өзгөртүү\n\n  + Атрибутту табуу\n\n    ```js\n    // jQuery\n    $el.attr('foo');\n\n    // Нативдүү түрү\n    el.getAttribute('foo');\n    ```\n  + Атрибутту кошуу\n\n    ```js\n    // jQuery, DOM'ду өзгөртпөстөн эсте иштей берет\n    $el.attr('foo', 'bar');\n\n    // Нативдүү түрү\n    el.setAttribute('foo', 'bar');\n    ```\n\n  +  `data-` атрибутту табуу\n\n    ```js\n    // jQuery\n    $el.data('foo');\n\n    // Нативдүү түрү (`getAttribute`'ду колдонуп)\n    el.getAttribute('data-foo');\n    // Нативдүү түрү  ( `dataset`'ти колдонуу, эгерде  IE 11 төмөн колдоо жок болсо)\n    el.dataset['foo'];\n    ```\n\n    **[⬆ Башына](#Мазмуну)**\n\n    ## CSS & Style\n\n    - [2.1](#2.1) <a name='2.1'></a> CSS\n\n      +  Стильди алуу\n\n        ```js\n        // jQuery\n        $el.css(\"color\");\n\n        // Нативдүү түрү\n        // Белгилөө:  Белгилүү ката, эгерде стильдин мааниси 'auto' болсо, анда 'auto' кайтарат\n        const win = el.ownerDocument.defaultView;\n        // null псевдостильдерди кайтарбоону белгилейт\n        win.getComputedStyle(el, null).color;\n        ```\n\n      +  style менчиктоо\n\n        ```js\n        // jQuery\n        $el.css({ color: \"#ff0011\" });\n\n        // Нативдүү түрү\n        el.style.color = '#ff0011';\n        ```\n\n      +  Стильдерди Алуу/Менчиктоо\n\n        Заметьте что если вы хотите присвоить несколько стилей за раз, вы можете сослаться на [setStyles](https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L194) метод в oui-dom-utils package.\n\n\n      + Классты кошуу\n\n        ```js\n        // jQuery\n        $el.addClass(className);\n\n        // Нативдүү түрү\n        el.classList.add(className);\n        ```\n\n      + Классты жок кылуу\n\n        ```js\n        // jQuery\n        $el.removeClass(className);\n\n        // Нативдүү түрү\n        el.classList.remove(className);\n        ```\n\n      +  Классты камтыйт\n\n        ```js\n        // jQuery\n        $el.hasClass(className);\n\n        // Нативдүү түрү\n        el.classList.contains(className);\n        ```\n\n      +  Классты которуу\n\n        ```js\n        // jQuery\n        $el.toggleClass(className);\n\n        // Нативдүү түрү\n        el.classList.toggle(className);\n        ```\n\n    - [2.2](#2.2) <a name='2.2'></a> Туурасы жана узундугу\n\n      Турасы жана узундугу теорикалык турдо бири-бирине окшош, узундугун мисалга алсак:\n\n      + Терезенин узундугу\n\n        ```js\n        // Терезенин узундугу\n        $(window).height();\n        // Скролбарсыз jQuery'дей эле сыяктуу болот\n        window.document.documentElement.clientHeight;\n        // скролбар менен\n        window.innerHeight;\n        ```\n\n      + Документтин узундугу\n\n        ```js\n        // jQuery\n        $(document).height();\n\n        // Нативдүү түрү\n        document.documentElement.scrollHeight;\n        ```\n\n      + Элементтин узундугу\n\n        ```js\n        // jQuery\n        $el.height();\n\n        // Нативдүү түрү\n        function getHeight(el) {\n          const styles = window.getComputedStyle(el);\n          const height = el.offsetHeight;\n          const borderTopWidth = parseFloat(styles.borderTopWidth);\n          const borderBottomWidth = parseFloat(styles.borderBottomWidth);\n          const paddingTop = parseFloat(styles.paddingTop);\n          const paddingBottom = parseFloat(styles.paddingBottom);\n          return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;\n        }\n        // Так сандарга чейин（ `border-box` болгондо, анда `height - border`;  `content-box` болгондо, анда  `height + padding`）\n        el.clientHeight;\n        // Ондон бирине чейин（ `border-box` болгондо, анда `height`;  `content-box` болгондо, анда `height + padding + border`）\n        el.getBoundingClientRect().height;\n        ```\n\n    - [2.3](#2.3) <a name='2.3'></a> Позиция  жана  өтүү\n\n      + Позициясы\n\n        Ата-энесин жылуусу боюнча учурдагы координаттарды алуу\n\n        ```js\n        // jQuery\n        $el.position();\n\n        // Нативдүү түрү\n        { left: el.offsetLeft, top: el.offsetTop }\n        ```\n\n      + Ылдый өтүү\n\n        Учурдагы элементтин координаттарын кайтарып алуу\n\n        ```js\n        // jQuery\n        $el.offset();\n\n        // Нативдүү түрү\n        function getOffset (el) {\n          const box = el.getBoundingClientRect();\n\n          return {\n            top: box.top + window.pageYOffset - document.documentElement.clientTop,\n            left: box.left + window.pageXOffset - document.documentElement.clientLeft\n          }\n        }\n        ```\n\n    - [2.4](#2.4) <a name='2.4'></a> Жогоруга жылдыруу\n\n      ```js\n      // jQuery\n      $(window).scrollTop();\n\n      // Нативдүү түрү\n      (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;\n      ```\n\n    **[⬆ Башына](#Мазмуну)**\n\n    ## DOM манипуляциясы\n\n    - [3.1](#3.1) <a name='3.1'></a> Remove\n\n       DOM'дон элементти өчүрүү .\n\n      ```js\n      // jQuery\n      $el.remove();\n\n      // Нативдүү түрү\n      el.parentNode.removeChild(el);\n      ```\n\n    - [3.2](#3.2) <a name='3.2'></a> Текст\n\n      +  Текстти кайтарып алуу\n\n        Элементтин тексттик  түрүн кайтарып алуу\n\n        ```js\n        // jQuery\n        $el.text();\n\n        // Нативдүү түрү\n        el.textContent;\n        ```\n\n      +  Текстти менчиктөө\n\n        ```js\n        // jQuery\n        $el.text(string);\n\n        // Нативдүү түрү\n        el.textContent = string;\n        ```\n\n    - [3.3](#3.3) <a name='3.3'></a> HTML\n\n      +  HTML кайтарып алуу\n\n        ```js\n        // jQuery\n        $el.html();\n\n        // Нативдүү түрү\n        el.innerHTML;\n        ```\n\n      +  HTML'ны менчиктөө\n\n        ```js\n        // jQuery\n        $el.html(htmlString);\n\n        // Нативдүү түрү\n        el.innerHTML = htmlString;\n        ```\n\n    - [3.4](#3.4) <a name='3.4'></a> Append\n\n      Акыркы ата-эненин баласындан кийин жаны элементти кошуу\n\n      ```js\n      // jQuery\n      $el.append(\"<div id='container'>hello</div>\");\n\n      // Нативдүү түрү\n      el.insertAdjacentHTML(\"beforeend\",\"<div id='container'>hello</div>\");\n      ```\n\n    - [3.5](#3.5) <a name='3.5'></a> Prepend\n\n      ```js\n      // jQuery\n      $el.prepend(\"<div id='container'>hello</div>\");\n\n      // Нативдүү түрү\n      el.insertAdjacentHTML(\"afterbegin\",\"<div id='container'>hello</div>\");\n      ```\n\n    - [3.6](#3.6) <a name='3.6'></a> insertBefore\n\n      Тандалган элементтин астына жаны элементти кошуу\n\n\n      ```js\n      // jQuery\n      $newEl.insertBefore(queryString);\n\n      // Нативдүү түрү\n      const target = document.querySelector(queryString);\n      target.parentNode.insertBefore(newEl, target);\n      ```\n\n    - [3.7](#3.7) <a name='3.7'></a> insertAfter\n\n      Тандалган элементтен кийин жаны элементти кошуу\n\n      ```js\n      // jQuery\n      $newEl.insertAfter(queryString);\n\n      // Нативдүү түрү\n      const target = document.querySelector(queryString);\n      target.parentNode.insertBefore(newEl, target.nextSibling);\n      ```\n\n    - [3.8](#3.8) <a name='3.8'></a> is\n\n       Эгерде селектордун кайрылуусуна  дал келсе, анда `true` кайтарат.\n\n      ```js\n      // jQuery - байсанар,   `is` `function` же  `elements` менен да иштейт.\n      $el.is(selector);\n\n      // Нативдүү түрү\n      el.matches(selector);\n      ```\n\n    **[⬆ Башына](#Мазмуну)**\n\n    ## Ajax\n\n    [Fetch API](https://fetch.spec.whatwg.org/) -  XMLHttpRequest ajax үчүн орун алган жаны стандарт. Chrome жана Firefox үчүн иштейт, бирок силер эски браузерлердин колдоосу үчүн полифилдерди колдонсонор болот.\n\n      IE9+ [github/fetch](http://github.com/github/fetch)үчүн  же  [fetch-ie8](https://github.com/camsong/fetch-ie8/)  IE8+ үчүн, [fetch-jsonp](https://github.com/camsong/fetch-jsonp)  JSONP-кайрылуулар үчүн колдонуп көргулө .\n\n    **[⬆ Башына](#Мазмуну)**\n\n    ## Окуялар\n\n    Аттардын мейкиндигни толук алмаштыруу жана делегирование кылыш үчүн  [oui-dom-events](https://github.com/oneuijs/oui-dom-events) кайрылуу керек\n\n    - [5.1](#5.1) <a name='5.1'></a> Окуяларды onn аркылуу  байланыштыруу\n\n      ```js\n      // jQuery\n      $el.on(eventName, eventHandler);\n\n      // Нативдүү түрү\n      el.addEventListener(eventName, eventHandler);\n      ```\n\n    - [5.2](#5.2) <a name='5.2'></a> Окуяларды off аркылуу  жоюу\n\n      ```js\n      // jQuery\n      $el.off(eventName, eventHandler);\n\n      // Нативдүү түрү\n      el.removeEventListener(eventName, eventHandler);\n      ```\n\n    - [5.3](#5.3) <a name='5.3'></a> Trigger\n\n      ```js\n      // jQuery\n      $(el).trigger('custom-event', {key1: 'data'});\n\n      // Нативдүү түрү\n      if (window.CustomEvent) {\n        const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});\n      } else {\n        const event = document.createEvent('CustomEvent');\n        event.initCustomEvent('custom-event', true, true, {key1: 'data'});\n      }\n\n      el.dispatchEvent(event);\n      ```\n\n    **[⬆ Башына](#Мазмуну)**\n\n    ## Утилиталар\n\n    - [6.1](#6.1) <a name='6.1'></a> isArray\n\n      ```js\n      // jQuery\n      $.isArray(range);\n\n      // Нативдүү түрү\n      Array.isArray(range);\n      ```\n\n    - [6.2](#6.2) <a name='6.2'></a> Trim\n\n      ```js\n      // jQuery\n      $.trim(string);\n\n      // Нативдүү түрү\n      string.trim();\n      ```\n\n    - [6.3](#6.3) <a name='6.3'></a> Объектин дайындоосу\n\n      Кошумча  object.assign https://github.com/ljharb/object.assign полифилин колдонгула\n\n      ```js\n      // jQuery\n      $.extend({}, defaultOpts, opts);\n\n      // Нативдүү түрү\n      Object.assign({}, defaultOpts, opts);\n      ```\n\n    - [6.4](#6.4) <a name='6.4'></a> Contains\n\n      ```js\n      // jQuery\n      $.contains(el, child);\n\n      // Нативдүү түрү\n      el !== child && el.contains(child);\n      ```\n\n    **[⬆ Башына](#Мазмуну)**\n\n    ## Альтернативалар\n\n    * [You Might Not Need jQuery](http://youmightnotneedjquery.com/) - Бат-бат окуялар, элементтер, ajax ж.б.у.с мисалдардын ванильдуу javascript менен көрсөтүү.\n    * [npm-dom](http://github.com/npm-dom) и [webmodules](http://github.com/webmodules) - Башка DOM бөлүктөрүy NPM'де тапса болот\n\n    ## Браузерлердин колдоосу\n\n    ![Chrome](https://raw.github.com/alrra/browser-logos/master/chrome/chrome_48x48.png) | ![Firefox](https://raw.github.com/alrra/browser-logos/master/firefox/firefox_48x48.png) | ![IE](https://raw.github.com/alrra/browser-logos/master/internet-explorer/internet-explorer_48x48.png) | ![Opera](https://raw.github.com/alrra/browser-logos/master/opera/opera_48x48.png) | ![Safari](https://raw.github.com/alrra/browser-logos/master/safari/safari_48x48.png)\n    --- | --- | --- | --- | --- |\n    Latest ✔ | Latest ✔ | 10+ ✔ | Latest ✔ | 6.1+ ✔ |\n\n    # License\n\n    MIT\n"
  },
  {
    "path": "README-my.md",
    "content": "## Anda tidak memerlukan jQuery\n\nMutakhir ini perkembangan dalam persekitaran frontend berlaku begitu pesat sekali. Justeru itu kebanyakan pelayar moden telahpun menyediakan API yang memadai untuk pengaksesan DOM/BOM. Kita tak payah lagi belajar jQuery dari asas untuk memanipulasi DOM dan acara-acara. Projek ini menawarkan perlaksanaan alternatif kepada kebanyakan kaedah-kaedah jQuery yang menyokong IE 10+.\n\n## Isi Kandungan\n\n1. [Terjemahan](#terjemahan)\n1. [Pemilihan elemen](#pemilihan-elemen)\n1. [CSS & Penggayaan](#css-penggayaan)\n1. [Manipulasi DOM](#manipulasi-dom)\n1. [Ajax](#ajax)\n1. [Events](#events)\n1. [Utiliti](#utiliti)\n1. [Browser Support](#browser-support)\n\n## Terjemahan\n\n* [한국어](./README.ko-KR.md)\n* [正體中文](./README.zh-TW.md)\n* [简体中文](./README.zh-CN.md)\n* [Bahasa Melayu](./README-my.md)\n* [Bahasa Indonesia](./README-id.md)\n* [Português(PT-BR)](./README.pt-BR.md)\n* [Tiếng Việt Nam](./README-vi.md)\n* [Español](./README-es.md)\n* [Русский](./README-ru.md)\n* [Кыргызча](./README-kg.md)\n* [Türkçe](./README-tr.md)\n* [Italiano](./README-it.md)\n* [Français](./README-fr.md)\n* [日本語](./README-ja.md)\n* [Polski](./README-pl.md)\n\n## Pemilihan Elemen\n\nPemilihan elemen yang umum seperti class, id atau atribut, biasanya kita boleh pakai `document.querySelector` atau `document.querySelectorAll` sebagai ganti. Bezanya terletak pada\n* `document.querySelector` akan mengembalikan elemen pertama sekali yang sepadan dijumpai\n* `document.querySelectorAll` akan mengembalikan kesemua elemen yang sepadan dijumpai kedalam sebuah NodeList. Ia boleh ditukar kedalam bentuk array menggunakan `[].slice.call`\n* Sekiranya tiada elemen yang sepadan dijumpai, jQuery akan mengembalikan `[]` dimana API DOM pula akan mengembalikan `null`. Sila ambil perhatian pada Null Pointer Exception\n\n> AWAS: `document.querySelector` dan `document.querySelectorAll` agak **LEMBAB** berbanding `getElementById`, `document.getElementsByClassName` atau `document.getElementsByTagName` jika anda menginginkan bonus dari segi prestasi.\n\n- [1.1](#1.1) <a name='1.1'></a> Pemilihan menggunakan class\n\n  ```js\n  // jQuery\n  $('.css');\n\n  // Native\n  document.querySelectorAll('.css');\n  ```\n\n- [1.2](#1.2) <a name='1.2'></a> Pemilihan menggunakan id\n\n  ```js\n  // jQuery\n  $('#id');\n\n  // Native\n  document.querySelector('#id');\n  ```\n\n- [1.3](#1.3) <a name='1.3'></a> Pemilihan menggunakan atribut\n\n  ```js\n  // jQuery\n  $('a[target=_blank]');\n\n  // Native\n  document.querySelectorAll('a[target=_blank]');\n  ```\n\n- [1.4](#1.4) <a name='1.4'></a> Cari sth.\n\n  + Find nodes\n\n    ```js\n    // jQuery\n    $el.find('li');\n\n    // Native\n    el.querySelectorAll('li');\n    ```\n\n  + Cari body\n\n    ```js\n    // jQuery\n    $('body');\n\n    // Native\n    document.body;\n    ```\n\n  + Cari Attribute\n\n    ```js\n    // jQuery\n    $el.attr('foo');\n\n    // Native\n    e.getAttribute('foo');\n    ```\n\n  + Cari atribut data\n\n    ```js\n    // jQuery\n    $el.data('foo');\n\n    // Native\n    // menggunakan getAttribute\n    el.getAttribute('data-foo');\n    // anda boleh juga gunakan `dataset` jika ingin pakai IE 11+\n    el.dataset['foo'];\n    ```\n\n- [1.5](#1.5) <a name='1.5'></a> Sibling/Previous/Next Elements\n\n  + Sibling elements\n\n    ```js\n    // jQuery\n    $el.siblings();\n\n    // Native\n    [].filter.call(el.parentNode.children, function(child) {\n      return child !== el;\n    });\n    ```\n\n  + Previous elements\n\n    ```js\n    // jQuery\n    $el.prev();\n\n    // Native\n    el.previousElementSibling;\n\n    ```\n\n  + Next elements\n\n    ```js\n    // next\n    $el.next();\n    el.nextElementSibling;\n    ```\n\n- [1.6](#1.6) <a name='1.6'></a> Closest\n\n  Return the first matched element by provided selector, traversing from current element to document.\n\n  ```js\n  // jQuery\n  $el.closest(queryString);\n\n  // Native\n  function closest(el, selector) {\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    while (el) {\n      if (matchesSelector.call(el, selector)) {\n        return el;\n      } else {\n        el = el.parentElement;\n      }\n    }\n    return null;\n  }\n  ```\n\n- [1.7](#1.7) <a name='1.7'></a> Parents Until\n\n  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.\n\n  ```js\n  // jQuery\n  $el.parentsUntil(selector, filter);\n\n  // Native\n  function parentsUntil(el, selector, filter) {\n    const result = [];\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    // match start from parent\n    el = el.parentElement;\n    while (el && !matchesSelector.call(el, selector)) {\n      if (!filter) {\n        result.push(el);\n      } else {\n        if (matchesSelector.call(el, filter)) {\n          result.push(el);\n        }\n      }\n      el = el.parentElement;\n    }\n    return result;\n  }\n  ```\n\n- [1.8](#1.8) <a name='1.8'></a> Form\n\n  + Input/Textarea\n\n    ```js\n    // jQuery\n    $('#my-input').val();\n\n    // Native\n    document.querySelector('#my-input').value;\n    ```\n\n  + Get index of e.currentTarget between `.radio`\n\n    ```js\n    // jQuery\n    $(e.currentTarget).index('.radio');\n\n    // Native\n    [].indexOf.call(document.querySelectAll('.radio'), e.currentTarget);\n    ```\n\n- [1.9](#1.9) <a name='1.9'></a> Iframe Contents\n\n  `$('iframe').contents()` returns `contentDocument` for this specific iframe\n\n  + Iframe contents\n\n    ```js\n    // jQuery\n    $iframe.contents();\n\n    // Native\n    iframe.contentDocument;\n    ```\n\n  + Iframe Query\n\n    ```js\n    // jQuery\n    $iframe.contents().find('.css');\n\n    // Native\n    iframe.contentDocument.querySelectorAll('.css');\n    ```\n\n**[⬆ back to top](#table-of-contents)**\n\n## CSS & Style\n\n- [2.1](#2.1) <a name='2.1'></a> CSS\n\n  + Get style\n\n    ```js\n    // jQuery\n    $el.css(\"color\");\n\n    // Native\n    // NOTE: Known bug, will return 'auto' if style value is 'auto'\n    const win = el.ownerDocument.defaultView;\n    // null means not return presudo styles\n    win.getComputedStyle(el, null).color;\n    ```\n\n  + Set style\n\n    ```js\n    // jQuery\n    $el.css({ color: \"#ff0011\" });\n\n    // Native\n    el.style.color = '#ff0011';\n    ```\n\n  + Get/Set Styles\n\n    Note that if you want to set multiple styles once, you could refer to [setStyles](https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L194) method in oui-dom-utils package.\n\n\n  + Add class\n\n    ```js\n    // jQuery\n    $el.addClass(className);\n\n    // Native\n    el.classList.add(className);\n    ```\n\n  + Remove class\n\n    ```js\n    // jQuery\n    $el.removeClass(className);\n\n    // Native\n    el.classList.remove(className);\n    ```\n\n  + has class\n\n    ```js\n    // jQuery\n    $el.hasClass(className);\n\n    // Native\n    el.classList.contains(className);\n    ```\n\n  + Toggle class\n\n    ```js\n    // jQuery\n    $el.toggleClass(className);\n\n    // Native\n    el.classList.toggle(className);\n    ```\n\n- [2.2](#2.2) <a name='2.2'></a> Width & Height\n\n  Width and Height are theoretically identical, take Height as example:\n\n  + Window height\n\n    ```js\n    // window height\n    $(window).height();\n    // without scrollbar, behaves like jQuery\n    window.document.documentElement.clientHeight;\n    // with scrollbar\n    window.innerHeight;\n    ```\n\n  + Document height\n\n    ```js\n    // jQuery\n    $(document).height();\n\n    // Native\n    document.documentElement.scrollHeight;\n    ```\n\n  + Element height\n\n    ```js\n    // jQuery\n    $el.height();\n\n    // Native\n    function getHeight(el) {\n      const styles = this.getComputedStyles(el);\n      const height = el.offsetHeight;\n      const borderTopWidth = parseFloat(styles.borderTopWidth);\n      const borderBottomWidth = parseFloat(styles.borderBottomWidth);\n      const paddingTop = parseFloat(styles.paddingTop);\n      const paddingBottom = parseFloat(styles.paddingBottom);\n      return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;\n    }\n    // accurate to integer（when `border-box`, it's `height - border`; when `content-box`, it's `height + padding`）\n    el.clientHeight;\n    // accurate to decimal（when `border-box`, it's `height`; when `content-box`, it's `height + padding + border`）\n    el.getBoundingClientRect().height;\n    ```\n\n- [2.3](#2.3) <a name='2.3'></a> Position & Offset\n\n  + Position\n\n    ```js\n    // jQuery\n    $el.position();\n\n    // Native\n    { left: el.offsetLeft, top: el.offsetTop }\n    ```\n\n  + Offset\n\n    ```js\n    // jQuery\n    $el.offset();\n\n    // Native\n    function getOffset (el) {\n      const box = el.getBoundingClientRect();\n\n      return {\n        top: box.top + window.pageYOffset - document.documentElement.clientTop,\n        left: box.left + window.pageXOffset - document.documentElement.clientLeft\n      }\n    }\n    ```\n\n- [2.4](#2.4) <a name='2.4'></a> Scroll Top\n\n  ```js\n  // jQuery\n  $(window).scrollTop();\n\n  // Native\n  (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;\n  ```\n\n**[⬆ back to top](#table-of-contents)**\n\n## DOM Manipulation\n\n- [3.1](#3.1) <a name='3.1'></a> Remove\n  ```js\n  // jQuery\n  $el.remove();\n\n  // Native\n  el.parentNode.removeChild(el);\n  ```\n\n- [3.2](#3.2) <a name='3.2'></a> Text\n\n  + Get text\n\n    ```js\n    // jQuery\n    $el.text();\n\n    // Native\n    el.textContent;\n    ```\n\n  + Set text\n\n    ```js\n    // jQuery\n    $el.text(string);\n\n    // Native\n    el.textContent = string;\n    ```\n\n- [3.3](#3.3) <a name='3.3'></a> HTML\n\n  + Get HTML\n\n    ```js\n    // jQuery\n    $el.html();\n\n    // Native\n    el.innerHTML;\n    ```\n\n  + Set HTML\n\n    ```js\n    // jQuery\n    $el.html(htmlString);\n\n    // Native\n    el.innerHTML = htmlString;\n    ```\n\n- [3.4](#3.4) <a name='3.4'></a> Append\n\n  append child element after the last child of parent element\n\n  ```js\n  // jQuery\n  $el.append(\"<div id='container'>hello</div>\");\n\n  // Native\n  let newEl = document.createElement('div');\n  newEl.setAttribute('id', 'container');\n  newEl.innerHTML = 'hello';\n  el.appendChild(newEl);\n  ```\n\n- [3.5](#3.5) <a name='3.5'></a> Prepend\n\n  ```js\n  // jQuery\n  $el.prepend(\"<div id='container'>hello</div>\");\n\n  // Native\n  let newEl = document.createElement('div');\n  newEl.setAttribute('id', 'container');\n  newEl.innerHTML = 'hello';\n  el.insertBefore(newEl, el.firstChild);\n  ```\n\n- [3.6](#3.6) <a name='3.6'></a> insertBefore\n\n  Insert a new node before the selected elements\n\n  ```js\n  // jQuery\n  $newEl.insertBefore(queryString);\n\n  // Native\n  const target = document.querySelector(queryString);\n  target.parentNode.insertBefore(newEl, target);\n  ```\n\n- [3.7](#3.7) <a name='3.7'></a> insertAfter\n\n  Insert a new node after the selected elements\n\n  ```js\n  // jQuery\n  $newEl.insertAfter(queryString);\n\n  // Native\n  const target = document.querySelector(queryString);\n  target.parentNode.insertBefore(newEl, target.nextSibling);\n  ```\n\n**[⬆ back to top](#table-of-contents)**\n\n## Ajax\n\nReplace with [fetch](https://github.com/camsong/fetch-ie8) and [fetch-jsonp](https://github.com/camsong/fetch-jsonp)\n\n**[⬆ back to top](#table-of-contents)**\n\n## Events\n\nFor a complete replacement with namespace and delegation, refer to https://github.com/oneuijs/oui-dom-events\n\n- [5.1](#5.1) <a name='5.1'></a> Bind an event with on\n\n  ```js\n  // jQuery\n  $el.on(eventName, eventHandler);\n\n  // Native\n  el.addEventListener(eventName, eventHandler);\n  ```\n\n- [5.2](#5.2) <a name='5.2'></a> Unbind an event with off\n\n  ```js\n  // jQuery\n  $el.off(eventName, eventHandler);\n\n  // Native\n  el.removeEventListener(eventName, eventHandler);\n  ```\n\n- [5.3](#5.3) <a name='5.3'></a> Trigger\n\n  ```js\n  // jQuery\n  $(el).trigger('custom-event', {key1: 'data'});\n\n  // Native\n  if (window.CustomEvent) {\n    const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});\n  } else {\n    const event = document.createEvent('CustomEvent');\n    event.initCustomEvent('custom-event', true, true, {key1: 'data'});\n  }\n\n  el.dispatchEvent(event);\n  ```\n\n**[⬆ back to top](#table-of-contents)**\n\n## Utility\n\n- [6.1](#6.1) <a name='6.1'></a> isArray\n\n  ```js\n  // jQuery\n  $.isArray(range);\n\n  // Native\n  Array.isArray(range);\n  ```\n\n- [6.2](#6.2) <a name='6.2'></a> Trim\n\n  ```js\n  // jQuery\n  $.trim(string);\n\n  // Native\n  String.trim(string);\n  ```\n\n- [6.3](#6.3) <a name='6.3'></a> Object Assign\n\n  Extend, use object.assign polyfill https://github.com/ljharb/object.assign\n\n  ```js\n  // jQuery\n  $.extend({}, defaultOpts, opts);\n\n  // Native\n  Object.assign({}, defaultOpts, opts);\n  ```\n\n- [6.4](#6.4) <a name='6.4'></a> Contains\n\n  ```js\n  // jQuery\n  $.contains(el, child);\n\n  // Native\n  el !== child && el.contains(child);\n  ```\n\n**[⬆ back to top](#table-of-contents)**\n\n## Sokongan Pelayar\n\n![Chrome](https://raw.github.com/alrra/browser-logos/master/chrome/chrome_48x48.png) | ![Firefox](https://raw.github.com/alrra/browser-logos/master/firefox/firefox_48x48.png) | ![IE](https://raw.github.com/alrra/browser-logos/master/internet-explorer/internet-explorer_48x48.png) | ![Opera](https://raw.github.com/alrra/browser-logos/master/opera/opera_48x48.png) | ![Safari](https://raw.github.com/alrra/browser-logos/master/safari/safari_48x48.png)\n--- | --- | --- | --- | --- |\nLatest ✔ | Latest ✔ | 10+ ✔ | Latest ✔ | 6.1+ ✔ |\n\n# Lesen\n\nMIT\n"
  },
  {
    "path": "README-pl.md",
    "content": "## Nie Potrzebujesz jQuery\n\nŚrodowiska frontendowe rozwijają się błyskawicznie, nowsze przeglądarki zaimplementowały już większą część API DOM/BOM, które są całkiem użyteczne. Nie musimy uczyć się jQuery od podstaw by manipulować modelem dokumentu lub obsługiwać zdarzenia. Tymczasem, dzięki coraz większej dominacji bibliotek frontendowych takich jak React, Angular czy Vue, obsługa DOM bezpośrednio staje się antywzorcem projektowym, a jQuery coraz bardziej traci na znaczeniu. Ten projekt pokazuje w jaki sposób można zastąpić większość metod jQuery korzystając z natywnej implementacji, ze wsparciem dla IE 10+.\n\n## Spis treści\n\n1. [Tłumaczenia](#tłumaczenia)\n1. [Wybór przez selektory](#wybór-przez-selektory)\n1. [CSS i styl](#css-i-styl)\n1. [Manipulacja DOM](#manipulacja-dom)\n1. [Ajax](#ajax)\n1. [Zdarzenia](#zdarzenia)\n1. [Funkcje użytkowe](#funkcje-użytkowe)\n1. [Obietnice](#obietnice)\n1. [Animacja](#animacja)\n1. [Alternatywy](#alternatywy)\n1. [Wsparcie przeglądarek](#wsparcie-przeglądarek)\n\n## Tłumaczenia\n\n* [한국어](./README.ko-KR.md)\n* [正體中文](./README.zh-TW.md)\n* [简体中文](./README.zh-CN.md)\n* [Bahasa Melayu](./README-my.md)\n* [Bahasa Indonesia](./README-id.md)\n* [Português(PT-BR)](./README.pt-BR.md)\n* [Tiếng Việt Nam](./README-vi.md)\n* [Español](./README-es.md)\n* [Русский](./README-ru.md)\n* [Кыргызча](./README-kg.md)\n* [Türkçe](./README-tr.md)\n* [Italiano](./README-it.md)\n* [Français](./README-fr.md)\n* [日本語](./README-ja.md)\n* [Polski](./README-pl.md)\n\n## Wybór przez Selektory\n\nZamiast korzystania z powszechnych selektorów takich jak klasa, id czy też atrybut, możemy użyć `document.querySelector` lub `document.querySelectorAll`. Różnica między nimi to:\n* `document.querySelector` zwraca pierwszy pasujący element\n* `document.querySelectorAll` zwraca wszystkie elementy jako NodeList. Może zostać przekształcony do tablicy przy użyciu `Array.prototype.slice.call(document.querySelectorAll(selector));`\n* Jeżeli żaden element nie został znaleziony, jQuery oraz `document.querySelectorAll` zwrócą `[]`, a `document.querySelector` zwróci `null`.\n\n> Uwaga: `document.querySelector` i `document.querySelectorAll` są dosyć **WOLNE**, staraj się używać `document.getElementById`, `document.getElementsByClassName` lub `document.getElementsByTagName` jeżeli chcesz zwiększyć wydajność.\n\n- [1.0](#1.0) <a name='1.0'></a> Wybór przez selektor\n\n  ```js\n  // jQuery\n  $('selector');\n\n  // Natywnie\n  document.querySelectorAll('selector');\n  ```\n\n- [1.1](#1.1) <a name='1.1'></a> Wybór przez klasę\n\n  ```js\n  // jQuery\n  $('.class');\n\n  // Natywnie\n  document.querySelectorAll('.class');\n\n  // lub\n  document.getElementsByClassName('class');\n  ```\n\n- [1.2](#1.2) <a name='1.2'></a> Wybór przez id\n\n  ```js\n  // jQuery\n  $('#id');\n\n  // Natywnie\n  document.querySelector('#id');\n\n  // lub\n  document.getElementById('id');\n  ```\n\n- [1.3](#1.3) <a name='1.3'></a> Wybór przez atrybut\n\n  ```js\n  // jQuery\n  $('a[target=_blank]');\n\n  // Natywnie\n  document.querySelectorAll('a[target=_blank]');\n  ```\n\n- [1.4](#1.4) <a name='1.4'></a> Wybór spośród potomków\n\n  ```js\n  // jQuery\n  $el.find('li');\n\n  // Natywnie\n  el.querySelectorAll('li');\n  ```\n\n- [1.5](#1.5) <a name='1.5'></a> Rodzeństwo, Poprzednie/Następne elementy\n\n  + Rodzeństwo\n\n    ```js\n    // jQuery\n    $el.siblings();\n\n    // Natywnie\n    Array.prototype.filter.call(el.parentNode.children, (child) =>\n      child !== el\n    );\n    ```\n\n  + Poprzednie elementy\n\n    ```js\n    // jQuery\n    $el.prev();\n\n    // Natywnie\n    el.previousElementSibling;\n    ```\n\n  + Następne elementy\n\n    ```js\n    // jQuery\n    $el.next();\n\n    // Natywnie\n    el.nextElementSibling;\n    ```\n\n- [1.6](#1.6) <a name='1.6'></a> Najbliższy\n\n  Zwraca pierwszy pasujący element przez podany selektor, sprawdzając kolejno elementy od bieżącego.\n\n  ```js\n  // jQuery\n  $el.closest(selector);\n\n  // Natywnie - Tylko najnowsze, bez wsparcia w IE\n  el.closest(selector);\n\n  // Natywnie - IE10+\n  function closest(el, selector) {\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    while (el) {\n      if (matchesSelector.call(el, selector)) {\n        return el;\n      } else {\n        el = el.parentElement;\n      }\n    }\n    return null;\n  }\n  ```\n\n- [1.7](#1.7) <a name='1.7'></a> Rodzice dopóki\n\n  Zwraca potomków każdego elementu w bieżącym zbiorze pasujących elementów, aż do elementu dopasowanego przez selektor, węzeł DOM, lub obiekt jQuery.\n\n  ```js\n  // jQuery\n  $el.parentsUntil(selector, filter);\n\n  // Natywnie\n  function parentsUntil(el, selector, filter) {\n    const result = [];\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    // match start from parent\n    el = el.parentElement;\n    while (el && !matchesSelector.call(el, selector)) {\n      if (!filter) {\n        result.push(el);\n      } else {\n        if (matchesSelector.call(el, filter)) {\n          result.push(el);\n        }\n      }\n      el = el.parentElement;\n    }\n    return result;\n  }\n  ```\n\n- [1.8](#1.8) <a name='1.8'></a> Formularze\n\n  + Pola tekstowe\n\n    ```js\n    // jQuery\n    $('#my-input').val();\n\n    // Natywnie\n    document.querySelector('#my-input').value;\n    ```\n\n  + Otrzymanie indeksu `e.currentTarget` wewnątrz elementów `.radio`\n\n    ```js\n    // jQuery\n    $('.radio').index(e.currentTarget);\n\n    // Natywnie\n    Array.prototype.indexOf.call(document.querySelectorAll('.radio'), e.currentTarget);\n    ```\n\n- [1.9](#1.9) <a name='1.9'></a> Zawartość ramek\n\n  `$('iframe').contents()` zwraca `contentDocument` tego iframe\n\n  + Zawartość ramki\n\n    ```js\n    // jQuery\n    $iframe.contents();\n\n    // Natywnie\n    iframe.contentDocument;\n    ```\n\n  + Wybór elementu ramki\n\n    ```js\n    // jQuery\n    $iframe.contents().find('.css');\n\n    // Natywnie\n    iframe.contentDocument.querySelectorAll('.css');\n    ```\n\n- [1.10](#1.10) <a name='1.10'></a> Otrzymanie body\n\n  ```js\n  // jQuery\n  $('body');\n\n  // Native\n  document.body;\n  ```\n\n- [1.11](#1.11) <a name='1.11'></a> Akcesory atrybutów\n\n  + Otrzymanie wartości atrybutu\n\n    ```js\n    // jQuery\n    $el.attr('foo');\n\n    // Natywnie\n    el.getAttribute('foo');\n    ```\n  + Ustawienie wartości atrybutu\n\n    ```js\n    // jQuery, działa w pamięci bez zmiany DOM\n    $el.attr('foo', 'bar');\n\n    // Natywnie\n    el.setAttribute('foo', 'bar');\n    ```\n\n  + Otrzymanie wartości atrybutu `data-`\n\n    ```js\n    // jQuery\n    $el.data('foo');\n\n    // Natywnie (użycie `getAttribute`)\n    el.getAttribute('data-foo');\n\n    // Natywnie (użycie `dataset` jeżeli wspierasz tylko przeglądarki IE 11+)\n    el.dataset['foo'];\n    ```\n\n**[⬆ powrót](#spis-treści)**\n\n## CSS i styl\n\n- [2.1](#2.1) <a name='2.1'></a> CSS\n\n  + Otrzymanie stylu\n\n    ```js\n    // jQuery\n    $el.css('color');\n\n    // Natywnie\n    // UWAGA: Znany bug, zwróci 'auto' jeżeli wartość style wynosi 'auto'\n    const win = el.ownerDocument.defaultView;\n\n    // null oznacza, że nie zostaną zwrócone pseudostyle\n    win.getComputedStyle(el, null).color;\n    ```\n\n  + Ustawienie stylu\n\n    ```js\n    // jQuery\n    $el.css({ color: '#f01' });\n\n    // Natywnie\n    el.style.color = '#f01';\n    ```\n\n  + Otrzymanie/Ustawienie stylów\n\n    Jeżeli chcesz ustawić wiele stylów jednocześnie, możesz odwołać się do metody [setStyles](https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L194) w pakiecie oui-dom-utils.\n\n\n  + Dodanie klasy\n\n    ```js\n    // jQuery\n    $el.addClass(className);\n\n    // Natywnie\n    el.classList.add(className);\n    ```\n\n  + Usunięcie klasy\n\n    ```js\n    // jQuery\n    $el.removeClass(className);\n\n    // Natywnie\n    el.classList.remove(className);\n    ```\n\n  + Sprawdzenie czy element posiada klasę\n\n    ```js\n    // jQuery\n    $el.hasClass(className);\n\n    // Natywnie\n    el.classList.contains(className);\n    ```\n\n  + Przełączenie klasy\n\n    ```js\n    // jQuery\n    $el.toggleClass(className);\n\n    // Natywnie\n    el.classList.toggle(className);\n    ```\n\n- [2.2](#2.2) <a name='2.2'></a> Szerokość i wysokość\n\n  Manipulowanie szerokością i wysokością jest teoretycznie takie samo, dla przykładu użycie wysokości:\n\n  + Wysokość okna\n\n    ```js\n    // window height\n    $(window).height();\n\n    // bez paska, działa jak jQuery\n    window.document.documentElement.clientHeight;\n\n    // z paskiem przewijania\n    window.innerHeight;\n    ```\n\n  + Wysokość dokumentu\n\n    ```js\n    // jQuery\n    $(document).height();\n\n    // Natywnie\n    const body = document.body;\n    const html = document.documentElement;\n    const height = Math.max(\n      body.offsetHeight,\n      body.scrollHeight,\n      html.clientHeight,\n      html.offsetHeight,\n      html.scrollHeight\n    );\n    ```\n\n  + Wysokość elementu\n\n    ```js\n    // jQuery\n    $el.height();\n\n    // Natywnie\n    function getHeight(el) {\n      const styles = window.getComputedStyle(el);\n      const height = el.offsetHeight;\n      const borderTopWidth = parseFloat(styles.borderTopWidth);\n      const borderBottomWidth = parseFloat(styles.borderBottomWidth);\n      const paddingTop = parseFloat(styles.paddingTop);\n      const paddingBottom = parseFloat(styles.paddingBottom);\n      return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;\n    }\n\n    // dokładne do części całkowitej（jeżeli `border-box`, wtedy `height - border`; jeżeli `content-box`, wtedy `height + padding`）\n    el.clientHeight;\n\n    // dokładne do części dziesiętnej（jeżeli `border-box`, wtedy `height`; jeżeli `content-box`, wtedy `height + padding + border`）\n    el.getBoundingClientRect().height;\n    ```\n\n- [2.3](#2.3) <a name='2.3'></a> Pozycja i przesunięcie\n\n  + Pozycja\n\n    Otrzymanie bieżącej pozycji elementu relatywnie do przesunięcia rodzica.\n\n    ```js\n    // jQuery\n    $el.position();\n\n    // Natywnie\n    { left: el.offsetLeft, top: el.offsetTop }\n    ```\n\n  + Przesunięcie\n\n    Otrzymanie bieżącej pozycji elementu relatywnie do dokumentu.\n\n    ```js\n    // jQuery\n    $el.offset();\n\n    // Natywnie\n    function getOffset (el) {\n      const box = el.getBoundingClientRect();\n\n      return {\n        top: box.top + window.pageYOffset - document.documentElement.clientTop,\n        left: box.left + window.pageXOffset - document.documentElement.clientLeft\n      };\n    }\n    ```\n\n- [2.4](#2.4) <a name='2.4'></a> Przesunięcie widoku\n\n  Otrzymanie bieżącego przesunięcia w pionie elementu.\n\n  ```js\n  // jQuery\n  $(window).scrollTop();\n\n  // Natywnie\n  (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;\n  ```\n\n**[⬆ wróć](#spis-treści)**\n\n## Manipulacja DOM\n\n- [3.1](#3.1) <a name='3.1'></a> Usuwanie\n\n  Usunięcie elementu z DOM.\n\n  ```js\n  // jQuery\n  $el.remove();\n\n  // Natywnie\n  el.parentNode.removeChild(el);\n  ```\n\n- [3.2](#3.2) <a name='3.2'></a> Tekst\n\n  + Otrzymanie tekstu\n\n    Otrzymanie połączonej zawartości tekstowej elementu, włącznie z jego potomkami,\n\n    ```js\n    // jQuery\n    $el.text();\n\n    // Natywnie\n    el.textContent;\n    ```\n\n  + Ustawianie tekstu\n\n    Ustawianie zawartości tekstowej elementu do wyznaczonej wartości.\n\n    ```js\n    // jQuery\n    $el.text(string);\n\n    // Natywnie\n    el.textContent = string;\n    ```\n\n- [3.3](#3.3) <a name='3.3'></a> HTML\n\n  + Otrzymanie HTML\n\n    ```js\n    // jQuery\n    $el.html();\n\n    // Natywnie\n    el.innerHTML;\n    ```\n\n  + Ustawianie HTML\n\n    ```js\n    // jQuery\n    $el.html(htmlString);\n\n    // Natywnie\n    el.innerHTML = htmlString;\n    ```\n\n- [3.4](#3.4) <a name='3.4'></a> Dodawanie na koniec\n\n  Dodanie elementu jako dziecko po ostatnim dziecku elementu rodzica\n\n  ```js\n  // jQuery\n  $el.append('<div id=\"container\">Hello World</div>');\n\n  // Natywnie (tekst HTML)\n  el.insertAdjacentHTML('beforeend', '<div id=\"container\">Hello World</div>');\n\n  // Natywnie (Element)\n  el.appendChild(newEl);\n  ```\n\n- [3.5](#3.5) <a name='3.5'></a> Dodawanie na początek\n\n  ```js\n  // jQuery\n  $el.prepend('<div id=\"container\">Hello World</div>');\n\n  // Natywnie (tekst HTML)\n  el.insertAdjacentHTML('afterbegin', '<div id=\"container\">Hello World</div>');\n\n  // Natywnie (Element)\n  el.insertBefore(newEl, el.firstChild);\n  ```\n\n- [3.6](#3.6) <a name='3.6'></a> Dodawanie przed\n\n  Dodanie nowego węzła przed wybranymi elementami\n\n  ```js\n  // jQuery\n  $newEl.insertBefore(selector);\n\n  // Natywnie (tekst HTML)\n  el.insertAdjacentHTML('beforebegin ', '<div id=\"container\">Hello World</div>');\n\n  // Natywnie (Element)\n  const el = document.querySelector(selector);\n  if (el.parentNode) {\n    el.parentNode.insertBefore(newEl, el);\n  }\n  ```\n\n- [3.7](#3.7) <a name='3.7'></a> Dodawanie po elemencie\n\n  Dodanie nowego węzła po wybranych elementach\n\n  ```js\n  // jQuery\n  $newEl.insertAfter(selector);\n\n  // Natywnie (tekst HTML)\n  el.insertAdjacentHTML('afterend', '<div id=\"container\">Hello World</div>');\n\n  // Natywnie (Element)\n  const el = document.querySelector(selector);\n  if (el.parentNode) {\n    el.parentNode.insertBefore(newEl, el.nextSibling);\n  }\n  ```\n\n- [3.8](#3.8) <a name='3.8'></a> Porównywanie\n\n  Zwraca `true` jeżeli podany selektor pasuje do wybranego elementu\n\n  ```js\n  // jQuery - Zauważ, że `is` działa również z `function` lub `elements`, które nie są tutaj rozważane\n  $el.is(selector);\n\n  // Natywnie\n  el.matches(selector);\n  ```\n- [3.9](#3.9) <a name='3.9'></a> Kopiowanie\n\n  Tworzenie głębokiej kopii wybranego elementu\n\n  ```js\n  // jQuery\n  $el.clone();\n\n  // Natywnie\n  el.cloneNode();\n\n  // Żeby kopiować głęboko, należy ustawić parametr na `true`\n  ```\n\n- [3.10](#3.10) <a name='3.10'></a> Wyczyszczenie\n\n  Usuwa wszystkie węzły dzieci\n\n  ```js\n  // jQuery\n  $el.empty();\n\n  // Natywnie\n  el.innerHTML = '';\n  ```\n\n- [3.11](#3.11) <a name='3.11'></a> Zawinięcie\n\n  Umieszczenie każdego elementu w strukturze HTML\n\n  ```js\n  // jQuery\n  $('.inner').wrap('<div class=\"wrapper\"></div>');\n\n  // Natywnie\n  Array.prototype.forEach.call(document.querySelectorAll('.inner'), (el) => {\n    const wrapper = document.createElement('div');\n    wrapper.className = 'wrapper';\n    el.parentNode.insertBefore(wrapper, el);\n    el.parentNode.removeChild(el);\n    wrapper.appendChild(el);\n  });\n  ```\n\n- [3.12](#3.12) <a name='3.12'></a> Odwinięcie\n\n  Usuwa rodziców z pasujących elementów z DOM\n\n  ```js\n  // jQuery\n  $('.inner').unwrap();\n\n  // Natywnie\n  Array.prototype.forEach.call(document.querySelectorAll('.inner'), (el) => {\n    Array.prototype.forEach.call(el.childNodes, (child) => {\n      el.parentNode.insertBefore(child, el);\n    });\n    el.parentNode.removeChild(el);\n  });\n  ```\n\n- [3.13](#3.13) <a name='3.13'></a> Zamiana\n\n  Wymiana każdego elementu ze zbioru pasujących elementów na podaną nową zawartość\n\n  ```js\n  // jQuery\n  $('.inner').replaceWith('<div class=\"outer\"></div>');\n\n  // Natywnie\n  Array.prototype.forEach.call(document.querySelectorAll('.inner'), (el) => {\n    const outer = document.createElement('div');\n    outer.className = 'outer';\n    el.parentNode.insertBefore(outer, el);\n    el.parentNode.removeChild(el);\n  });\n  ```\n\n\n**[⬆ powrót](#spis-treści)**\n\n## Ajax\n\n[Fetch API](https://fetch.spec.whatwg.org/) jest nowym standardem mającym zastąpić XMLHttpRequest by wykonować ajax. Obecnie działa na Chrome i Firefox, istnieje możliwość użycia tzw. polyfills (wypełnień) by móc używać tej funkcjonalności w starszych przeglądarkach.\n\nWypróbuj [github/fetch](http://github.com/github/fetch) na IE9+ lub [fetch-ie8](https://github.com/camsong/fetch-ie8/) na IE8+, [fetch-jsonp](https://github.com/camsong/fetch-jsonp) by wykonywać żądania JSONP.\n\n- [4.1](#4.1) <a name='4.1'></a> Ładowanie danych z serwera i umieszczenie zwróconego HTML do pasującego elementu\n\n  ```js\n  // jQuery\n  $(selector).load(url, completeCallback)\n\n  // Natywnie\n  fetch(url).then(data => data.text()).then(data => {\n    document.querySelector(selector).innerHTML = data\n  }).then(completeCallback)\n  ```\n\n**[⬆ powrót](#spis-treści)**\n\n## Zdarzenia\n\nDla pełnego zastąpienia ze wsparciem przestrzenią nazw i delegowaniem, odnieś się do https://github.com/oneuijs/oui-dom-events\n\n- [5.0](#5.0) <a name='5.0'></a> Dokument gotowy ze zdarzeniem `DOMContentLoaded`\n\n  ```js\n  // jQuery\n  $(document).ready(eventHandler);\n\n  // Natywnie\n  // Sprawdź czy zdarzenie DOMContentLoaded został zakończone\n  if (document.readyState !== 'loading') {\n    eventHandler();\n  } else {\n    document.addEventListener('DOMContentLoaded', eventHandler);\n  }\n  ```\n\n- [5.1](#5.1) <a name='5.1'></a> Nasłuchiwanie funkcji na zdarzenie\n\n  ```js\n  // jQuery\n  $el.on(eventName, eventHandler);\n\n  // Natywnie\n  el.addEventListener(eventName, eventHandler);\n  ```\n\n- [5.2](#5.2) <a name='5.2'></a> Zatrzymanie nasłuchiwania\n\n  ```js\n  // jQuery\n  $el.off(eventName, eventHandler);\n\n  // Natywnie\n  el.removeEventListener(eventName, eventHandler);\n  ```\n\n- [5.3](#5.3) <a name='5.3'></a> Wywołanie zdarzenia\n\n  ```js\n  // jQuery\n  $(el).trigger('custom-event', {key1: 'data'});\n\n  // Natywnie\n  if (window.CustomEvent) {\n    const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});\n  } else {\n    const event = document.createEvent('CustomEvent');\n    event.initCustomEvent('custom-event', true, true, {key1: 'data'});\n  }\n\n  el.dispatchEvent(event);\n  ```\n\n**[⬆ powrót](#spis-treści)**\n\n## Funkcje użytkowe\n\nWiększość funkcji użytkowych można znaleźć w natywnym API. Pozostałe, bardziej zaawansowane funkcje mogą zostać zastąpione lepszymi bibliotekami użytkowymi, które skupiają się na spójności i wydajności. Rekomendowaną biblioteką jest [lodash](https://lodash.com).\n\n- [6.1](#6.1) <a name='6.1'></a> Podstawowe funkcje użytkowe\n\n  + isArray\n\n  Sprawdza czy podany argument jest tablicą.\n\n  ```js\n  // jQuery\n  $.isArray(array);\n\n  // Natywnie\n  Array.isArray(array);\n  ```\n\n  + isWindow\n\n  Sprawdza czy podany argument jest oknem.\n\n  ```js\n  // jQuery\n  $.isWindow(obj);\n\n  // Natywnie\n  function isWindow(obj) {\n    return obj !== null && obj !== undefined && obj === obj.window;\n  }\n  ```\n\n  + inArray\n\n  Szuka podanej wartości wewnątrz tablicy i zwraca jej indeks (lub -1 jeżeli nie znaleziono).\n\n  ```js\n  // jQuery\n  $.inArray(item, array);\n\n  // Natywnie\n  array.indexOf(item) > -1;\n\n  // sposób ES6\n  array.includes(item);\n  ```\n\n  + isNumeric\n\n  Sprawdza czy podany argument jest wartością numeryczną.\n  Użyj `typeof` by sprawdzić typ lub przykładu `type` dla większej dokładności.\n\n  ```js\n  // jQuery\n  $.isNumeric(item);\n\n  // Natywnie\n  function isNumeric(value) {\n    var type = typeof value;\n\n    return (type === 'number' || type === 'string') && !Number.isNaN(value - Number.parseFloat(value));\n  }\n  ```\n\n  + isFunction\n\n  Sprawdza czy podany argument jest obiektem funkcji.\n\n  ```js\n  // jQuery\n  $.isFunction(item);\n\n  // Natywnie\n  function isFunction(item) {\n    if (typeof item === 'function') {\n      return true;\n    }\n    var type = Object.prototype.toString(item);\n    return type === '[object Function]' || type === '[object GeneratorFunction]';\n  }\n  ```\n\n  + isEmptyObject\n\n  Sprawdza czy obiekt jest pusty (nie posiada żadnych wymiernych atrybutów).\n\n  ```js\n  // jQuery\n  $.isEmptyObject(obj);\n\n  // Natywnie\n  function isEmptyObject(obj) {\n    return Object.keys(obj).length === 0;\n  }\n  ```\n\n  + isPlainObject\n\n  Sprawdza czy obiekt jest prostym obiektem (stworzonym przy pomocy “{}” lub “new Object”).\n\n  ```js\n  // jQuery\n  $.isPlainObject(obj);\n\n  // Natywnie\n  function isPlainObject(obj) {\n    if (typeof (obj) !== 'object' || obj.nodeType || obj !== null && obj !== undefined && obj === obj.window) {\n      return false;\n    }\n\n    if (obj.constructor &&\n        !Object.prototype.hasOwnProperty.call(obj.constructor.prototype, 'isPrototypeOf')) {\n      return false;\n    }\n\n    return true;\n  }\n  ```\n\n  + extend\n\n  Scalenie zawartości dwóch lub większej ilości obiektów razem w pierwszy obiekt.\n  `Object.assign` należy do API ES6, więc można również użyć [wypełnienia](https://github.com/ljharb/object.assign).\n\n  ```js\n  // jQuery\n  $.extend({}, defaultOpts, opts);\n\n  // Natywnie\n  Object.assign({}, defaultOpts, opts);\n  ```\n\n  + trim\n\n  Usuwa białe znaki z początku i końca ciągu znaków.\n\n  ```js\n  // jQuery\n  $.trim(string);\n\n  // Natywnie\n  string.trim();\n  ```\n\n  + map\n\n  Przekształcenie wszystkich elementów tablicy lub obiektu w nową tablicę.\n\n  ```js\n  // jQuery\n  $.map(array, (value, index) => {\n  });\n\n  // Natywnie\n  array.map((value, index) => {\n  });\n  ```\n\n  + each\n\n  Ogólna funkcja do iteracji, która może być użyta zarówno na obiektach jak i tablicach.\n\n  ```js\n  // jQuery\n  $.each(array, (index, value) => {\n  });\n\n  // Natywnie\n  array.forEach((value, index) => {\n  });\n  ```\n\n  + grep\n\n  Zwraca elementy które przechodzą test podanej funkcji filtrującej.\n\n  ```js\n  // jQuery\n  $.grep(array, (value, index) => {\n  });\n\n  // Natywnie\n  array.filter((value, index) => {\n  });\n  ```\n\n  + type\n\n  Ustala wewnętrzną klasę obiektu.\n\n  ```js\n  // jQuery\n  $.type(obj);\n\n  // Natywnie\n  function type(item) {\n    const reTypeOf = /(?:^\\[object\\s(.*?)\\]$)/;\n    return Object.prototype.toString.call(item)\n      .replace(reTypeOf, '$1')\n      .toLowerCase();\n  }\n  ```\n\n  + merge\n\n  Scala zawartość dwóch tablic w jedną.\n\n  ```js\n  // jQuery\n  $.merge(array1, array2);\n\n  // Natywnie\n  // Funkcja concat nie usuwa duplikatów.\n  function merge(...args) {\n    return [].concat(...args)\n  }\n  ```\n\n  + now\n\n  Zwraca liczbę reprezentującą bieżący czas.\n\n  ```js\n  // jQuery\n  $.now();\n\n  // Natywnie\n  Date.now();\n  ```\n\n  + proxy\n\n  Pobiera funkcję jako argument i zwraca nową funkcję, która będzie miała zawsze określony kontekst.\n\n  ```js\n  // jQuery\n  $.proxy(fn, context);\n\n  // Natywnie\n  fn.bind(context);\n  ```\n\n  + makeArray\n\n  Konwertuje obiekt tablico-podobny w tablicę.\n\n  ```js\n  // jQuery\n  $.makeArray(arrayLike);\n\n  // Natywnie\n  Array.prototype.slice.call(arrayLike);\n\n  // sposób ES6\n  Array.from(arrayLike);\n  ```\n\n- [6.2](#6.2) <a name='6.2'></a> Zawieranie\n\n  Sprawdza czy dany element DOM jest potomkiem innego elementu DOM.\n\n  ```js\n  // jQuery\n  $.contains(el, child);\n\n  // Natywnie\n  el !== child && el.contains(child);\n  ```\n\n- [6.3](#6.3) <a name='6.3'></a> Globalna ewaluacja\n\n  Wykonuje kod Javascript z globalnym kontekstem.\n\n  ```js\n  // jQuery\n  $.globaleval(code);\n\n  // Natywnie\n  function Globaleval(code) {\n    const script = document.createElement('script');\n    script.text = code;\n\n    document.head.appendChild(script).parentNode.removeChild(script);\n  }\n\n  // Używaj eval, chociaż kontekst eval jest lokalny, a kontekst $.Globaleval jest globalny.\n  eval(code);\n  ```\n\n- [6.4](#6.4) <a name='6.4'></a> parse\n\n  + parseHTML\n\n  Przetwarza łańcuch znaków w tablicę węzłów DOM.\n\n  ```js\n  // jQuery\n  $.parseHTML(htmlString);\n\n  // Natywnie\n  function parseHTML(string) {\n    const context = document.implementation.createHTMLDocument();\n\n    // Ustaw href elementu na stworzony dokument, żeby przetworzone elementy z URL\n    // były oparte o URL dokumentu\n    const base = context.createElement('base');\n    base.href = document.location.href;\n    context.head.appendChild(base);\n\n    context.body.innerHTML = string;\n    return context.body.children;\n  }\n  ```\n\n  + parseJSON\n\n  Pobiera ciąg znaków reprezentujący JSON i zwraca wynikową wartość Javascript.\n\n  ```js\n  // jQuery\n  $.parseJSON(str);\n\n  // Natywnie\n  JSON.parse(str);\n  ```\n\n**[⬆ powrót](#spis-treści)**\n\n## Obietnice\n\nObietnice (_ang. Promises_) reprezentują ewentualny wynik asynchronicznej operacji. jQuery posiada własny system zarządzania obietnicami. Natywny Javascript implementuje minimalną warstwę API do obsługi obietnic według specyfikacji [Promises/A+](http://promises-aplus.github.io/promises-spec/).\n\n- [7.1](#7.1) <a name='7.1'></a> done, fail, always\n\n  `done` jest wywoływane gdy obietnica zostanie zakończona sukcesem, `fail` jest wywoływane gdy obietnica jest odrzucona, `always` gdy obietnica jest zakończona z dowolnym wynikiem.\n\n  ```js\n  // jQuery\n  $promise.done(doneCallback).fail(failCallback).always(alwaysCallback)\n\n  // Natywnie\n  promise.then(doneCallback, failCallback).then(alwaysCallback, alwaysCallback)\n  ```\n\n- [7.2](#7.2) <a name='7.2'></a> when\n\n  `when` wykorzystuje się do obsługi wielu obietnic jednocześnie. Zakończy się sukcesem, jeżeli wszystkie podane obietnice zostaną również zakończone sukcesem; zakończy się odrzuceniem, jeżeli jakakolwiek z obietnic zostanie odrzucona.\n\n  ```js\n  // jQuery\n  $.when($promise1, $promise2).done((promise1Result, promise2Result) => {\n  });\n\n  // Natywnie\n  Promise.all([$promise1, $promise2]).then([promise1Result, promise2Result] => {});\n  ```\n\n- [7.3](#7.3) <a name='7.3'></a> Deferred\n\n  Deferred (_pl. Odłożenie_) jest metodą tworzenia obietnic.\n\n  ```js\n  // jQuery\n  function asyncFunc() {\n    const defer = new $.Deferred();\n    setTimeout(() => {\n      if(true) {\n        defer.resolve('some_value_computed_asynchronously');\n      } else {\n        defer.reject('failed');\n      }\n    }, 1000);\n\n    return defer.promise();\n  }\n\n  // Natywnie\n  function asyncFunc() {\n    return new Promise((resolve, reject) => {\n      setTimeout(() => {\n        if (true) {\n          resolve('some_value_computed_asynchronously');\n        } else {\n          reject('failed');\n        }\n      }, 1000);\n    });\n  }\n\n  // sposób z Deferred\n  function defer() {\n    const deferred = {};\n    const promise = new Promise((resolve, reject) => {\n      deferred.resolve = resolve;\n      deferred.reject = reject;\n    });\n\n    deferred.promise = () => {\n      return promise;\n    };\n\n    return deferred;\n  }\n\n  function asyncFunc() {\n    const defer = defer();\n    setTimeout(() => {\n      if(true) {\n        defer.resolve('some_value_computed_asynchronously');\n      } else {\n        defer.reject('failed');\n      }\n    }, 1000);\n\n    return defer.promise();\n  }\n  ```\n\n**[⬆ powrót](#spis-treści)**\n\n## Animacja\n\n- [8.1](#8.1) <a name='8.1'></a> Show i Hide\n\n  ```js\n  // jQuery\n  $el.show();\n  $el.hide();\n\n  // Natywnie\n  // Po więcej szczegółów o tej metodzie odnieś się do https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L363\n  el.style.display = ''|'inline'|'inline-block'|'inline-table'|'block';\n  el.style.display = 'none';\n  ```\n\n- [8.2](#8.2) <a name='8.2'></a> Toggle\n\n  Wyświetla lub ukrywa element.\n\n  ```js\n  // jQuery\n  $el.toggle();\n\n  // Natywnie\n  if (el.ownerDocument.defaultView.getComputedStyle(el, null).display === 'none') {\n    el.style.display = ''|'inline'|'inline-block'|'inline-table'|'block';\n  } else {\n    el.style.display = 'none';\n  }\n  ```\n\n- [8.3](#8.3) <a name='8.3'></a> FadeIn i FadeOut\n\n  ```js\n  // jQuery\n  $el.fadeIn(3000);\n  $el.fadeOut(3000);\n\n  // Natywnie\n  el.style.transition = 'opacity 3s';\n  // FadeIn\n  el.style.opacity = '1';\n  // FadeOut\n  el.style.opacity = '0';\n  ```\n\n- [8.4](#8.4) <a name='8.4'></a> FadeTo\n\n  Dostosowuje przezroczystość elementu w czasie.\n\n  ```js\n  // jQuery\n  $el.fadeTo('slow',0.15);\n  // Natywnie\n  el.style.transition = 'opacity 3s'; // przyjęto że 'slow' trwa 3 sekundy\n  el.style.opacity = '0.15';\n  ```\n\n- [8.5](#8.5) <a name='8.5'></a> FadeToggle\n\n  Wyświetla lub ukrywa element przez animowanie jego przezroczystości.\n\n  ```js\n  // jQuery\n  $el.fadeToggle();\n\n  // Natywnie\n  el.style.transition = 'opacity 3s';\n  const { opacity } = el.ownerDocument.defaultView.getComputedStyle(el, null);\n  if (opacity === '1') {\n    el.style.opacity = '0';\n  } else {\n    el.style.opacity = '1';\n  }\n  ```\n\n- [8.6](#8.6) <a name='8.6'></a> SlideUp i SlideDown\n\n  ```js\n  // jQuery\n  $el.slideUp();\n  $el.slideDown();\n\n  // Natywnie\n  const originHeight = '100px';\n  el.style.transition = 'height 3s';\n  // slideUp\n  el.style.height = '0px';\n  // slideDown\n  el.style.height = originHeight;\n  ```\n\n- [8.7](#8.7) <a name='8.7'></a> SlideToggle\n\n  Wyświetla lub ukrywa element przez przesunięcie.\n\n  ```js\n  // jQuery\n  $el.slideToggle();\n\n  // Natywnie\n  const originHeight = '100px';\n  el.style.transition = 'height 3s';\n  const { height } = el.ownerDocument.defaultView.getComputedStyle(el, null);\n  if (parseInt(height, 10) === 0) {\n    el.style.height = originHeight;\n  }\n  else {\n    el.style.height = '0px';\n  }\n  ```\n\n- [8.8](#8.8) <a name='8.8'></a> Animate\n\n  Wykonuje własną animację zbioru atrybutów CSS.\n\n  ```js\n  // jQuery\n  $el.animate({ params }, speed);\n\n  // Natywnie\n  el.style.transition = 'all ' + speed;\n  Object.keys(params).forEach((key) => {\n    el.style[key] = params[key];\n  });\n  ```\n\n## Alternatywy\n\n* [You Might Not Need jQuery](http://youmightnotneedjquery.com/) - Przykłady wykonania powszechnych zdarzeń, elementów, ajax itd. z użyciem zwykłego Javascript.\n* [npm-dom](http://github.com/npm-dom) oraz [webmodules](http://github.com/webmodules) - Indywidualne moduły DOM na NPM.\n\n## Wsparcie przeglądarek\n\n![Chrome][chrome-image] | ![Firefox][firefox-image] | ![IE][ie-image] | ![Opera][opera-image] | ![Safari][safari-image]\n--- | --- | --- | --- | --- |\nLatest ✔ | Latest ✔ | 10+ ✔ | Latest ✔ | 6.1+ ✔ |\n\n# Licencja\n\nMIT\n\n[chrome-image]: https://raw.github.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png\n[firefox-image]: https://raw.github.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png\n[ie-image]: https://raw.github.com/alrra/browser-logos/master/src/archive/internet-explorer_9-11/internet-explorer_9-11_48x48.png\n[opera-image]: https://raw.github.com/alrra/browser-logos/master/src/opera/opera_48x48.png\n[safari-image]: https://raw.github.com/alrra/browser-logos/master/src/safari/safari_48x48.png\n"
  },
  {
    "path": "README-ru.md",
    "content": "## Вам не нужен jQuery\n\nВ наше время среда front-end разработки быстро развивается, и современные браузеры достаточно хорошо реализовали работу с DOM/BOM API. Вам не нужно изучать jQuery с нуля для манипуляцией DOM'ом или объектами событий. В то же время, благодаря лидирующим front-end библиотекам, таким как React, Angular и Vue, манипуляция DOM'ом напрямую становится антипаттерном, а jQuery теряет свою значимость. Этот проект объединяет большинство альтернативных методов jQuery в нативном исполнении с поддержкой IE 10+.\n\n## Содержание\n\n1. [Переводы](#Переводы)\n1. [Query Selector](#query-selector)\n1. [CSS & Style](#css--style)\n1. [Манипуляция с DOM](#манипуляции-с-dom)\n1. [Ajax](#ajax)\n1. [События](#События)\n1. [Утилиты](#Утилиты)\n1. [Альтернативы](#Альтернативы)\n1. [Поддержка браузеров](#Поддержка-браузеров)\n\n## Переводы\n\n* [한국어](./README.ko-KR.md)\n* [正體中文](./README.zh-TW.md)\n* [简体中文](./README.zh-CN.md)\n* [Bahasa Melayu](./README-my.md)\n* [Bahasa Indonesia](./README-id.md)\n* [Português(PT-BR)](./README.pt-BR.md)\n* [Tiếng Việt Nam](./README-vi.md)\n* [Español](./README-es.md)\n* [Русский](./README-ru.md)\n* [Кыргызча](./README-kg.md)\n* [Türkçe](./README-tr.md)\n* [Italiano](./README-it.md)\n* [Français](./README-fr.md)\n* [日本語](./README-ja.md)\n* [Polski](./README-pl.md)\n\n## Query Selector\n\nДля часто используемых селекторов, таких как class, id или attribute мы можем использовать `document.querySelector` или `document.querySelectorAll` для замены. Разница такова:\n* `document.querySelector` возвращает первый совпавший элемент\n* `document.querySelectorAll` возвращает все совпавшие элементы как список узлов (NodeList). Его можно конвертировать в массив, используя `Array.prototype.slice.call(document.querySelectorAll(selector));`\n* Если никакие элементы не совпадут, jQuery и `document.querySelectorAll` вернет `[]` где `document.querySelector` вернет `null`.\n\n> Заметка: `document.querySelector` и `document.querySelectorAll` достаточно **МЕДЛЕННЫ**, старайтесь использовать `getElementById`, `document.getElementsByClassName` или `document.getElementsByTagName` если хотите улучшить производительность.\n\n- [1.0](#1.0) <a name='1.0'></a> Query by selector\n\n  ```js\n  // jQuery\n  $('selector');\n\n  // Нативно\n  document.querySelectorAll('selector');\n  ```\n\n- [1.1](#1.1) <a name='1.1'></a> Запрос по классу\n\n  ```js\n  // jQuery\n  $('.class');\n\n  // Нативно\n  document.querySelectorAll('.class');\n\n  // или\n  document.getElementsByClassName('class');\n  ```\n\n- [1.2](#1.2) <a name='1.2'></a> Запрос по ID\n\n  ```js\n  // jQuery\n  $('#id');\n\n  // Нативно\n  document.querySelector('#id');\n\n  // или\n  document.getElementById('id');\n  ```\n\n- [1.3](#1.3) <a name='1.3'></a> Запрос по атрибуту\n\n  ```js\n  // jQuery\n  $('a[target=_blank]');\n\n  // Нативно\n  document.querySelectorAll('a[target=_blank]');\n  ```\n\n- [1.4](#1.4) <a name='1.4'></a> Найти среди потомков\n\n  ```js\n  // jQuery\n  $el.find('li');\n\n  // Нативно\n  el.querySelectorAll('li');\n  ```\n\n- [1.5](#1.5) <a name='1.5'></a> Родственные/Предыдущие/Следующие Элементы\n\n  + Родственные элементы\n\n    ```js\n    // jQuery\n    $el.siblings();\n\n    // Нативно\n    Array.prototype.filter.call(el.parentNode.children, (child) =>\n      child !== el\n    );\n    ```\n\n  + Предыдущие элементы\n\n    ```js\n    // jQuery\n    $el.prev();\n\n    // Нативно\n    el.previousElementSibling;\n    ```\n\n  + Следующие элементы\n\n    ```js\n    // jQuery\n    $el.next();\n\n    // Нативно\n    el.nextElementSibling;\n    ```\n\n- [1.6](#1.6) <a name='1.6'></a> Ближайший\n\n  Возвращает первый совпавший элемент по предоставленному селектору, проходя от текущего элемента до документа.\n\n  ```js\n  // jQuery\n  $el.closest(selector);\n\n  // Нативно - только последние версии браузеров, без IE\n  el.closest(selector);\n\n  // Нативно - IE10+\n  function closest(el, selector) {\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    while (el) {\n      if (matchesSelector.call(el, selector)) {\n        return el;\n      } else {\n        el = el.parentElement;\n      }\n    }\n    return null;\n  }\n  ```\n\n- [1.7](#1.7) <a name='1.7'></a> Родители до\n\n  Получить родителей каждого элемента в текущем результате совпавших элементов, но не включая элемент, совпавший с указанным селектором, узлом DOM'а, или объектом jQuery.\n\n  ```js\n  // jQuery\n  $el.parentsUntil(selector, filter);\n\n  // Нативно\n  function parentsUntil(el, selector, filter) {\n    const result = [];\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    // Совпадать начиная от родителя\n    el = el.parentElement;\n    while (el && !matchesSelector.call(el, selector)) {\n      if (!filter) {\n        result.push(el);\n      } else {\n        if (matchesSelector.call(el, filter)) {\n          result.push(el);\n        }\n      }\n      el = el.parentElement;\n    }\n    return result;\n  }\n  ```\n\n- [1.8](#1.8) <a name='1.8'></a> Форма\n\n  + Input/Textarea\n\n    ```js\n    // jQuery\n    $('#my-input').val();\n\n    // Нативно\n    document.querySelector('#my-input').value;\n    ```\n\n  + Получить индекс e.currentTarget между `.radio`\n\n    ```js\n    // jQuery\n    $('.radio').index(e.currentTarget);\n\n    // Нативно\n    Array.prototype.indexOf.call(document.querySelectorAll('.radio'), e.currentTarget);\n    ```\n\n- [1.9](#1.9) <a name='1.9'></a> Содержимое Iframe\n\n  `$('iframe').contents()` возвращает `contentDocument` именно для этого iframe\n\n  + Контент Iframe\n\n    ```js\n    // jQuery\n    $iframe.contents();\n\n    // Нативно\n    iframe.contentDocument;\n    ```\n\n  + Iframe Query\n\n    ```js\n    // jQuery\n    $iframe.contents().find('.css');\n\n    // Нативно\n    iframe.contentDocument.querySelectorAll('.css');\n    ```\n\n- [1.10](#1.10) <a name='1.10'></a> Найти body\n\n  ```js\n  // jQuery\n  $('body');\n\n  // Нативно\n  document.body;\n  ```\n\n- [1.11](#1.11) <a name='1.11'></a> Получение и изменение атрибута\n\n  + Найти атрибут\n\n    ```js\n    // jQuery\n    $el.attr('foo');\n\n    // Нативно\n    el.getAttribute('foo');\n    ```\n  + Добавление атрибута\n\n    ```js\n    // jQuery, помните, это происходит в памяти без изменения DOM\n    $el.attr('foo', 'bar');\n\n    // Нативно\n    el.setAttribute('foo', 'bar');\n    ```\n\n  + Найти `data-` атрибут\n\n    ```js\n    // jQuery\n    $el.data('foo');\n\n    // Нативно (используя `getAttribute`)\n    el.getAttribute('data-foo');\n\n    // Нативно (используя `dataset`, если не требуется поддержка ниже IE 11)\n    el.dataset['foo'];\n    ```\n\n**[⬆ Наверх](#Содержание)**\n\n## CSS & Style\n\n- [2.1](#2.1) <a name='2.1'></a> CSS\n\n  + Получить стили\n\n    ```js\n    // jQuery\n    $el.css('color');\n\n    // Нативно\n    // ЗАМЕТКА: Известная ошибка, возвращает 'auto' если значение стиля 'auto'\n    const win = el.ownerDocument.defaultView;\n\n    // null означает не возвращать псевдостили\n    win.getComputedStyle(el, null).color;\n    ```\n\n  + Присвоение style\n\n    ```js\n    // jQuery\n    $el.css({ color: '#f01' });\n\n    // Нативно\n    el.style.color = '#f01';\n    ```\n\n  + Получение/Присвоение стилей\n\n    Заметьте что если вы хотите присвоить несколько стилей за раз, вы можете сослаться на [setStyles](https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L194) метод в пакете oui-dom-utils.\n\n\n  + Добавить класс\n\n    ```js\n    // jQuery\n    $el.addClass(className);\n\n    // Нативно\n    el.classList.add(className);\n    ```\n\n  + Удалить class\n\n    ```js\n    // jQuery\n    $el.removeClass(className);\n\n    // Нативно\n    el.classList.remove(className);\n    ```\n\n  + Имеет ли класс\n\n    ```js\n    // jQuery\n    $el.hasClass(className);\n\n    // Нативно\n    el.classList.contains(className);\n    ```\n\n  + Переключить класс\n\n    ```js\n    // jQuery\n    $el.toggleClass(className);\n\n    // Нативно\n    el.classList.toggle(className);\n    ```\n\n- [2.2](#2.2) <a name='2.2'></a> Ширина и Высота\n\n  Ширина и высота теоретически имеют общие свойства, например возьмем высоту:\n\n  + Высота окна\n\n    ```js\n    // Высота окна\n    $(window).height();\n\n    // без полосы прокрутки, ведет себя как jQuery\n    window.document.documentElement.clientHeight;\n\n    // вместе с полосой прокрутки\n    window.innerHeight;\n    ```\n\n  + Высота документа\n\n    ```js\n    // jQuery\n    $(document).height();\n\n    // Нативно\n    const body = document.body;\n    const html = document.documentElement;\n    const height = Math.max(\n      body.offsetHeight,\n      body.scrollHeight,\n      html.clientHeight,\n      html.offsetHeight,\n      html.scrollHeight\n    );\n    ```\n\n  + Высота элемента\n\n    ```js\n    // jQuery\n    $el.height();\n\n    // Нативно\n    function getHeight(el) {\n      const styles = window.getComputedStyle(el);\n      const height = el.offsetHeight;\n      const borderTopWidth = parseFloat(styles.borderTopWidth);\n      const borderBottomWidth = parseFloat(styles.borderBottomWidth);\n      const paddingTop = parseFloat(styles.paddingTop);\n      const paddingBottom = parseFloat(styles.paddingBottom);\n      return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;\n    }\n\n    // С точностью до целого числа（когда `border-box`, это `height - border`; когда `content-box`, это `height + padding`）\n    el.clientHeight;\n\n    // С точностью до десятых（когда `border-box`, это `height`; когда `content-box`, это `height + padding + border`）\n    el.getBoundingClientRect().height;\n    ```\n\n- [2.3](#2.3) <a name='2.3'></a> Позиция и смещение\n\n  + Position\n\n    Получить текущие координаты элемента относительно смещения его родителя\n\n    ```js\n    // jQuery\n    $el.position();\n\n    // Нативно\n    { left: el.offsetLeft, top: el.offsetTop }\n    ```\n\n  + Offset\n\n    Получить текущие координаты элемента относительно документа\n\n    ```js\n    // jQuery\n    $el.offset();\n\n    // Нативно\n    function getOffset (el) {\n      const box = el.getBoundingClientRect();\n\n      return {\n        top: box.top + window.pageYOffset - document.documentElement.clientTop,\n        left: box.left + window.pageXOffset - document.documentElement.clientLeft\n      };\n    }\n    ```\n\n- [2.4](#2.4) <a name='2.4'></a> Прокрутка вверх\n\n  ```js\n  // jQuery\n  $(window).scrollTop();\n\n  // Нативно\n  (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;\n  ```\n\n**[⬆ Наверх](#Содержание)**\n\n## Манипуляции с DOM\n\n- [3.1](#3.1) <a name='3.1'></a> Remove\n\n  Удаление элемента из DOM.\n\n  ```js\n  // jQuery\n  $el.remove();\n\n  // Нативно\n  el.parentNode.removeChild(el);\n  ```\n\n- [3.2](#3.2) <a name='3.2'></a> Text\n\n  + Получить текст\n\n    Получить текстовое содержимое элемента, включая его потомков,\n\n    ```js\n    // jQuery\n    $el.text();\n\n    // Нативно\n    el.textContent;\n    ```\n\n  + Присвоить текст\n\n    ```js\n    // jQuery\n    $el.text(string);\n\n    // Нативно\n    el.textContent = string;\n    ```\n\n- [3.3](#3.3) <a name='3.3'></a> HTML\n\n  + Получить HTML\n\n    ```js\n    // jQuery\n    $el.html();\n\n    // Нативно\n    el.innerHTML;\n    ```\n\n  + Присвоить HTML\n\n    ```js\n    // jQuery\n    $el.html(htmlString);\n\n    // Нативно\n    el.innerHTML = htmlString;\n    ```\n\n- [3.4](#3.4) <a name='3.4'></a> Append\n\n  Добавить родительскому элементу новый дочерний элемент.\n\n  ```js\n  // jQuery\n  $el.append('<div id=\"container\">Hello World</div>');\n\n  // Нативно (строка HTML)\n  el.insertAdjacentHTML('beforeend', '<div id=\"container\">Hello World</div>');\n\n  // Нативно (элемент)\n  el.appendChild(newEl);\n  ```\n\n- [3.5](#3.5) <a name='3.5'></a> Prepend\n\n\tДобавить родительскому элементу новый дочерний элемент перед остальными\n\n  ```js\n  // jQuery\n  $el.prepend('<div id=\"container\">Hello World</div>');\n\n  // Нативно (строка HTML)\n  el.insertAdjacentHTML('afterbegin', '<div id=\"container\">Hello World</div>');\n\n  // Нативно (элемент)\n  el.insertBefore(newEl, el.firstChild);\n  ```\n\n- [3.6](#3.6) <a name='3.6'></a> insertBefore\n\n  Вставка нового элемента перед выбранным элементом\n\n  ```js\n  // jQuery\n  $newEl.insertBefore(selector);\n\n  // Нативно (строка HTML)\n  el.insertAdjacentHTML('beforebegin ', '<div id=\"container\">Hello World</div>');\n\n  // Нативно (элемент)\n  const el = document.querySelector(selector);\n  if (el.parentNode) {\n    el.parentNode.insertBefore(newEl, el);\n  }\n  ```\n\n- [3.7](#3.7) <a name='3.7'></a> insertAfter\n\n  Вставка новго элемента после выбранного элемента\n\n  ```js\n  // jQuery\n  $newEl.insertAfter(selector);\n\n  // Нативно (строка HTML)\n  el.insertAdjacentHTML('afterend', '<div id=\"container\">Hello World</div>');\n\n  // Нативно (элемент)\n  const el = document.querySelector(selector);\n  if (el.parentNode) {\n    el.parentNode.insertBefore(newEl, el.nextSibling);\n  }\n  ```\n\n- [3.8](#3.8) <a name='3.8'></a> is\n\n  Возвращает `true` если  совпадает с селектором запроса\n\n  ```js\n  // jQuery - заметьте что `is` так же работает с `function` или `elements` которые не имеют к этому отношения\n  $el.is(selector);\n\n  // Нативно\n  el.matches(selector);\n  ```\n\n**[⬆ Наверх](#Содержание)**\n\n## Ajax\n\n[Fetch API](https://fetch.spec.whatwg.org/) - новый стандарт, заменяющий XMLHttpRequest для ajax. Работает в Chrome и Firefox, вы можете использовать полифилы, для поддержки старых браузеров.\n\nПопробуйте [github/fetch](http://github.com/github/fetch) для IE9+ или [fetch-ie8](https://github.com/camsong/fetch-ie8/) для IE8+, [fetch-jsonp](https://github.com/camsong/fetch-jsonp) для JSONP-запросов.\n\n- [4.1](#4.1) <a name='4.1'></a> Загрузить данные с сервера и поместить полученный HTML в элемент.\n\n  ```js\n  // jQuery\n  $(selector).load(url, completeCallback)\n\n  // Нативно\n  fetch(url).then(data => data.text()).then(data => {\n    document.querySelector(selector).innerHTML = data\n  }).then(completeCallback)\n  ```\n\n**[⬆ Наверх](#Содержание)**\n\n## События\n\nДля полной замены пространства имен и делегирования, используйте  [oui-dom-events](https://github.com/oneuijs/oui-dom-events)\n\n- [5.0](#5.0) <a name='5.0'></a> Готовность документа по событию `DOMContentLoaded`\n\n  ```js\n  // jQuery\n  $(document).ready(eventHandler);\n\n  // Нативно\n  // Проверяем, что событие DOMContentLoaded было выполнено\n  if (document.readyState !== 'loading') {\n    eventHandler();\n  } else {\n    document.addEventListener('DOMContentLoaded', eventHandler);\n  }\n  ```\n\n- [5.1](#5.1) <a name='5.1'></a> Связать событие используя `on`\n\n  ```js\n  // jQuery\n  $el.on(eventName, eventHandler);\n\n  // Нативно\n  el.addEventListener(eventName, eventHandler);\n  ```\n\n- [5.2](#5.2) <a name='5.2'></a> Отвязать событие используя `off`\n\n  ```js\n  // jQuery\n  $el.off(eventName, eventHandler);\n\n  // Нативно\n  el.removeEventListener(eventName, eventHandler);\n  ```\n\n- [5.3](#5.3) <a name='5.3'></a> Trigger\n\n  ```js\n  // jQuery\n  $(el).trigger('custom-event', {key1: 'data'});\n\n  // Нативно\n  if (window.CustomEvent) {\n    const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});\n  } else {\n    const event = document.createEvent('CustomEvent');\n    event.initCustomEvent('custom-event', true, true, {key1: 'data'});\n  }\n\n  el.dispatchEvent(event);\n  ```\n\n**[⬆ Наверх](#Содержание)**\n\n## Утилиты\n\nБольшинство из утилит, представленных в jQuery также могут быть найдены в нативном API. Более продвинутые функции могут быть выбраны из других, более актуальных библиотек, направленных на согласованность данных и производительность. Например, [Lodash](https://lodash.com) является рекомендуемой заменой.\n\n- [6.1](#6.1) <a name='6.1'></a> Basic utilities\n\n  + isArray\n\n  Определить, является ли аргумент массивом.\n\n  ```js\n  // jQuery\n  $.isArray(array);\n\n  // Нативно\n  Array.isArray(array);\n  ```\n+ isWindow\n\n  Определить, является ли аргумент окном.\n\n  ```js\n  // jQuery\n  $.isWindow(obj);\n\n  // Нативно\n  function isWindow(obj) {\n    return obj !== null && obj !== undefined && obj === obj.window;\n  }\n  ```\n\n  + inArray\n\n Поиск определенного значения в массиве и возвращение его индекса (или -1 если значение не найдено)\n\n  ```js\n  // jQuery\n  $.inArray(item, array);\n\n  // Нативно\n  array.indexOf(item) > -1;\n\n  // В нотации ES6\n  array.includes(item);\n  ```\n\n  + isNumeric\n\n  Determine if the argument passed is numerical.\n  Use `typeof` to decide the type or the `type` example for better accuracy. Определить, является ли переданный аргумент числовым. Используйте `typeof` для определения типа или `type` для большей точности.\n\n  ```js\n  // jQuery\n  $.isNumeric(item);\n\n  // Нативно\n  function isNumeric(n) {\n    return !isNaN(parseFloat(n)) && isFinite(n);\n  }\n  ```\n\n  + isFunction\n\n  Определить,  является ли переданный аргумент функцией(объектом) JavaScript.\n\n  ```js\n  // jQuery\n  $.isFunction(item);\n\n  // Нативно\n  function isFunction(item) {\n    if (typeof item === 'function') {\n      return true;\n    }\n    var type = Object.prototype.toString.call(item);\n    return type === '[object Function]' || type === '[object GeneratorFunction]';\n  }\n  ```\n\n  + isEmptyObject\n\n  Проверить, является ли объект пустым (не содержащим перечесляемых свойств)\n\n  ```js\n  // jQuery\n  $.isEmptyObject(obj);\n\n  // Нативно\n  function isEmptyObject(obj) {\n    return Object.keys(obj).length === 0;\n  }\n  ```\n\n  + isPlainObject\n\n  Проверить, является ли объект простым / 'ванильным' (созданным с помощью “{}” или “new Object”)\n\n  ```js\n  // jQuery\n  $.isPlainObject(obj);\n\n  // Нативно\n  function isPlainObject(obj) {\n    if (typeof (obj) !== 'object' || obj.nodeType || obj !== null && obj !== undefined && obj === obj.window) {\n      return false;\n    }\n\n    if (obj.constructor &&\n        !Object.prototype.hasOwnProperty.call(obj.constructor.prototype, 'isPrototypeOf')) {\n      return false;\n    }\n\n    return true;\n  }\n  ```\n\n  + extend\n\n  Объединить содержимое двух или более объектов в новый объект, не изменяя ни один из аргументов.\n  object.assign является частью ES6 API, также можно использовать [полифилл](https://github.com/ljharb/object.assign).\n\n  ```js\n  // jQuery\n  $.extend({}, object1, object2);\n\n  // Нативно\n  Object.assign({}, object1, object2);\n  ```\n\n  + trim\n\n  Убрать символы пробелов из начала и конца строки.\n\n  ```js\n  // jQuery\n  $.trim(string);\n\n  // Нативно\n  string.trim();\n  ```\n\n  + map\n\n  Преобразовать все элементы массива или объекта в новый массив.\n\n  ```js\n  // jQuery\n  $.map(array, (value, index) => {\n  });\n\n  // Нативно\n  array.map((value, index) => {\n  });\n  ```\n\n  + each\n\n  Общая (generic) функция итератора, которую можно использовать для последовательной итерации как по объектам, так и по массивам.\n\n  ```js\n  // jQuery\n  $.each(array, (index, value) => {\n  });\n\n  // Нативно\n  array.forEach((value, index) => {\n  });\n  ```\n\n  + grep\n\n  Найти элементы массива которые удовлетворяют функции-фильтру.\n\n  ```js\n  // jQuery\n  $.grep(array, (value, index) => {\n  });\n\n  // Нативно\n  array.filter((value, index) => {\n  });\n  ```\n\n  + type\n\n  Определите внутренний класс JavaScript объекта.\n\n  ```js\n  // jQuery\n  $.type(obj);\n\n  // Нативно\n  function type(item) {\n    const reTypeOf = /(?:^\\[object\\s(.*?)\\]$)/;\n    return Object.prototype.toString.call(item)\n      .replace(reTypeOf, '$1')\n      .toLowerCase();\n  }\n  ```\n\n  + merge\n\n  Объединить содержимое двух массивов в первый массив.\n\n  ```js\n  // jQuery, не удаляя дубликаты\n  $.merge(array1, array2);\n\n  // Нативно, не удаляя дубликаты\n  function merge(...args) {\n    return [].concat(...args)\n  }\n\n  // В нотации ES6, не удаляя дубликаты\n  array1 = [...array1, ...array2]\n\n  // Версия с удалением дубликатов\n  function merge(...args) {\n    return Array.from(new Set([].concat(...args)))\n  }\n  ```\n\n  + now\n\n  Вернуть текущее время в числовом формате.\n\n  ```js\n  // jQuery\n  $.now();\n\n  // Нативно\n  Date.now();\n  ```\n\n  + proxy\n\n  По заданной функции, создает другую такую же, cохраняя контекст.\n\n  ```js\n  // jQuery\n  $.proxy(fn, context);\n\n  // Нативно\n  fn.bind(context);\n  ```\n\n  <a name=\"makeArray\"></a>+ makeArray\n\n  Конвертирует объекты, похожие на массивы, в массивы JavaScript.\n\n  ```js\n  // jQuery\n  $.makeArray(arrayLike);\n\n  // Нативно\n  Array.prototype.slice.call(arrayLike);\n\n  // В нотации ES6: Array.from() метод\n  Array.from(arrayLike);\n\n  // В нотации ES6: используя оператор распространения\n  [...arrayLike];\n  ```\n\n- [6.2](#6.2) <a name='6.2'></a> Contains\n\n  Проверяет, не является ли элемент DOM потомком другого элемента DOM.\n\n  ```js\n  // jQuery\n  $.contains(el, child);\n\n  // Нативно\n  el !== child && el.contains(child);\n  ```\n\n- [6.3](#6.3) <a name='6.3'></a> Globaleval\n\n  Исполняет определенный JavaScript код глобально.\n\n  ```js\n  // jQuery\n  $.globaleval(code);\n\n  // Нативно\n  function Globaleval(code) {\n    const script = document.createElement('script');\n    script.text = code;\n\n    document.head.appendChild(script).parentNode.removeChild(script);\n  }\n\n  // Используем eval, учитывая, что контекст eval текущий, а контекст $.Globaleval глобальный.\n  eval(code);\n  ```\n\n- [6.4](#6.4) <a name='6.4'></a> parse\n\n  + parseHTML\n\n  Разбирает строку в массив узлов DOM.\n\n  ```js\n  // jQuery\n  $.parseHTML(htmlString);\n\n  // Нативно\n  function parseHTML(string) {\n    const context = document.implementation.createHTMLDocument();\n\n    // Устанавливает базовую ссылку для созданного документа, чтобы любые проанализированные элементы с URL-адресами\n    // основывались на URL-адресе документа.\n    const base = context.createElement('base');\n    base.href = document.location.href;\n    context.head.appendChild(base);\n\n    context.body.innerHTML = string;\n    return context.body.children;\n  }\n  ```\n- [6.5](#6.4) <a name='6.5'></a> exists\n\n+ exists\n\n  Проверяет, существует ли элемент в DOM.\n\n  ```js\n  // jQuery\n  if ($('selector').length) {\n     // exists\n  }\n\n  // Нативно\n  var element =  document.getElementById('elementId');\n  if (typeof(element) != 'undefined' && element != null)\n  {\n     // exists\n  }\n  ```\n\n**[⬆ Наверх](#Содержание)**\n\n## Промисы (Promises)\n\nПромисы предоставляют собой удобный способ организации асинхронного кода. У jQuery есть свой способ обработки промисов. Нативный JavaScript реализует тонкий и минимальный API для обработки промисов в соответствии с [Promises/A+](http://promises-aplus.github.io/promises-spec/) спецификацией.\n\n- [7.1](#7.1) <a name='7.1'></a> done, fail, always\n\n  `done` вызывается, когда промис разрешен,` fail` вызывается, когда промис отклонен, `always` вызывается, когда промис либо разрешен, либо отклонен.\n\n  ```js\n  // jQuery\n  $promise.done(doneCallback).fail(failCallback).always(alwaysCallback)\n\n  // Нативно\n  promise.then(doneCallback, failCallback).then(alwaysCallback, alwaysCallback)\n  ```\n\n- [7.2](#7.2) <a name='7.2'></a> when\n\n  `when` используется для обработки нескольких промисов. Он разрешится, когда будут выполнены все промисы, и отклонится, если один из промисов будет отклонен.\n\n  ```js\n  // jQuery\n  $.when($promise1, $promise2).done((promise1Result, promise2Result) => {\n  });\n\n  // Нативно\n  Promise.all([$promise1, $promise2]).then([promise1Result, promise2Result] => {});\n  ```\n\n- [7.3](#7.3) <a name='7.3'></a> Deferred\n\n  Отложенный способ создания промисов.\n\n  ```js\n  // jQuery\n  function asyncFunc() {\n    const defer = new $.Deferred();\n    setTimeout(() => {\n      if(true) {\n        defer.resolve('some_value_computed_asynchronously');\n      } else {\n        defer.reject('failed');\n      }\n    }, 1000);\n\n    return defer.promise();\n  }\n\n  // Нативно\n  function asyncFunc() {\n    return new Promise((resolve, reject) => {\n      setTimeout(() => {\n        if (true) {\n          resolve('some_value_computed_asynchronously');\n        } else {\n          reject('failed');\n        }\n      }, 1000);\n    });\n  }\n\n  // Отложенным способом\n  function defer() {\n    const deferred = {};\n    const promise = new Promise((resolve, reject) => {\n      deferred.resolve = resolve;\n      deferred.reject = reject;\n    });\n\n    deferred.promise = () => {\n      return promise;\n    };\n\n    return deferred;\n  }\n\n  function asyncFunc() {\n    const defer = defer();\n    setTimeout(() => {\n      if(true) {\n        defer.resolve('some_value_computed_asynchronously');\n      } else {\n        defer.reject('failed');\n      }\n    }, 1000);\n\n    return defer.promise();\n  }\n  ```\n\n**[⬆ Наверх](#Содержание)**\n\n## Анимации\n\n- [8.1](#8.1) <a name='8.1'></a> Show & Hide\n\n  ```js\n  // jQuery\n  $el.show();\n  $el.hide();\n\n  // Нативно\n  // За дополнительной информацией о методе show, пройдите по ссылке https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L363\n  el.style.display = ''|'inline'|'inline-block'|'inline-table'|'block';\n  el.style.display = 'none';\n  ```\n\n- [8.2](#8.2) <a name='8.2'></a> Toggle\n\n  Показать или скрыть элемент.\n\n  ```js\n  // jQuery\n  $el.toggle();\n\n  // Нативно\n  if (el.ownerDocument.defaultView.getComputedStyle(el, null).display === 'none') {\n    el.style.display = ''|'inline'|'inline-block'|'inline-table'|'block';\n  } else {\n    el.style.display = 'none';\n  }\n  ```\n\n- [8.3](#8.3) <a name='8.3'></a> FadeIn & FadeOut\n\n  ```js\n  // jQuery\n  $el.fadeIn(3000);\n  $el.fadeOut(3000);\n\n  // Нативный fadeOut (исчезновение)\n  function fadeOut(el, ms) {\n    if (ms) {\n      el.style.transition = `opacity ${ms} ms`;\n      el.addEventListener(\n        'transitionend',\n        function(event) {\n          el.style.display = 'none';\n        },\n        false\n      );\n    }\n    el.style.opacity = '0';\n  }\n\n  // Нативный fadeIn (появление)\n  function fadeIn(elem, ms) {\n    elem.style.opacity = 0;\n\n    if (ms) {\n      let opacity = 0;\n      const timer = setInterval(function() {\n        opacity += 50 / ms;\n        if (opacity >= 1) {\n          clearInterval(timer);\n          opacity = 1;\n        }\n        elem.style.opacity = opacity;\n      }, 50);\n    } else {\n      elem.style.opacity = 1;\n    }\n  }\n  ```\n\n- [8.4](#8.4) <a name='8.4'></a> FadeTo\n\n  Регулировка непрозрачности элемента.\n\n  ```js\n  // jQuery\n  $el.fadeTo('slow',0.15);\n  // Нативно\n  el.style.transition = 'opacity 3s'; // assume 'slow' equals 3 seconds\n  el.style.opacity = '0.15';\n  ```\n\n- [8.5](#8.5) <a name='8.5'></a> FadeToggle\n\n  Отображение или скрытие элемента через изменение его непрозрачности.\n\n  ```js\n  // jQuery\n  $el.fadeToggle();\n\n  // Нативно\n  el.style.transition = 'opacity 3s';\n  const { opacity } = el.ownerDocument.defaultView.getComputedStyle(el, null);\n  if (opacity === '1') {\n    el.style.opacity = '0';\n  } else {\n    el.style.opacity = '1';\n  }\n  ```\n\n- [8.6](#8.6) <a name='8.6'></a> SlideUp & SlideDown\n\n  ```js\n  // jQuery\n  $el.slideUp();\n  $el.slideDown();\n\n  // Нативно\n  const originHeight = '100px';\n  el.style.transition = 'height 3s';\n  // slideUp\n  el.style.height = '0px';\n  // slideDown\n  el.style.height = originHeight;\n  ```\n\n- [8.7](#8.7) <a name='8.7'></a> SlideToggle\n\n  Отобразить или скрыть элемент скользящим движением (слайдом).\n\n  ```js\n  // jQuery\n  $el.slideToggle();\n\n  // Нативно\n  const originHeight = '100px';\n  el.style.transition = 'height 3s';\n  const { height } = el.ownerDocument.defaultView.getComputedStyle(el, null);\n  if (parseInt(height, 10) === 0) {\n    el.style.height = originHeight;\n  } else {\n   el.style.height = '0px';\n  }\n  ```\n\n- [8.8](#8.8) <a name='8.8'></a> Animate\n\n  Perform a custom animation of a set of CSS properties. Применить пользовательский набор свойств анимации CSS.\n\n  ```js\n  // jQuery\n  $el.animate({ params }, speed);\n\n  // Нативно\n  el.style.transition = 'all ' + speed;\n  Object.keys(params).forEach((key) => {\n    el.style[key] = params[key];\n  });\n  ```\n\n\n## Альтернативы\n\n* [You Might Not Need jQuery](http://youmightnotneedjquery.com/) - Примеры как исполняются частые события, элементы, ajax и тд с ванильным javascript.\n* [npm-dom](http://github.com/npm-dom) и [webmodules](http://github.com/webmodules) - Отдельные DOM модули можно найти на NPM\n\n## Поддержка браузеров\n\n![Chrome][chrome-image] | ![Firefox][firefox-image] | ![IE][ie-image] | ![Opera][opera-image] | ![Safari][safari-image]\n--- | --- | --- | --- | --- |\nLatest ✔ | Latest ✔ | 10+ ✔ | Latest ✔ | 6.1+ ✔ |\n\n# License\n\nMIT\n\n[chrome-image]: https://raw.github.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png\n[firefox-image]: https://raw.github.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png\n[ie-image]: https://raw.github.com/alrra/browser-logos/master/src/archive/internet-explorer_9-11/internet-explorer_9-11_48x48.png\n[opera-image]: https://raw.github.com/alrra/browser-logos/master/src/opera/opera_48x48.png\n[safari-image]: https://raw.github.com/alrra/browser-logos/master/src/safari/safari_48x48.png\n"
  },
  {
    "path": "README-tr.md",
    "content": "## jQuery'e İhtiyacınız Yok\n\nÖnyüz ortamları bugünlerde çok hızlı gelişiyor, öyle ki modern tarayıcılar DOM/DOM APİ'lere ait önemli gereklilikleri çoktan yerine getirdiler. DOM işleme ve olaylar için, en baştan jQuery ögrenmemize gerek kalmadı. Bu arada, üstünlükleri ile jQuery'i önemsizleştiren ve doğrudan DOM değişikliklerinin bir Anti-pattern olduğunu gösteren, React, Angular ve Vue gibi gelişmiş önyüz kütüphanelerine ayrıca teşekkür ederiz. Bu proje, IE10+ desteği ile coğunluğu jQuery yöntemlerine alternatif olan yerleşik uygulamaları içerir.\n\n## İçerik Tablosu\n\n1. [Çeviriler](#Çeviriler)\n1. [Sorgu seçiciler](#sorgu-seçiciler)\n1. [CSS & Stil](#css--stil)\n1. [DOM düzenleme](#dom-düzenleme)\n1. [Ajax](#ajax)\n1. [Olaylar](#olaylar)\n1. [Araçlar](#araçlar)\n1. [Alternatifler](#alternatifler)\n1. [Tarayıcı desteği](#tarayıcı-desteği)\n\n## Çeviriler\n\n* [한국어](./README.ko-KR.md)\n* [正體中文](./README.zh-TW.md)\n* [简体中文](./README.zh-CN.md)\n* [Bahasa Melayu](./README-my.md)\n* [Bahasa Indonesia](./README-id.md)\n* [Português(PT-BR)](./README.pt-BR.md)\n* [Tiếng Việt Nam](./README-vi.md)\n* [Español](./README-es.md)\n* [Русский](./README-ru.md)\n* [Кыргызча](./README-kg.md)\n* [Türkçe](./README-tr.md)\n* [Italiano](./README-it.md)\n* [Français](./README-fr.md)\n* [日本語](./README-ja.md)\n* [Polski](./README-pl.md)\n\n## Sorgu seçiciler\n\nYaygın olan class, id ve özellik seçiciler yerine, `document.querySelector` yada `document.querySelectorAll` kullanabiliriz. Ayrıldıkları nokta:\n* `document.querySelector` ilk seçilen öğeyi döndürür\n* `document.querySelectorAll` Seçilen tüm öğeleri NodeList olarak geri döndürür. `[].slice.call(document.querySelectorAll(selector) || []);` kullanarak bir diziye dönüştürebilirsiniz.\n* Herhangi bir öğenin seçilememesi durumda ise, jQuery `[]` döndürürken, DOM API `null` döndürecektir. Null Pointer istisnası almamak için `||` ile varsayılan değere atama yapabilirsiniz, örnek: `document.querySelectorAll(selector) || []`\n\n> Uyarı: `document.querySelector` ve `document.querySelectorAll` biraz **YAVAŞ** olabilir, Daha hızlısını isterseniz, `getElementById`, `document.getElementsByClassName` yada `document.getElementsByTagName` kullanabilirsiniz.\n\n- [1.0](#1.0) <a name='1.0'></a> Seçici ile sorgu\n\n  ```js\n  // jQuery\n  $('selector');\n\n  // Yerleşik\n  document.querySelectorAll('selector');\n  ```\n\n- [1.1](#1.1) <a name='1.1'></a> Sınıf ile sorgu\n\n  ```js\n  // jQuery\n  $('.class');\n\n  // Yerleşik\n  document.querySelectorAll('.class');\n\n  // yada\n  document.getElementsByClassName('class');\n  ```\n\n- [1.2](#1.2) <a name='1.2'></a> Id ile sorgu\n\n  ```js\n  // jQuery\n  $('#id');\n\n  // Yerleşik\n  document.querySelector('#id');\n\n  // yada\n  document.getElementById('id');\n  ```\n\n- [1.3](#1.3) <a name='1.3'></a> Özellik ile sorgu\n\n  ```js\n  // jQuery\n  $('a[target=_blank]');\n\n  // Yerleşik\n  document.querySelectorAll('a[target=_blank]');\n  ```\n\n- [1.4](#1.4) <a name='1.4'></a> Öğe erişimi\n\n  + Node'a erişim\n\n    ```js\n    // jQuery\n    $el.find('li');\n\n    // Yerleşik\n    el.querySelectorAll('li');\n    ```\n\n  + Body'e erişim\n\n    ```js\n    // jQuery\n    $('body');\n\n    // Yerleşik\n    document.body;\n    ```\n\n  + Özelliğe erişim\n\n    ```js\n    // jQuery\n    $el.attr('foo');\n\n    // Yerleşik\n    el.getAttribute('foo');\n    ```\n\n  + Data özelliğine erişim\n\n    ```js\n    // jQuery\n    $el.data('foo');\n\n    // Yerleşik\n    // getAttribute kullanarak\n    el.getAttribute('data-foo');\n    // Eğer  IE 11+ kullanıyor iseniz, `dataset` ile de erişebilirsiniz\n    el.dataset['foo'];\n    ```\n\n- [1.5](#1.5) <a name='1.5'></a> Kardeş/Önceki/Sonraki öğeler\n\n  + Kardeş öğeler\n\n    ```js\n    // jQuery\n    $el.siblings();\n\n    // Yerleşik\n    [].filter.call(el.parentNode.children, function(child) {\n      return child !== el;\n    });\n    ```\n\n  + Önceki öğeler\n\n    ```js\n    // jQuery\n    $el.prev();\n\n    // Yerleşik\n    el.previousElementSibling;\n    ```\n\n  + Sonraki öğeler\n\n    ```js\n    // jQuery\n    $el.next();\n\n    // Yerleşik\n    el.nextElementSibling;\n    ```\n\n- [1.6](#1.6) <a name='1.6'></a> En yakın\n\n  Verilen seçici ile eşleşen ilk öğeyi döndürür, geçerli öğeden başlayarak document'a kadar geçiş yapar.\n\n  ```js\n  // jQuery\n  $el.closest(selector);\n\n  // Yerleşik - Sadece en güncellerde, IE desteklemiyor\n  el.closest(selector);\n\n  // Yerleşik - IE10+\n  function closest(el, selector) {\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    while (el) {\n      if (matchesSelector.call(el, selector)) {\n        return el;\n      } else {\n        el = el.parentElement;\n      }\n    }\n    return null;\n  }\n  ```\n\n- [1.7](#1.7) <a name='1.7'></a> Önceki atalar\n\n  Verilen seçici ile eşleşen öğe veya DOM node veya jQuery nesnesi hariç, mevcut öğe ile aradaki tüm önceki ataları bir set dahilinde verir.\n\n  ```js\n  // jQuery\n  $el.parentsUntil(selector, filter);\n\n  // Yerleşik\n  function parentsUntil(el, selector, filter) {\n    const result = [];\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    // eşleştirme, atadan başlar\n    el = el.parentElement;\n    while (el && !matchesSelector.call(el, selector)) {\n      if (!filter) {\n        result.push(el);\n      } else {\n        if (matchesSelector.call(el, filter)) {\n          result.push(el);\n        }\n      }\n      el = el.parentElement;\n    }\n    return result;\n  }\n  ```\n\n- [1.8](#1.8) <a name='1.8'></a> Form\n\n  + Input/Textarea\n\n    ```js\n    // jQuery\n    $('#my-input').val();\n\n    // Yerleşik\n    document.querySelector('#my-input').value;\n    ```\n\n  + e.currentTarget ile `.radio` arasındaki dizini verir\n\n    ```js\n    // jQuery\n    $(e.currentTarget).index('.radio');\n\n    // Yerleşik\n    [].indexOf.call(document.querySelectAll('.radio'), e.currentTarget);\n    ```\n\n- [1.9](#1.9) <a name='1.9'></a> Iframe İçeriği\n\n  Mevcut Iframe için `$('iframe').contents()` yerine `contentDocument` döndürür.\n\n  + Iframe İçeriği\n\n    ```js\n    // jQuery\n    $iframe.contents();\n\n    // Yerleşik\n    iframe.contentDocument;\n    ```\n\n  + Iframe seçici\n\n    ```js\n    // jQuery\n    $iframe.contents().find('.css');\n\n    // Yerleşik\n    iframe.contentDocument.querySelectorAll('.css');\n    ```\n\n**[⬆ üste dön](#İçerik-tablosu)**\n\n## CSS & Stil\n\n- [2.1](#2.1) <a name='2.1'></a> CSS\n\n  + Stili verir\n\n    ```js\n    // jQuery\n    $el.css(\"color\");\n\n    // Yerleşik\n    // NOT: Bilinen bir hata, eğer stil değeri 'auto' ise 'auto' döndürür\n    const win = el.ownerDocument.defaultView;\n    // null sahte tipleri döndürmemesi için\n    win.getComputedStyle(el, null).color;\n    ```\n\n  + Stil değiştir\n\n    ```js\n    // jQuery\n    $el.css({ color: \"#ff0011\" });\n\n    // Yerleşik\n    el.style.color = '#ff0011';\n    ```\n\n  + Stil değeri al/değiştir\n\n    Eğer aynı anda birden fazla stili değiştirmek istiyor iseniz, oui-dom-utils paketi içindeki [setStyles](https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L194) metoduna göz atınız.\n\n\n  + Sınıf ekle\n\n    ```js\n    // jQuery\n    $el.addClass(className);\n\n    // Yerleşik\n    el.classList.add(className);\n    ```\n\n  + Sınıf çıkart\n\n    ```js\n    // jQuery\n    $el.removeClass(className);\n\n    // Yerleşik\n    el.classList.remove(className);\n    ```\n\n  + sınfı var mı?\n\n    ```js\n    // jQuery\n    $el.hasClass(className);\n\n    // Yerleşik\n    el.classList.contains(className);\n    ```\n\n  + Sınfı takas et\n\n    ```js\n    // jQuery\n    $el.toggleClass(className);\n\n    // Yerleşik\n    el.classList.toggle(className);\n    ```\n\n- [2.2](#2.2) <a name='2.2'></a> Genişlik ve Yükseklik\n\n  Genişlik ve Yükseklik teorik olarak aynı şekilde, örnek olarak Yükseklik veriliyor\n\n  + Window Yüksekliği\n\n    ```js\n    // window yüksekliği\n    $(window).height();\n    // kaydırma çubuğu olmaksızın, jQuery ile aynı\n    window.document.documentElement.clientHeight;\n    // kaydırma çubuğu ile birlikte\n    window.innerHeight;\n    ```\n\n  + Document yüksekliği\n\n    ```js\n    // jQuery\n    $(document).height();\n\n    // Yerleşik\n    document.documentElement.scrollHeight;\n    ```\n\n  + Öğe yüksekliği\n\n    ```js\n    // jQuery\n    $el.height();\n\n    // Yerleşik\n    function getHeight(el) {\n      const styles = this.getComputedStyles(el);\n      const height = el.offsetHeight;\n      const borderTopWidth = parseFloat(styles.borderTopWidth);\n      const borderBottomWidth = parseFloat(styles.borderBottomWidth);\n      const paddingTop = parseFloat(styles.paddingTop);\n      const paddingBottom = parseFloat(styles.paddingBottom);\n      return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;\n    }\n    // Tamsayı olarak daha doğru olanı（`border-box` iken, `height - border` esas; `content-box` ise, `height + padding` esas alınır）\n    el.clientHeight;\n    // Ondalık olarak daha doğru olanı（`border-box` iken, `height` esas; `content-box` ise, `height + padding + border` esas alınır）\n    el.getBoundingClientRect().height;\n    ```\n\n- [2.3](#2.3) <a name='2.3'></a> Pozisyon ve Ara-Açıklığı\n\n  + Pozisyon\n\n    ```js\n    // jQuery\n    $el.position();\n\n    // Yerleşik\n    { left: el.offsetLeft, top: el.offsetTop }\n    ```\n\n  + Ara-Açıklığı\n\n    ```js\n    // jQuery\n    $el.offset();\n\n    // Yerleşik\n    function getOffset (el) {\n      const box = el.getBoundingClientRect();\n\n      return {\n        top: box.top + window.pageYOffset - document.documentElement.clientTop,\n        left: box.left + window.pageXOffset - document.documentElement.clientLeft\n      }\n    }\n    ```\n\n- [2.4](#2.4) <a name='2.4'></a> Üste kaydır\n\n  ```js\n  // jQuery\n  $(window).scrollTop();\n\n  // Yerleşik\n  (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;\n  ```\n\n**[⬆ üste dön](#İçerik-tablosu)**\n\n## DOM düzenleme\n\n- [3.1](#3.1) <a name='3.1'></a> Çıkartma\n  ```js\n  // jQuery\n  $el.remove();\n\n  // Yerleşik\n  el.parentNode.removeChild(el);\n  ```\n\n- [3.2](#3.2) <a name='3.2'></a> Metin\n\n  + Get text\n\n    ```js\n    // jQuery\n    $el.text();\n\n    // Yerleşik\n    el.textContent;\n    ```\n\n  + Set text\n\n    ```js\n    // jQuery\n    $el.text(string);\n\n    // Yerleşik\n    el.textContent = string;\n    ```\n\n- [3.3](#3.3) <a name='3.3'></a> HTML\n\n  + HTML'i alma\n\n    ```js\n    // jQuery\n    $el.html();\n\n    // Yerleşik\n    el.innerHTML;\n    ```\n\n  + HTML atama\n\n    ```js\n    // jQuery\n    $el.html(htmlString);\n\n    // Yerleşik\n    el.innerHTML = htmlString;\n    ```\n\n- [3.4](#3.4) <a name='3.4'></a> Sona ekleme\n\n  Ata öğenin son çocuğundan sonra öğe ekleme\n\n  ```js\n  // jQuery\n  $el.append(\"<div id='container'>hello</div>\");\n\n  // Yerleşik\n  el.insertAdjacentHTML(\"beforeend\",\"<div id='container'>hello</div>\");\n  ```\n\n- [3.5](#3.5) <a name='3.5'></a> Öne ekleme\n\n  ```js\n  // jQuery\n  $el.prepend(\"<div id='container'>hello</div>\");\n\n  // Yerleşik\n  el.insertAdjacentHTML(\"afterbegin\",\"<div id='container'>hello</div>\");\n  ```\n\n- [3.6](#3.6) <a name='3.6'></a> Öncesine Ekleme\n\n  Seçili öğeden önceki yere yeni öğe ekleme\n\n  ```js\n  // jQuery\n  $newEl.insertBefore(queryString);\n\n  // Yerleşik\n  const target = document.querySelector(queryString);\n  target.parentNode.insertBefore(newEl, target);\n  ```\n\n- [3.7](#3.7) <a name='3.7'></a> Sonrasına ekleme\n\n  Seçili öğeden sonraki yere yeni öğe ekleme\n\n  ```js\n  // jQuery\n  $newEl.insertAfter(queryString);\n\n  // Yerleşik\n  const target = document.querySelector(queryString);\n  target.parentNode.insertBefore(newEl, target.nextSibling);\n  ```\n\n- [3.8](#3.8) <a name='3.8'></a> eşit mi?\n\n  Sorgu seçici ile eşleşiyor ise `true` döner\n\n  ```js\n  // jQuery için not: `is` aynı zamanda `function` veya `elements` için de geçerlidir fakat burada bir önemi bulunmuyor\n  $el.is(selector);\n\n  // Yerleşik\n  el.matches(selector);\n  ```\n- [3.9](#3.9) <a name='3.9'></a> Klonlama\n\n  Mevcut öğenin bir derin kopyasını oluşturur\n\n  ```js\n  // jQuery\n  $el.clone();\n\n  // Yerleşik\n  el.cloneNode();\n\n  // Derin kopya için, `true` parametresi kullanınız  \n  ```\n**[⬆ üste dön](#İçerik-tablosu)**\n\n## Ajax\n\n[Fetch API](https://fetch.spec.whatwg.org/) ajax için XMLHttpRequest yerine kullanan yeni standarttır. Chrome ve Firefox destekler,  eski tarayıcılar için polyfill kullanabilirsiniz.\n\nIE9+ ve üstü için [github/fetch](http://github.com/github/fetch) yada IE8+ ve üstü için [fetch-ie8](https://github.com/camsong/fetch-ie8/), JSONP istekler için [fetch-jsonp](https://github.com/camsong/fetch-jsonp) deneyiniz.\n\n**[⬆ üste dön](#İçerik-tablosu)**\n\n## Olaylar\n\nNamespace ve Delegasyon ile tam olarak değiştirmek için, https://github.com/oneuijs/oui-dom-events sayfasına bakınız  \n\n- [5.1](#5.1) <a name='5.1'></a> on ile bir öğeye bağlama\n\n  ```js\n  // jQuery\n  $el.on(eventName, eventHandler);\n\n  // Yerleşik\n  el.addEventListener(eventName, eventHandler);\n  ```\n\n- [5.2](#5.2) <a name='5.2'></a> off ile bir bağlamayı sonlandırma\n\n  ```js\n  // jQuery\n  $el.off(eventName, eventHandler);\n\n  // Yerleşik\n  el.removeEventListener(eventName, eventHandler);\n  ```\n\n- [5.3](#5.3) <a name='5.3'></a> Tetikleyici\n\n  ```js\n  // jQuery\n  $(el).trigger('custom-event', {key1: 'data'});\n\n  // Yerleşik\n  if (window.CustomEvent) {\n    const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});\n  } else {\n    const event = document.createEvent('CustomEvent');\n    event.initCustomEvent('custom-event', true, true, {key1: 'data'});\n  }\n\n  el.dispatchEvent(event);\n  ```\n\n**[⬆ üste dön](#İçerik-tablosu)**\n\n## Araçlar\n\n- [6.1](#6.1) <a name='6.1'></a> isArray\n\n  ```js\n  // jQuery\n  $.isArray(range);\n\n  // Yerleşik\n  Array.isArray(range);\n  ```\n\n- [6.2](#6.2) <a name='6.2'></a> Trim\n\n  ```js\n  // jQuery\n  $.trim(string);\n\n  // Yerleşik\n  string.trim();\n  ```\n\n- [6.3](#6.3) <a name='6.3'></a> Nesne atama\n\n  Türetmek için, object.assign polyfill'ini deneyiniz https://github.com/ljharb/object.assign\n\n  ```js\n  // jQuery\n  $.extend({}, defaultOpts, opts);\n\n  // Yerleşik\n  Object.assign({}, defaultOpts, opts);\n  ```\n\n- [6.4](#6.4) <a name='6.4'></a> İçerme\n\n  ```js\n  // jQuery\n  $.contains(el, child);\n\n  // Yerleşik\n  el !== child && el.contains(child);\n  ```\n\n**[⬆ üste dön](#İçerik-tablosu)**\n\n## Alternatifler\n\n* [jQuery'e İhtiyacınız Yok](http://youmightnotneedjquery.com/) - Yaygın olan olay, öğe ve ajax işlemlerinin yalın Javascript'teki karşılıklarına ait örnekler\n* [npm-dom](http://github.com/npm-dom) ve [webmodules](http://github.com/webmodules) - NPM için ayrı DOM modül organizasyonları\n\n## Tarayıcı Desteği\n\n![Chrome](https://raw.github.com/alrra/browser-logos/master/chrome/chrome_48x48.png) | ![Firefox](https://raw.github.com/alrra/browser-logos/master/firefox/firefox_48x48.png) | ![IE](https://raw.github.com/alrra/browser-logos/master/internet-explorer/internet-explorer_48x48.png) | ![Opera](https://raw.github.com/alrra/browser-logos/master/opera/opera_48x48.png) | ![Safari](https://raw.github.com/alrra/browser-logos/master/safari/safari_48x48.png)\n--- | --- | --- | --- | --- |\nLatest ✔ | Latest ✔ | 10+ ✔ | Latest ✔ | 6.1+ ✔ |\n\n# Lisans\n\nMIT\n"
  },
  {
    "path": "README-vi.md",
    "content": "## You (Might) Don't Need jQuery\n\n## Bạn không cần jQuery nữa đâu\n\nNgày nay, môi trường lập trình front-end phát triển rất nhanh chóng, các trình duyệt hiện đại đã cung cấp các API đủ tốt để làm việc với DOM/BOM. Bạn không còn cần phải học về jQuery nữa. Đồng thời, nhờ sự ra đời của các thư viện như React, Angular và Vue đã khiến cho việc can thiệp trực tiếp vào DOM trở thành một việc không tốt. jQuery đã không còn quan trọng như trước nữa. Bài viết này tổng hợp những cách để thay thế các hàm của jQuery bằng các hàm được hỗ trợ bởi trình duyệt, và hó cũng hoạt động trên IE 10+\n\n## Danh mục\n\n1. [Query Selector](#query-selector)\n1. [CSS & Style](#css--style)\n1. [Thao tác với DOM](#thao-tác-với-dom)\n1. [Ajax](#ajax)\n1. [Events](#events)\n1. [Hàm tiện ích](#hàm-tiện-ích)\n1. [Ngôn ngữ khác](#ngôn-ngữ-khác)\n1. [Các trình duyệt hỗ trợ](#các-trình-duyệt-hỗ-trợ)\n\n## Ngôn ngữ khác\n\n* [한국어](./README.ko-KR.md)\n* [正體中文](./README.zh-TW.md)\n* [简体中文](./README.zh-CN.md)\n* [Bahasa Melayu](./README-my.md)\n* [Bahasa Indonesia](./README-id.md)\n* [Português(PT-BR)](./README.pt-BR.md)\n* [Tiếng Việt Nam](./README-vi.md)\n* [Español](./README-es.md)\n* [Русский](./README-ru.md)\n* [Кыргызча](./README-kg.md)\n* [Türkçe](./README-tr.md)\n* [Italiano](./README-it.md)\n* [Français](./README-fr.md)\n* [日本語](./README-ja.md)\n* [Polski](./README-pl.md)\n\n## Query Selector\n\nĐối với những selector phổ biến như class, id hoặc thuộc tính thì chúng ta có thể sử dụng `document.querySelector` hoặc `document.querySelectorAll` để thay thế cho jQuery selector. Sự khác biệt của hai hàm này là ở chỗ:\n\n* `document.querySelector` trả về element đầu tiên được tìm thấy\n* `document.querySelectorAll` trả về tất cả các element được tìm thấy dưới dạng một instance của NodeList. Nó có thể được convert qua array bằng cách `[].slice.call(document.querySelectorAll(selector) || []);`\n* Nếu không có element nào được tìm thấy, thì jQuery sẽ trả về một array rỗng `[]` trong khi đó DOM API sẽ trả về `null`. Hãy chú ý đến Null Pointer Exception. Bạn có thể sử dụng toán tử `||` để đặt giá trị default nếu như không có element nào được tìm thấy, ví dụ như `document.querySelectorAll(selector) || []`\n\n> Chú ý : `document.querySelector` và `document.querySelectorAll` hoạt động khá **CHẬM**, hãy thử dùng `getElementById`, `document.getElementsByClassName` hoặc `document.getElementsByTagName` nếu bạn muốn đạt hiệu suất tốt hơn.\n\n- [1.0](#1.0) <a name='1.0'></a> Query bằng selector\n\n  ```js\n  // jQuery\n  $('selector');\n\n  // Native\n  document.querySelectorAll('selector');\n  ```\n\n- [1.1](#1.1) <a name='1.1'></a> Query bằng class\n\n  ```js\n  // jQuery\n  $('.class');\n\n  // Native\n  document.querySelectorAll('.class');\n\n  // hoặc\n  document.getElementsByClassName('class');\n  ```\n\n- [1.2](#1.2) <a name='1.2'></a> Query bằng id\n\n  ```js\n  // jQuery\n  $('#id');\n\n  // Native\n  document.querySelector('#id');\n\n  // hoặc\n  document.getElementById('id');\n  ```\n\n- [1.3](#1.3) <a name='1.3'></a> Query bằng thuộc tính\n\n  ```js\n  // jQuery\n  $('a[target=_blank]');\n\n  // Native\n  document.querySelectorAll('a[target=_blank]');\n  ```\n\n- [1.4](#1.4) <a name='1.4'></a> Tìm bất cứ gì.\n\n  + Tìm node\n\n    ```js\n    // jQuery\n    $el.find('li');\n\n    // Native\n    el.querySelectorAll('li');\n    ```\n\n  + Tìm body\n\n    ```js\n    // jQuery\n    $('body');\n\n    // Native\n    document.body;\n    ```\n\n  + lấy thuộc tính\n\n    ```js\n    // jQuery\n    $el.attr('foo');\n\n    // Native\n    e.getAttribute('foo');\n    ```\n\n  + Lấy giá trị của thuộc tính `data`\n\n    ```js\n    // jQuery\n    $el.data('foo');\n\n    // Native\n    // using getAttribute\n    el.getAttribute('data-foo');\n    // you can also use `dataset` if only need to support IE 11+\n    el.dataset['foo'];\n    ```\n\n- [1.5](#1.5) <a name='1.5'></a> Tìm element cùng level/trước/sau\n\n  + Element cùng level\n\n    ```js\n    // jQuery\n    $el.siblings();\n\n    // Native\n    [].filter.call(el.parentNode.children, function(child) {\n      return child !== el;\n    });\n    ```\n\n  + Element ở phía trước\n\n    ```js\n    // jQuery\n    $el.prev();\n\n    // Native\n    el.previousElementSibling;\n\n    ```\n\n  + Element ở phía sau\n\n    ```js\n    // next\n    $el.next();\n    el.nextElementSibling;\n    ```\n\n- [1.6](#1.6) <a name='1.6'></a> Element gần nhất\n\n  Trả về element đầu tiên có selector khớp với yêu cầu khi duyệt từ element hiện tại trở lên tới document.\n\n  ```js\n  // jQuery\n  $el.closest(queryString);\n\n  // Native\n  function closest(el, selector) {\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    while (el) {\n      if (matchesSelector.call(el, selector)) {\n        return el;\n      } else {\n        el = el.parentElement;\n      }\n    }\n    return null;\n  }\n  ```\n\n- [1.7](#1.7) <a name='1.7'></a> Tìm parent\n\n  Truy ngược một cách đệ quy tổ tiên của element hiện tại, cho đến khi tìm được một element tổ tiên ( element cần tìm ) mà element đó là con trực tiếp của element khớp với selector được cung cấp, Return lại element cần tìm đó.\n\n  ```js\n  // jQuery\n  $el.parentsUntil(selector, filter);\n\n  // Native\n  function parentsUntil(el, selector, filter) {\n    const result = [];\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    // match start from parent\n    el = el.parentElement;\n    while (el && !matchesSelector.call(el, selector)) {\n      if (!filter) {\n        result.push(el);\n      } else {\n        if (matchesSelector.call(el, filter)) {\n          result.push(el);\n        }\n      }\n      el = el.parentElement;\n    }\n    return result;\n  }\n  ```\n\n- [1.8](#1.8) <a name='1.8'></a> Form\n\n  + Input/Textarea\n\n    ```js\n    // jQuery\n    $('#my-input').val();\n\n    // Native\n    document.querySelector('#my-input').value;\n    ```\n\n  + Lấy index của e.currentTarget trong danh sách các element khớp với selector `.radio`\n\n    ```js\n    // jQuery\n    $(e.currentTarget).index('.radio');\n\n    // Native\n    [].indexOf.call(document.querySelectAll('.radio'), e.currentTarget);\n    ```\n\n- [1.9](#1.9) <a name='1.9'></a> Nội dung Iframe\n\n  `$('iframe').contents()` trả về thuộc tính `contentDocument` của iframe được tìm thấy\n\n  + Nọi dung iframe\n\n    ```js\n    // jQuery\n    $iframe.contents();\n\n    // Native\n    iframe.contentDocument;\n    ```\n\n  + Query Iframe\n\n    ```js\n    // jQuery\n    $iframe.contents().find('.css');\n\n    // Native\n    iframe.contentDocument.querySelectorAll('.css');\n    ```\n\n**[⬆ Trở về đầu](#danh-mục)**\n\n## CSS & Style\n\n- [2.1](#2.1) <a name='2.1'></a> CSS\n\n  + Lấy style\n\n    ```js\n    // jQuery\n    $el.css(\"color\");\n\n    // Native\n    // NOTE: Bug đã được biết, sẽ trả về 'auto' nếu giá trị của style là 'auto'\n    const win = el.ownerDocument.defaultView;\n    // null means not return presudo styles\n    win.getComputedStyle(el, null).color;\n    ```\n\n  + Đặt style\n\n    ```js\n    // jQuery\n    $el.css({ color: \"#ff0011\" });\n\n    // Native\n    el.style.color = '#ff0011';\n    ```\n\n  + Lấy/Đặt Nhiều style\n\n    Nếu bạn muốn đặt nhiều style một lần, bạn có thể sẽ thích phương thức [setStyles](https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L194) trong thư viện oui-dom-utils.\n\n\n  + Thêm class và element\n\n    ```js\n    // jQuery\n    $el.addClass(className);\n\n    // Native\n    el.classList.add(className);\n    ```\n\n  + Loại bỏ class class ra khỏi element\n\n    ```js\n    // jQuery\n    $el.removeClass(className);\n\n    // Native\n    el.classList.remove(className);\n    ```\n\n  + Kiểm tra xem element có class nào đó hay không\n\n    ```js\n    // jQuery\n    $el.hasClass(className);\n\n    // Native\n    el.classList.contains(className);\n    ```\n\n  + Toggle class\n\n    ```js\n    // jQuery\n    $el.toggleClass(className);\n\n    // Native\n    el.classList.toggle(className);\n    ```\n\n- [2.2](#2.2) <a name='2.2'></a> Chiều rộng, chiều cao\n\n  Về mặt lý thuyết thì chiều rộng và chiều cao giống như nhau trong cả jQuery và DOM API:\n\n  + Chiều rộng của window\n\n    ```js\n    // window height\n    $(window).height();\n    // trừ đi scrollbar\n    window.document.documentElement.clientHeight;\n    // Tính luôn scrollbar\n    window.innerHeight;\n    ```\n\n  + Chiều cao của Document\n\n    ```js\n    // jQuery\n    $(document).height();\n\n    // Native\n    document.documentElement.scrollHeight;\n    ```\n\n  + Chiều cao của element\n\n    ```js\n    // jQuery\n    $el.height();\n\n    // Native\n    function getHeight(el) {\n      const styles = this.getComputedStyles(el);\n      const height = el.offsetHeight;\n      const borderTopWidth = parseFloat(styles.borderTopWidth);\n      const borderBottomWidth = parseFloat(styles.borderBottomWidth);\n      const paddingTop = parseFloat(styles.paddingTop);\n      const paddingBottom = parseFloat(styles.paddingBottom);\n      return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;\n    }\n    // chính xác tới số nguyên（khi có thuộc tính `box-sizing` là `border-box`, nó là `height - border`; khi box-sizing là `content-box`, nó là `height + padding`）\n    el.clientHeight;\n    // Chính xác tới số thập phân（khi `box-sizing` là `border-box`, nó là `height`; khi `box-sizing` là `content-box`, nó là `height + padding + border`）\n    el.getBoundingClientRect().height;\n    ```\n\n- [2.3](#2.3) <a name='2.3'></a> Position & Offset\n\n  + Position\n\n    ```js\n    // jQuery\n    $el.position();\n\n    // Native\n    { left: el.offsetLeft, top: el.offsetTop }\n    ```\n\n  + Offset\n\n    ```js\n    // jQuery\n    $el.offset();\n\n    // Native\n    function getOffset (el) {\n      const box = el.getBoundingClientRect();\n\n      return {\n        top: box.top + window.pageYOffset - document.documentElement.clientTop,\n        left: box.left + window.pageXOffset - document.documentElement.clientLeft\n      }\n    }\n    ```\n\n- [2.4](#2.4) <a name='2.4'></a> Scroll Top\n\n  ```js\n  // jQuery\n  $(window).scrollTop();\n\n  // Native\n  (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;\n  ```\n\n**[⬆ Trở về đầu](#danh-mục)**\n\n## Thao tác với DOM\n\n- [3.1](#3.1) <a name='3.1'></a> Loại bỏ\n  ```js\n  // jQuery\n  $el.remove();\n\n  // Native\n  el.parentNode.removeChild(el);\n  ```\n\n- [3.2](#3.2) <a name='3.2'></a> Text\n\n  + Lấy text\n\n    ```js\n    // jQuery\n    $el.text();\n\n    // Native\n    el.textContent;\n    ```\n\n  + Đặt giá trị text\n\n    ```js\n    // jQuery\n    $el.text(string);\n\n    // Native\n    el.textContent = string;\n    ```\n\n- [3.3](#3.3) <a name='3.3'></a> HTML\n\n  + Lấy HTML\n\n    ```js\n    // jQuery\n    $el.html();\n\n    // Native\n    el.innerHTML;\n    ```\n\n  + Đặt giá trị HTML\n\n    ```js\n    // jQuery\n    $el.html(htmlString);\n\n    // Native\n    el.innerHTML = htmlString;\n    ```\n\n- [3.4](#3.4) <a name='3.4'></a> Append\n\n  append một element sau element con cuối cùng của element cha\n\n  ```js\n  // jQuery\n  $el.append(\"<div id='container'>hello</div>\");\n\n  // Native\n  let newEl = document.createElement('div');\n  newEl.setAttribute('id', 'container');\n  newEl.innerHTML = 'hello';\n  el.appendChild(newEl);\n  ```\n\n- [3.5](#3.5) <a name='3.5'></a> Prepend\n\n  ```js\n  // jQuery\n  $el.prepend(\"<div id='container'>hello</div>\");\n\n  // Native\n  let newEl = document.createElement('div');\n  newEl.setAttribute('id', 'container');\n  newEl.innerHTML = 'hello';\n  el.insertBefore(newEl, el.firstChild);\n  ```\n\n- [3.6](#3.6) <a name='3.6'></a> insertBefore\n\n  Chèn một node vào trước element được query.\n\n  ```js\n  // jQuery\n  $newEl.insertBefore(queryString);\n\n  // Native\n  const target = document.querySelector(queryString);\n  target.parentNode.insertBefore(newEl, target);\n  ```\n\n- [3.7](#3.7) <a name='3.7'></a> insertAfter\n\n  Chèn node vào sau element được query\n\n  ```js\n  // jQuery\n  $newEl.insertAfter(queryString);\n\n  // Native\n  const target = document.querySelector(queryString);\n  target.parentNode.insertBefore(newEl, target.nextSibling);\n  ```\n\n**[⬆ Trở về đầu](#danh-mục)**\n\n## Ajax\n\nThay thế bằng [fetch](https://github.com/camsong/fetch-ie8) và [fetch-jsonp](https://github.com/camsong/fetch-jsonp)\n\n**[⬆ Trở về đầu](#danh-mục)**\n\n## Events\n\nĐể có một sự thay thế đầy đủ nhất, bạn nên sử dụng https://github.com/oneuijs/oui-dom-events\n\n- [5.1](#5.1) <a name='5.1'></a> Bind event bằng on\n\n  ```js\n  // jQuery\n  $el.on(eventName, eventHandler);\n\n  // Native\n  el.addEventListener(eventName, eventHandler);\n  ```\n\n- [5.2](#5.2) <a name='5.2'></a> Unbind event bằng off\n\n  ```js\n  // jQuery\n  $el.off(eventName, eventHandler);\n\n  // Native\n  el.removeEventListener(eventName, eventHandler);\n  ```\n\n- [5.3](#5.3) <a name='5.3'></a> Trigger\n\n  ```js\n  // jQuery\n  $(el).trigger('custom-event', {key1: 'data'});\n\n  // Native\n  if (window.CustomEvent) {\n    const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});\n  } else {\n    const event = document.createEvent('CustomEvent');\n    event.initCustomEvent('custom-event', true, true, {key1: 'data'});\n  }\n\n  el.dispatchEvent(event);\n  ```\n\n**[⬆ Trở về đầu](#danh-mục)**\n\n## Hàm tiện ích\n\n- [6.1](#6.1) <a name='6.1'></a> isArray\n\n  ```js\n  // jQuery\n  $.isArray(range);\n\n  // Native\n  Array.isArray(range);\n  ```\n\n- [6.2](#6.2) <a name='6.2'></a> Trim\n\n  ```js\n  // jQuery\n  $.trim(string);\n\n  // Native\n  string.trim();\n  ```\n\n- [6.3](#6.3) <a name='6.3'></a> Object Assign\n\n  Mở rộng, sử dụng object.assign https://github.com/ljharb/object.assign\n\n  ```js\n  // jQuery\n  $.extend({}, defaultOpts, opts);\n\n  // Native\n  Object.assign({}, defaultOpts, opts);\n  ```\n\n- [6.4](#6.4) <a name='6.4'></a> Contains\n\n  ```js\n  // jQuery\n  $.contains(el, child);\n\n  // Native\n  el !== child && el.contains(child);\n  ```\n\n**[⬆ Trở về đầu](#danh-mục)**\n\n## Các trình duyệt hỗ trợ\n\n![Chrome](https://raw.github.com/alrra/browser-logos/master/chrome/chrome_48x48.png) | ![Firefox](https://raw.github.com/alrra/browser-logos/master/firefox/firefox_48x48.png) | ![IE](https://raw.github.com/alrra/browser-logos/master/internet-explorer/internet-explorer_48x48.png) | ![Opera](https://raw.github.com/alrra/browser-logos/master/opera/opera_48x48.png) | ![Safari](https://raw.github.com/alrra/browser-logos/master/safari/safari_48x48.png)\n--- | --- | --- | --- | --- |\nLatest ✔ | Latest ✔ | 10+ ✔ | Latest ✔ | 6.1+ ✔ |\n\n# Giấy phép\n\nMIT\n"
  },
  {
    "path": "README.ko-KR.md",
    "content": "## You (Might) Don't Need jQuery\n\n오늘날 프론트엔드 개발 환경은 급격히 진화하고 있고, 모던 브라우저들은 이미 충분히 많은 DOM/BOM API들을 구현했습니다. 우리는 jQuery를 DOM 처리나 이벤트를 위해 처음부터 배울 필요가 없습니다. React, Angular, Vue같은 프론트엔드 라이브러리들이 주도권을 차지하는 동안 DOM을 바로 처리하는 것은 안티패턴이 되었고, jQuery의 중요성은 줄어들었습니다. 이 프로젝트는 대부분의 jQuery 메소드의 대안을 IE 10 이상을 지원하는 네이티브 구현으로 소개합니다.\n\n노트: jQuery는 여전히 훌륭한 라이브러리이며 많은 유즈 케이스를 갖고 있습니다. 원하지 않으신다면 마이그레이트하지 않으셔도됩니다.\n\n## 목차\n\n1. [번역](#번역)\n1. [Query Selector](#query-selector)\n1. [CSS & Style](#css--style)\n1. [DOM 조작](#dom-조작)\n1. [Ajax](#ajax)\n1. [이벤트](#이벤트)\n1. [유틸리티](#유틸리티)\n1. [Promises](#promises)\n1. [Animation](#animation)\n1. [대안방법](#대안방법)\n1. [브라우저 지원](#브라우저-지원)\n\n## 번역\n\n* [한국어](./README.ko-KR.md)\n* [正體中文](./README.zh-TW.md)\n* [简体中文](./README.zh-CN.md)\n* [Bahasa Melayu](./README-my.md)\n* [Bahasa Indonesia](./README-id.md)\n* [Português(PT-BR)](./README.pt-BR.md)\n* [Tiếng Việt Nam](./README-vi.md)\n* [Español](./README-es.md)\n* [Русский](./README-ru.md)\n* [Кыргызча](./README-kg.md)\n* [Türkçe](./README-tr.md)\n* [Italiano](./README-it.md)\n* [Français](./README-fr.md)\n* [日本語](./README-ja.md)\n* [Polski](./README-pl.md)\n\n## Query Selector\n\n평범한 class, id, attribute같은 selector는 `document.querySelector`나 `document.querySelectorAll`으로 대체할 수 있습니다.\n* `document.querySelector`는 처음 매칭된 엘리먼트를 반환합니다.\n* `document.querySelectorAll`는 모든 매칭된 엘리먼트를 NodeList로 반환합니다. `Array.prototype.slice.call(document.querySelectorAll(selector));`을 사용해서 Array로 변환할 수 있습니다.\n* 만약 매칭된 엘리멘트가 없으면 jQuery와 `document.querySelectorAll`는 `[]`를 반환하지만 `document.querySelector`는 `null`을 반환합니다.\n\n> 안내: `document.querySelector`와 `document.querySelectorAll`는 꽤 **느립니다**, `getElementById`나 `document.getElementsByClassName`, `document.getElementsByTagName`를 사용하면 퍼포먼스가 향상을 기대할 수 있습니다.\n\n- [1.0](#1.0) <a name='1.0'></a> selector로 찾기\n\n  ```js\n  // jQuery\n  $('selector');\n\n  // Native\n  document.querySelectorAll('selector');\n  ```\n\n- [1.1](#1.1) <a name='1.1'></a> class로 찾기\n\n  ```js\n  // jQuery\n  $('.class');\n\n  // Native\n  document.querySelectorAll('.class');\n\n  // 또는\n  document.getElementsByClassName('class');\n  ```\n\n- [1.2](#1.2) <a name='1.2'></a> id로 찾기\n\n  ```js\n  // jQuery\n  $('#id');\n\n  // Native\n  document.querySelector('#id');\n\n  // 또는\n  document.getElementById('id');\n\n  // 또는\n  window['id']\n  ```\n\n- [1.3](#1.3) <a name='1.3'></a> 속성(attribute)으로 찾기\n\n  ```js\n  // jQuery\n  $('a[target=_blank]');\n\n  // Native\n  document.querySelectorAll('a[target=_blank]');\n  ```\n\n- [1.4](#1.4) <a name='1.4'></a> 자식에서 찾기\n\n  ```js\n  // jQuery\n  $el.find('li');\n\n  // Native\n  el.querySelectorAll('li');\n  ```\n\n- [1.5](#1.5) <a name='1.5'></a> 형제/이전/다음 엘리먼트 찾기\n\n  + 형제 엘리먼트\n\n    ```js\n    // jQuery\n    $el.siblings();\n\n    // Native - latest, Edge13+\n    [...el.parentNode.children].filter((child) =>\n      child !== el\n    );\n    // Native (alternative) - latest, Edge13+\n    Array.from(el.parentNode.children).filter((child) =>\n      child !== el\n    );\n    // Native - IE10+\n    Array.prototype.filter.call(el.parentNode.children, (child) =>\n      child !== el\n    );\n    ```\n\n  + 이전 엘리먼트\n\n    ```js\n    // jQuery\n    $el.prev();\n\n    // Native\n    el.previousElementSibling;\n    ```\n  + 다음 엘리먼트\n\n    ```js\n    // jQuery\n    $el.next();\n\n    // Native\n    el.nextElementSibling;\n    ```\n\n  + 모든 이전 형제 엘리먼트\n\n    ```js\n    // jQuery (선택적 필터 셀렉터)\n    $el.prevAll($filter);\n\n    // Native (선택적 필터 함수)\n    function getPreviousSiblings(elem, filter) {\n      var sibs = [];\n      while (elem = elem.previousSibling) {\n        if (elem.nodeType === 3) continue; // 텍스트 노트 무시\n        if (!filter || filter(elem)) sibs.push(elem);\n      }\n      return sibs;\n    }\n\n  + 모든 다음 형제 엘리먼트\n\n    ```js\n    // jQuery (선택적 셀렉터 필터)\n    $el.nextAll($filter);\n\n    // Native (선택적 필터 함수)\n    function getNextSiblings(elem, filter) {\n      var sibs = [];\n      var nextElem = elem.parentNode.firstChild;\n      do {\n        if (nextElem.nodeType === 3) continue; // 텍스트 노드 무시\n        if (nextElem === elem) continue; // 대상 elem 무시\n        if (nextElem === elem.nextElementSibling) {\n          if (!filter || filter(elem)) {\n            sibs.push(nextElem);\n            elem = nextElem;\n          }\n        }\n      } while(nextElem = nextElem.nextSibling)\n      return sibs;\n    }\n\n필터 함수 예제:\n\n```js\nfunction exampleFilter(elem) {\n  switch (elem.nodeName.toUpperCase()) {\n    case 'DIV':\n      return true;\n    case 'SPAN':\n      return true;\n    default:\n      return false;\n  }\n}\n```\n\n- [1.6](#1.6) <a name='1.6'></a> Closest\n\n  현재 엘리먼트부터 document로 이동하면서 주어진 셀렉터와 일치하는 가장 가까운 엘리먼트를 반환합니다.\n\n  ```js\n  // jQuery\n  $el.closest(selector);\n\n  // Native - 최신 브라우저만, IE는 미지원\n   el.closest(selector);\n\n  // Native - IE10 이상\n  function closest(el, selector) {\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    while (el) {\n      if (matchesSelector.call(el, selector)) {\n        return el;\n      } else {\n        el = el.parentElement;\n      }\n    }\n    return null;\n  }\n  ```\n\n- [1.7](#1.7) <a name='1.7'></a> Parents Until\n\n  주어진 셀렉터에 매칭되는 엘리먼트를 찾기까지 부모 태그들을 위로 올라가며 탐색하여 저장해두었다가 DOM 노드 또는 jQuery object로 반환합니다.\n\n  ```js\n  // jQuery\n  $el.parentsUntil(selector, filter);\n\n  // Native\n  function parentsUntil(el, selector, filter) {\n    const result = [];\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    // match start from parent\n    el = el.parentElement;\n    while (el && !matchesSelector.call(el, selector)) {\n      if (!filter) {\n        result.push(el);\n      } else {\n        if (matchesSelector.call(el, filter)) {\n          result.push(el);\n        }\n      }\n      el = el.parentElement;\n    }\n    return result;\n  }\n  ```\n\n- [1.8](#1.8) <a name='1.8'></a> Form\n\n  + Input/Textarea\n\n    ```js\n    // jQuery\n    $('#my-input').val();\n\n    // Native\n    document.querySelector('#my-input').value;\n    ```\n\n  + e.currentTarget이 몇 번째 `.radio` 인지 구하기\n\n    ```js\n    // jQuery\n    $(e.currentTarget).index('.radio');\n\n    // Native\n    Array.from(document.querySelectorAll('.radio')).indexOf(e.currentTarget);\n    또는\n    Array.prototype.indexOf.call(document.querySelectorAll('.radio'), e.currentTarget);\n    ```\n\n- [1.9](#1.9) <a name='1.9'></a> Iframe Contents\n\n  `$('iframe').contents()`는 iframe에 한정해서 `contentDocument`를 반환합니다.\n\n  + Iframe contents\n\n    ```js\n    // jQuery\n    $iframe.contents();\n\n    // Native\n    iframe.contentDocument;\n    ```\n\n  + Iframe에서 찾기\n\n    ```js\n    // jQuery\n    $iframe.contents().find('.css');\n\n    // Native\n    iframe.contentDocument.querySelectorAll('.css');\n    ```\n\n- [1.10](#1.10) <a name='1.10'></a> body 얻기\n\n  ```js\n  // jQuery\n  $('body');\n\n  // Native\n  document.body;\n  ```\n\n- [1.11](#1.11) <a name='1.11'></a> 속성 얻기 및 설정\n\n  + 속성 얻기\n\n    ```js\n    // jQuery\n    $el.attr('foo');\n\n    // Native\n    el.getAttribute('foo');\n    ```\n  + 속성 설정하기\n\n    ```js\n    // jQuery, DOM 변형 없이 메모리에서 작동됩니다.\n    $el.attr('foo', 'bar');\n\n    // Native\n    el.setAttribute('foo', 'bar');\n    ```\n\n  + `data-` 속성 얻기\n\n    ```js\n    // jQuery\n    $el.data('foo');\n\n    // Native (`getAttribute` 사용)\n    el.getAttribute('data-foo');\n\n    // Native (IE 11 이상의 지원만 필요하다면 `dataset`을 사용)\n    el.dataset['foo'];\n    ```\n\n- [1.12](#1.12) <a name='1.12'></a> 문자열을 포함하는 셀렉터(대소문자 구분)\n\n    ```js\n    // jQuery\n    $(\"selector:contains('text')\");\n\n    // Native\n    function contains(selector, text) {\n      var elements = document.querySelectorAll(selector);\n      return Array.from(elements).filter(function(element) {\n        return RegExp(text).test(element.textContent);\n      });\n    }\n    ```\n\n**[⬆ 목차로 돌아가기](#목차)**\n\n## CSS & Style\n\n- [2.1](#2.1) <a name='2.1'></a> CSS\n\n  + style값 얻기\n\n    ```js\n    // jQuery\n    $el.css(\"color\");\n\n    // Native\n    // NOTE: 알려진 버그로, style값이 'auto'이면 'auto'를 반환합니다.\n    const win = el.ownerDocument.defaultView;\n\n    // null은 가상 스타일은 반환하지 않음을 의미합니다.\n    win.getComputedStyle(el, null).color;\n    ```\n\n  + style값 설정하기\n\n    ```js\n    // jQuery\n    $el.css({ color: '#f01' });\n\n    // Native\n    el.style.color = '#f01';\n    ```\n\n  + Style값들을 동시에 얻거나 설정하기\n\n    만약 한번에 여러 style값을 바꾸고 싶다면 oui-dom-utils 패키지의 [setStyles](https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L194)를 사용해보세요.\n\n\n  + class 추가하기\n\n    ```js\n    // jQuery\n    $el.addClass(className);\n\n    // Native\n    el.classList.add(className);\n    ```\n\n  + class 제거하기\n\n    ```js\n    // jQuery\n    $el.removeClass(className);\n\n    // Native\n    el.classList.remove(className);\n    ```\n\n  + class를 포함하고 있는지 검사하기\n\n    ```js\n    // jQuery\n    $el.hasClass(className);\n\n    // Native\n    el.classList.contains(className);\n    ```\n\n  + class 토글하기\n\n    ```js\n    // jQuery\n    $el.toggleClass(className);\n\n    // Native\n    el.classList.toggle(className);\n    ```\n\n- [2.2](#2.2) <a name='2.2'></a> 폭과 높이\n\n  폭과 높이는 이론상 동일합니다. 높이로 예를 들겠습니다.\n\n  + Window의 높이\n\n    ```js\n    // window 높이\n    $(window).height();\n\n    // jQuery처럼 스크롤바를 제외하기\n    window.document.documentElement.clientHeight;\n\n    // 스크롤바 포함\n    window.innerHeight;\n    ```\n\n  + 문서 높이\n\n    ```js\n    // jQuery\n    $(document).height();\n\n    // Native\n    const body = document.body;\n    const html = document.documentElement;\n    const height = Math.max(\n      body.offsetHeight,\n      body.scrollHeight,\n      html.clientHeight,\n      html.offsetHeight,\n      html.scrollHeight\n    );\n    ```\n\n  + Element 높이\n\n    ```js\n    // jQuery\n    $el.height();\n\n    // Native\n    function getHeight(el) {\n      const styles = window.getComputedStyle(el);\n      const height = el.offsetHeight;\n      const borderTopWidth = parseFloat(styles.borderTopWidth);\n      const borderBottomWidth = parseFloat(styles.borderBottomWidth);\n      const paddingTop = parseFloat(styles.paddingTop);\n      const paddingBottom = parseFloat(styles.paddingBottom);\n      return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;\n    }\n\n    // 정수로 정확하게（`border-box`일 때 이 값은 `height - border`이고, `content-box`일 때, 이 값은 `height + padding`）\n    el.clientHeight;\n\n    // 실수로 정확하게（`border-box`일 때 이 값은 `height`이고, `content-box`일 때, 이 값은 `height + padding + border`）\n    el.getBoundingClientRect().height;\n    ```\n\n- [2.3](#2.3) <a name='2.3'></a> Position & Offset\n\n  + Position\n\n    오프셋 부모를 기준으로 엘리먼트의 현재 위치를 얻습니다.\n\n    ```js\n    // jQuery\n    $el.position();\n\n    // Native\n    { left: el.offsetLeft, top: el.offsetTop }\n    ```\n\n  + Offset\n\n    다큐먼트를 기준으로 엘리먼트의 현재 위치를 얻습니다.\n\n    ```js\n    // jQuery\n    $el.offset();\n\n    // Native\n    function getOffset (el) {\n      const box = el.getBoundingClientRect();\n\n      return {\n        top: box.top + window.pageYOffset - document.documentElement.clientTop,\n        left: box.left + window.pageXOffset - document.documentElement.clientLeft\n      };\n    }\n    ```\n\n- [2.4](#2.4) <a name='2.4'></a> Scroll Top\n\n  엘리먼트에대한 스크롤바의 현재 수직 위치를 얻습니다.\n\n  ```js\n  // jQuery\n  $(window).scrollTop();\n\n  // Native\n  (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;\n  ```\n\n**[⬆ 목차로 돌아가기](#목차)**\n\n## DOM 조작\n\n- [3.1](#3.1) <a name='3.1'></a> 제거\n\n  DOM으로부터 엘리먼트를 제거합니다.\n\n  ```js\n  // jQuery\n  $el.remove();\n\n  // Native\n  el.parentNode.removeChild(el);\n  ```\n\n- [3.2](#3.2) <a name='3.2'></a> Text\n\n  + text 가져오기\n\n    자손을 포함하는 엘리먼트의 결합된 텍스트 컨텐츠를 얻습니다.\n\n    ```js\n    // jQuery\n    $el.text();\n\n    // Native\n    el.textContent;\n    ```\n\n  + text 설정하기\n\n    엘리먼트의 컨텐츠를 지정한 텍스트로 설정합니다.\n  \n    ```js\n    // jQuery\n    $el.text(string);\n\n    // Native\n    el.textContent = string;\n    ```\n\n- [3.3](#3.3) <a name='3.3'></a> HTML\n\n  + HTML 가져오기\n\n    ```js\n    // jQuery\n    $el.html();\n\n    // Native\n    el.innerHTML;\n    ```\n\n  + HTML 설정하기\n\n    ```js\n    // jQuery\n    $el.html(htmlString);\n\n    // Native\n    el.innerHTML = htmlString;\n    ```\n\n- [3.4](#3.4) <a name='3.4'></a> 해당 엘리먼트의 자식들 뒤에 넣기(Append)\n\n  부모 엘리먼트의 마지막 자식 다음으로 엘리먼트를 추가합니다.\n\n  ```js\n  // jQuery: DOMString과 Node 객체를 위한 통합된 구문\n  $parent.append(newEl | '<div id=\"container\">Hello World</div>');\n\n  // Native: 다른 구문\n  parent.insertAdjacentHTML('beforeend', '<div id=\"container\">Hello World</div>');\n  parent.appendChild(newEl);\n\n  // Native (ES6 방식): 통합된 구문\n  parent.append(newEl | '<div id=\"container\">Hello World</div>');\n  ```\n\n- [3.5](#3.5) <a name='3.5'></a> 해당 엘리먼트의 자식들 앞에 넣기(Prepend)\n\n  ```js\n  // jQuery: DOMString과 Node 객체를 위한 통합된 구문\n  $parent.prepend(newEl | '<div id=\"container\">Hello World</div>');\n\n  // Native: 다른 구문\n  parent.insertAdjacentHTML('afterbegin', '<div id=\"container\">Hello World</div>');\n  parent.insertBefore(newEl, parent.firstChild);\n  \n  // Native (ES6 방식): 통합된 구문\n  parent.prepend(newEl | '<div id=\"container\">Hello World</div>');\n  ```\n\n- [3.6](#3.6) <a name='3.6'></a> 해당 엘리먼트 앞에 넣기(insertBefore)\n\n  새 노드를 선택한 엘리먼트 앞에 넣습니다.\n\n  ```js\n  // jQuery\n  $newEl.insertBefore(selector);\n\n  // Native (HTML 문자열)\n  el.insertAdjacentHTML('beforebegin', '<div id=\"container\">Hello World</div>');\n\n  // Native (엘리먼트)\n  const el = document.querySelector(selector);\n  if (el.parentNode) {\n    el.parentNode.insertBefore(newEl, el);\n  }\n  ```\n\n- [3.7](#3.7) <a name='3.7'></a> 해당 엘리먼트 뒤에 넣기(insertAfter)\n\n  새 노드를 선택한 엘리먼트 뒤에 넣습니다.\n\n  ```js\n  // jQuery\n  $newEl.insertAfter(selector);\n\n  // Native (HTML 문자열)\n  el.insertAdjacentHTML('afterend', '<div id=\"container\">Hello World</div>');\n\n  // Native (엘리먼트)\n  onst el = document.querySelector(selector);\n  if (el.parentNode) {\n    el.parentNode.insertBefore(newEl, el.nextSibling);\n  }\n  ```\n\n- [3.8](#3.8) <a name='3.8'></a> is\n\n  query selector와 일치하면 `true` 를 반환합니다.\n\n  ```js\n  // jQuery - `is`는 함수, 존재하는 jQuery 객체 또는 여기에서 언급하지 않은 DOM 엘리먼트와도 동작함을 알립니다.\n  $el.is(selector);\n\n  // Native\n  el.matches(selector);\n  ```\n- [3.9](#3.9) <a name='3.9'></a> clone\n\n  엘리먼트의 깊은 복사본을 생성합니다. 일치한 엘리먼트를 포함해 그 자손 노드와 텍스트 노드를 모두 복사합니다.\n\n  ```js\n  // jQuery. 이벤트 핸들러가 엘리먼트와 함께 복사되어야함을 알리려면 파라미터를 `true`로 설정하세요.\n  $el.clone();\n\n  // Native\n  el.cloneNode();\n\n  ```\n\n- [3.10](#3.10) <a name='3.10'></a> empty\n\n  모든 자식 노드를 제거합니다.\n\n  ```js\n  // jQuery\n  $el.empty();\n\n  // Native\n  el.innerHTML = null;\n  ```\n\n- [3.11](#3.11) <a name='3.11'></a> wrap\n\n  각각의 엘리먼트를 주어진 HTML 구조로 감쌉니다.\n\n  ```js\n  // jQuery\n  $('.inner').wrap('<div class=\"wrapper\"></div>');\n\n  // Native\n  Array.from(document.querySelectorAll('.inner')).forEach((el) => {\n    const wrapper = document.createElement('div');\n    wrapper.className = 'wrapper';\n    el.parentNode.insertBefore(wrapper, el);\n    wrapper.appendChild(el);\n  });\n  ```\n\n- [3.12](#3.12) <a name='3.12'></a> unwrap\n\n  DOM에서 해당 엘리먼트를 감싸고 있는 부모 요소를 없앱니다.\n\n  ```js\n  // jQuery\n  $('.inner').unwrap();\n\n  // Native\n  Array.from(document.querySelectorAll('.inner')).forEach((el) => {\n    let elParentNode = el.parentNode;\n\n    if (elParentNode !== document.body) {\n      elParentNode.parentNode.insertBefore(el, elParentNode);\n      elParentNode.parentNode.removeChild(elParentNode);\n    }\n  });\n  ```\n\n- [3.13](#3.13) <a name='3.13'></a> replaceWith\n\n  각각의 엘리먼트를 주어진 새 엘리먼트로 교체합니다.\n\n  ```js\n  // jQuery\n  $('.inner').replaceWith('<div class=\"outer\"></div>');\n\n  // Native (대안) - 최신, Edge17+\n  Array.from(document.querySelectorAll('.inner')).forEach((el) => {\n    const outer = document.createElement('div');\n    outer.className = 'outer';\n    el.replaceWith(outer);\n  });\n\n  // Native\n  Array.from(document.querySelectorAll('.inner')).forEach((el) => {\n    const outer = document.createElement('div');\n    outer.className = 'outer';\n    el.parentNode.replaceChild(outer, el);\n  });\n  ```\n\n  - [3.14](#3.14) <a name='3.14'></a> 간단한 파싱\n\n    문자열을 HTML/SVG/XML 로 파싱합니다.\n\n    ```js\n    // jQuery\n    $(`<ol>\n      <li>a</li>\n      <li>b</li>\n    </ol>\n    <ol>\n      <li>c</li>\n      <li>d</li>\n    </ol>`);\n\n    // Native\n    range = document.createRange();\n    parse = range.createContextualFragment.bind(range);\n\n    parse(`<ol>\n      <li>a</li>\n      <li>b</li>\n    </ol>\n    <ol>\n      <li>c</li>\n      <li>d</li>\n    </ol>`);\n    ```\n\n\n**[⬆ 목차로 돌아가기](#목차)**\n\n## Ajax\n\n[Fetch API](https://fetch.spec.whatwg.org/) 는 XMLHttpRequest를 ajax로 대체하는 새로운 표준 입니다. Chrome과 Firefox에서 작동하며, polyfill을 이용해서 구형 브라우저에서 작동되도록 만들 수도 있습니다.\n\nIE9 이상에서 지원하는 [github/fetch](http://github.com/github/fetch) 혹은 IE8 이상에서 지원하는 [fetch-ie8](https://github.com/camsong/fetch-ie8/), JSONP 요청을 만드는 [fetch-jsonp](https://github.com/camsong/fetch-jsonp)를 이용해보세요.\n\n- [4.1](#4.1) <a name='4.1'></a> 서버로부터 HTML data를 불러와서 매칭된 엘리먼트에 배치.\n\n  ```js\n  // jQuery\n  $(selector).load(url, completeCallback)\n\n  // Native\n  fetch(url).then(data => data.text()).then(data => {\n    document.querySelector(selector).innerHTML = data\n  }).then(completeCallback)\n  ```\n\n**[⬆ 목차로 돌아가기](#목차)**\n\n## 이벤트\n\nnamespace와 delegation을 포함해서 완전히 갈아 엎길 원하시면 https://github.com/oneuijs/oui-dom-events 를 고려해보세요.\n\n- [5.0](#5.0) <a name='5.0'></a> `DOMContentLoaded`가 되어 문서가 사용 가능한지\n\n  ```js\n  // jQuery\n  $(document).ready(eventHandler);\n\n  // Native\n  // DOMContentLoaded가 이미 완료되었는지를 확인\n  if (document.readyState !== 'loading') {\n    eventHandler();\n  } else {\n    document.addEventListener('DOMContentLoaded', eventHandler);\n  }\n  ```\n\n- [5.1](#5.1) <a name='5.1'></a> 이벤트 Bind 걸기\n\n  ```js\n  // jQuery\n  $el.on(eventName, eventHandler);\n\n  // Native\n  el.addEventListener(eventName, eventHandler);\n  ```\n\n- [5.2](#5.2) <a name='5.2'></a> 이벤트 Bind 풀기\n\n  ```js\n  // jQuery\n  $el.off(eventName, eventHandler);\n\n  // Native\n  el.removeEventListener(eventName, eventHandler);\n  ```\n\n- [5.3](#5.3) <a name='5.3'></a> 이벤트 발생시키기(Trigger)\n\n  ```js\n  // jQuery\n  $(el).trigger('custom-event', {key1: 'data'});\n\n  // Native\n  if (window.CustomEvent) {\n    const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});\n  } else {\n    const event = document.createEvent('CustomEvent');\n    event.initCustomEvent('custom-event', true, true, {key1: 'data'});\n  }\n\n  el.dispatchEvent(event);\n  ```\n\n**[⬆ 목차로 돌아가기](#목차)**\n\n## 유틸리티\n\n대부분의 jQuery 유틸은 네이티브 API에서도 찾을 수 있습니다. 다른 향상된 기능들은 지속성과 성능에 중점을 둔 더 나은 유틸 라이브러리로부터 선택할 수 있습니다. 권장하는 대안은 [Lodash](https://lodash.com)입니다.\n\n- [6.1](#6.1) <a name='6.1'></a> 기본 유틸리티\n\n  + isArray\n\n  주어진 인자가 배열인지 검사합니다.\n\n  ```js\n  // jQuery\n  $.isArray(array);\n\n  // Native\n  Array.isArray(array);\n  ```\n\n  + isWindow\n\n  주어진 인자가 window 객체인지 검사합니다.\n\n  ```js\n  // jQuery\n  $.isWindow(obj);\n\n  // Native\n  function isWindow(obj) {\n    return obj !== null && obj !== undefined && obj === obj.window;\n  }\n  ```\n\n  + inArray\n\n  배열에서 해당 값이 있는지 검색하고 해당 값의 순번을 반환합니다. (검색 결과가 없을 경우 -1을 반환)\n\n  ```js\n  // jQuery\n  $.inArray(item, array);\n\n  // Native\n  array.indexOf(item) > -1;\n\n  // ES6 방식\n  array.includes(item);\n  ```\n\n  + isNumeric\n\n  주어진 인자가 숫자인지 검사합니다.\n  검사에 `typeof` 를 사용합니다. 필요하면 라이브러리를 사용하세요. 가끔 `typeof`는 정확하지 않습니다.\n\n  ```js\n  // jQuery\n  $.isNumeric(item);\n\n  // Native\n  function isNumeric(n) {\n    return !isNaN(parseFloat(n)) && isFinite(n);\n  }\n  ```\n\n  + isFunction\n\n  주어진 인자가 JavaScript 함수 객체인지 검사합니다.\n\n  ```js\n  // jQuery\n  $.isFunction(item);\n\n  // Native\n  function isFunction(item) {\n    if (typeof item === 'function') {\n      return true;\n    }\n    var type = Object.prototype.toString(item);\n    return type === '[object Function]' || type === '[object GeneratorFunction]';\n  }\n  ```\n\n  + isEmptyObject\n\n  객체가 비어있는지 검사합니다. Check to see if an object is empty (열거할 수 있는 프로퍼티가 없는지 검사).\n\n  ```js\n  // jQuery\n  $.isEmptyObject(obj);\n\n  // Native\n  function isEmptyObject(obj) {\n    return Object.keys(obj).length === 0;\n  }\n  ```\n\n  + isPlainObject\n\n  주어진 객체가 평범한 객체인지 검사합니다. (“{}”이나 “new Object”으로 생성되었는지 검사)\n\n  ```js\n  // jQuery\n  $.isPlainObject(obj);\n\n  // Native\n  function isPlainObject(obj) {\n    if (typeof (obj) !== 'object' || obj.nodeType || obj !== null && obj !== undefined && obj === obj.window) {\n      return false;\n    }\n\n    if (obj.constructor &&\n        !Object.prototype.hasOwnProperty.call(obj.constructor.prototype, 'isPrototypeOf')) {\n      return false;\n    }\n\n    return true;\n  }\n  ```\n\n  + extend\n\n  두 개 이상의 객체를 첫 번째 객체로 합칩니다.\n  object.assign 은 ES6 API입니다. [polyfill](https://github.com/ljharb/object.assign) 을 사용할 수 있습니다.\n\n  ```js\n  // jQuery\n  $.extend({}, defaultOpts, opts);\n\n  // Native\n  Object.assign({}, defaultOpts, opts);\n  ```\n\n  + trim\n\n  문자열 앞뒤에 붙은 공백문자를 제거합니다.\n\n  ```js\n  // jQuery\n  $.trim(string);\n\n  // Native\n  string.trim();\n  ```\n\n  + map\n\n  배열이나 객체 내의 모든 요소를 새 배열에 변환하여 저장합니다.\n\n  ```js\n  // jQuery\n  $.map(array, (value, index) => {\n  });\n\n  // Native\n  array.map((value, index) => {\n  });\n  ```\n\n  + each\n\n  객체나 함수 모두에 매끄럽게 사용할 수 있는 포괄적인 용도의 반복 함수입니다.\n\n  ```js\n  // jQuery\n  $.each(array, (index, value) => {\n  });\n\n  // Native\n  array.forEach((value, index) => {\n  });\n  ```\n\n  + grep\n\n  배열에서 필터 함수를 만족하는 엘리먼트를 찾습니다.\n\n  ```js\n  // jQuery\n  $.grep(array, (value, index) => {\n  });\n\n  // Native\n  array.filter((value, index) => {\n  });\n  ```\n\n  + type\n\n  객체의 JavaScript 내부 [[Class]]를 검사합니다.\n\n  ```js\n  // jQuery\n  $.type(obj);\n\n  // Native\n  function type(item) {\n    const reTypeOf = /(?:^\\[object\\s(.*?)\\]$)/;\n    return Object.prototype.toString.call(item)\n        .replace(reTypeOf, '$1')\n        .toLowerCase();\n  }\n  ```\n\n  + merge\n\n  두 배열을 첫 번째 배열로 합칩니다.\n\n  ```js\n  // jQuery, 중복된 항목을 제거하지 않습니다\n  $.merge(array1, array2);\n\n  // Native, 중복된 항목을 제거하지 않습니다\n  function merge(...args) {\n    return [].concat(...args)\n  }\n\n  // ES6 방식, 중복된 항목을 제거하지 않습니다\n  array1 = [...array1, ...array2]\n\n  // Set 버전, 중복된 항목을 제거합니다\n  function merge(...args) {\n    return Array.from(new Set([].concat(...args)))\n  }\n  ```\n\n  + now\n\n  현재 시간을 숫자로 반환합니다.\n\n  ```js\n  // jQuery\n  $.now();\n\n  // Native\n  Date.now();\n  ```\n\n  + proxy\n\n  함수를 받아서 언제나 특정 context를 갖는 새 함수를 반환합니다.\n\n  ```js\n  // jQuery\n  $.proxy(fn, context);\n\n  // Native\n  fn.bind(context);\n  ```\n\n  <a name=\"makeArray\"></a>+ makeArray\n\n  array-like 한 객체를 진짜 JavaScript 배열로 변환합니다.\n\n  ```js\n  // jQuery\n  $.makeArray(arrayLike);\n\n  // Native\n  Array.prototype.slice.call(arrayLike);\n\n  // ES6 방식: Array.from() 메소드\n  Array.from(arrayLike);\n\n  // ES6 방식: spread 연산자\n  [...arrayLike];\n  ```\n\n- [6.2](#6.2) <a name='6.2'></a> Contains\n\n  주어진 엘리먼트가 주어진 또 다른 엘리먼트를 자손으로 포함하는지 검사합니다.\n\n  ```js\n  // jQuery\n  $.contains(el, child);\n\n  // Native\n  el !== child && el.contains(child);\n  ```\n\n- [6.3](#6.3) <a name='6.3'></a> Globaleval\n\n  JavaScript 코드를 전역적으로 실행합니다.\n\n  ```js\n  // jQuery\n  $.globaleval(code);\n\n  // Native\n  function Globaleval(code) {\n    const script = document.createElement('script');\n    script.text = code;\n\n    document.head.appendChild(script).parentNode.removeChild(script);\n  }\n\n  // eval 함수를 쓸 수도 있습니다. 하지만 $.Globaleval 의 context가 전역인 데 반해 eval 함수의 context 는 실행 영역입니다.\n  eval(code);\n  ```\n\n- [6.4](#6.4) <a name='6.4'></a> parse\n\n  + parseHTML\n\n  문자열을 DOM 노드의 배열로 변환합니다.\n\n  ```js\n  // jQuery\n  $.parseHTML(htmlString);\n\n  // Native\n  function parseHTML(string) {\n    const context = document.implementation.createHTMLDocument();\n\n    // 생성된 도큐먼트를 위해 base href를 지정해서 URL이 있는 엘리먼트들은 도큐먼트 기준으로 처리됩니다.\n    const base = context.createElement('base');\n    base.href = document.location.href;\n    context.head.appendChild(base);\n\n    context.body.innerHTML = string;\n    return context.body.children;\n  }\n  ```\n\n- [6.5](#6.4) <a name='6.5'></a> exists\n\n+ exists\n\n  엘리먼트가 DOM에 존재하는지를 확인합니다\n  \n  ```js\n  // jQuery\n  if ($('selector').length) {\n    // 존재함\n  }\n\n  // Native\n  var element =  document.getElementById('elementId');\n  if (typeof(element) != 'undefined' && element != null) \n  {\n    // 존재함\n  }\n  ```\n\n**[⬆ 목차로 돌아가기](#목차)**\n\n## Promises\n\nPromise는 비동기적인 작업의 결과를 표현합니다. jQuery는 자체적인 promise 처리를 가지고 있습니다. 네이티브 JavaScript엔 [Promises/A+](http://promises-aplus.github.io/promises-spec/) 명세에 맞는 얇고 작은 API를 구현되어 있습니다.\n\n- [7.1](#7.1) <a name='7.1'></a> done, fail, always\n\n  `done`은 promise가 처리되었을 때, `fail`은 promise가 거절되었을 때, `always`는 promise가 어떻게 되었건 실행됩니다.\n\n  ```js\n  // jQuery\n  $promise.done(doneCallback).fail(failCallback).always(alwaysCallback)\n\n  // Native\n  promise.then(doneCallback, failCallback).then(alwaysCallback, alwaysCallback)\n  ```\n\n- [7.2](#7.2) <a name='7.2'></a> when\n\n  `when`은 여러 개의 promise들을 처리할 때 사용됩니다. 이것은 모든 promise가 처리되었을 때 resolve하고 하나라도 거절되면 reject합니다.\n\n  ```js\n  // jQuery\n  $.when($promise1, $promise2).done((promise1Result, promise2Result) => {\n  });\n\n  // Native\n  Promise.all([$promise1, $promise2]).then([promise1Result, promise2Result] => {});\n  ```\n\n- [7.3](#7.3) <a name='7.3'></a> Deferred\n\n  Deferred는 promise를 생성하는 방법입니다.\n\n  ```js\n  // jQuery\n  function asyncFunc() {\n    const defer = new $.Deferred();\n    setTimeout(() => {\n      if(true) {\n        defer.resolve('some_value_computed_asynchronously');\n      } else {\n        defer.reject('failed');\n      }\n    }, 1000);\n\n    return defer.promise();\n  }\n\n  // Native\n  function asyncFunc() {\n    return new Promise((resolve, reject) => {\n      setTimeout(() => {\n        if (true) {\n          resolve('some_value_computed_asynchronously');\n        } else {\n          reject('failed');\n        }\n      }, 1000);\n    });\n  }\n\n  // Deferred way\n  function defer() {\n    const deferred = {};\n    const promise = new Promise((resolve, reject) => {\n      deferred.resolve = resolve;\n      deferred.reject = reject;\n    });\n\n    deferred.promise = () => {\n      return promise;\n    };\n\n    return deferred;\n  }\n\n  function asyncFunc() {\n    const defer = defer();\n    setTimeout(() => {\n      if (true) {\n        defer.resolve('some_value_computed_asynchronously');\n      } else {\n        defer.reject('failed');\n      }\n    }, 1000);\n\n    return defer.promise();\n  }\n  ```\n\n**[⬆ 목차로 돌아가기](#목차)**\n\n## Animation\n\n- [8.1](#8.1) <a name='8.1'></a> Show & Hide\n\n  ```js\n  // jQuery\n  $el.show();\n  $el.hide();\n\n  // Native\n  // show 메소드에 대한 더 자세한 정보를 보고 싶으면  https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L363 를 참고하세요\n  el.style.display = ''|'inline'|'inline-block'|'inline-table'|'block';\n  el.style.display = 'none';\n  ```\n\n- [8.2](#8.2) <a name='8.2'></a> Toggle\n\n  엘리먼트를 출력하거나 숨깁니다.\n\n  ```js\n  // jQuery\n  $el.toggle();\n\n  // Native\n  if (el.ownerDocument.defaultView.getComputedStyle(el, null).display === 'none') {\n    el.style.display = ''|'inline'|'inline-block'|'inline-table'|'block';\n  } else {\n    el.style.display = 'none';\n  }\n  ```\n\n- [8.3](#8.3) <a name='8.3'></a> FadeIn & FadeOut\n\n  ```js\n  // jQuery\n  $el.fadeIn(3000);\n  $el.fadeOut(3000);\n\n  // Native fadeOut\n  function fadeOut(el, ms) {\n    if (ms) {\n      el.style.transition = `opacity ${ms} ms`;\n      el.addEventListener(\n        'transitionend',\n        function(event) {\n          el.style.display = 'none';\n        },\n        false\n      );\n    }\n    el.style.opacity = '0';\n  }\n\n  // Native fadeIn\n  function fadeIn(elem, ms) {\n    elem.style.opacity = 0;\n\n    if (ms) {\n      let opacity = 0;\n      const timer = setInterval(function() {\n        opacity += 50 / ms;\n        if (opacity >= 1) {\n          clearInterval(timer);\n          opacity = 1;\n        }\n        elem.style.opacity = opacity;\n      }, 50);\n    } else {\n      elem.style.opacity = 1;\n    }\n  }\n  ```\n\n- [8.4](#8.4) <a name='8.4'></a> FadeTo\n\n  엘리먼트의 투명도(opacity)를 조정합니다.\n\n  ```js\n  // jQuery\n  $el.fadeTo('slow',0.15);\n  // Native\n  el.style.transition = 'opacity 3s'; // 'slow'가 3초라고 가정합니다.\n  el.style.opacity = '0.15';\n  ```\n\n- [8.5](#8.5) <a name='8.5'></a> FadeToggle\n\n  엘리먼트를 투명도를 조절해서 보여주거나 숨깁니다.\n\n  ```js\n  // jQuery\n  $el.fadeToggle();\n\n  // Native\n  el.style.transition = 'opacity 3s';\n  const { opacity } = el.ownerDocument.defaultView.getComputedStyle(el, null);\n  if (opacity === '1') {\n    el.style.opacity = '0';\n  } else {\n    el.style.opacity = '1';\n  }\n  ```\n\n- [8.6](#8.6) <a name='8.6'></a> SlideUp & SlideDown\n\n  ```js\n  // jQuery\n  $el.slideUp();\n  $el.slideDown();\n\n  // Native\n  const originHeight = '100px';\n  el.style.transition = 'height 3s';\n  // slideUp\n  el.style.height = '0px';\n  // slideDown\n  el.style.height = originHeight;\n  ```\n\n- [8.7](#8.7) <a name='8.7'></a> SlideToggle\n\n  슬라이딩 모션과 함께 엘리먼트를 보이거나 숨깁니다.\n\n  ```js\n  // jQuery\n  $el.slideToggle();\n\n  // Native\n  const originHeight = '100px';\n  el.style.transition = 'height 3s';\n  const { height } = el.ownerDocument.defaultView.getComputedStyle(el, null);\n  if (parseInt(height, 10) === 0) {\n    el.style.height = originHeight;\n  } else {\n    el.style.height = '0px';\n  }\n  ```\n\n- [8.8](#8.8) <a name='8.8'></a> Animate\n\n  자체적으로 CSS 프로퍼티들을 에니메이션합니다.\n\n  ```js\n  // jQuery\n  $el.animate({ params }, speed);\n\n  // Native\n  el.style.transition = 'all ' + speed;\n  Object.keys(params).forEach((key) => {\n    el.style[key] = params[key];\n  });\n  ```\n\n## 대안방법\n\n* [You Might Not Need jQuery](http://youmightnotneedjquery.com/) - 일반 자바스크립트로 공통이벤트, 엘리먼트, ajax 등을 다루는 방법 예제.\n* [npm-dom](http://github.com/npm-dom) 과 [webmodules](http://github.com/webmodules) - 개별 DOM모듈을 NPM에서 찾을 수 있습니다.\n\n## Browser Support\n\n![Chrome][chrome-image] | ![Firefox][firefox-image] | ![IE][ie-image] | ![Opera][opera-image] | ![Safari][safari-image]\n--- | --- | --- | --- | --- |\nLatest ✔ | Latest ✔ | 10+ ✔ | Latest ✔ | 6.1+ ✔ |\n\n# License\n\nMIT\n\n[chrome-image]: https://raw.github.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png\n[firefox-image]: https://raw.github.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png\n[ie-image]: https://raw.github.com/alrra/browser-logos/master/src/archive/internet-explorer_9-11/internet-explorer_9-11_48x48.png\n[opera-image]: https://raw.github.com/alrra/browser-logos/master/src/opera/opera_48x48.png\n[safari-image]: https://raw.github.com/alrra/browser-logos/master/src/safari/safari_48x48.png\n"
  },
  {
    "path": "README.md",
    "content": "## You (Might) Don't Need jQuery\n\nFrontend 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.\n\nℹ️ Notice: \n1. jQuery is still a great library and has many valid use cases. Don’t migrate away if you don’t want to!\n2. The alternatives are not completely equivalent in all scenarios, and it is recommended that you test it before using it.\n\n## Table of Contents\n\n1. [Translations](#translations)\n1. [Query Selector](#query-selector)\n1. [CSS & Style](#css--style)\n1. [DOM Manipulation](#dom-manipulation)\n1. [Ajax](#ajax)\n1. [Events](#events)\n1. [Utilities](#utilities)\n1. [Promises](#promises)\n1. [Animation](#animation)\n1. [Alternatives](#alternatives)\n1. [Browser Support](#browser-support)\n\n## Translations\n\n* [한국어](./README.ko-KR.md)\n* [正體中文](./README.zh-TW.md)\n* [简体中文](./README.zh-CN.md)\n* [Bahasa Melayu](./README-my.md)\n* [Bahasa Indonesia](./README-id.md)\n* [Português(PT-BR)](./README.pt-BR.md)\n* [Tiếng Việt Nam](./README-vi.md)\n* [Español](./README-es.md)\n* [Русский](./README-ru.md)\n* [Кыргызча](./README-kg.md)\n* [Türkçe](./README-tr.md)\n* [Italiano](./README-it.md)\n* [Français](./README-fr.md)\n* [日本語](./README-ja.md)\n* [Polski](./README-pl.md)\n\n## Query Selector\n\nIn place of common selectors like class, id or attribute we can use `document.querySelector` or `document.querySelectorAll` for substitution. The differences lie in:\n* `document.querySelector` returns the first matched element\n* `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](#makeArray)\n* If there are no elements matched, jQuery and `document.querySelectorAll` will return `[]`, whereas `document.querySelector` will return `null`.\n\n> 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.\n\n- [1.0](#1.0) <a name='1.0'></a> Query by selector\n\n  ```js\n  // jQuery\n  $('selector');\n\n  // Native\n  document.querySelectorAll('selector');\n  ```\n\n- [1.1](#1.1) <a name='1.1'></a> Query by class\n\n  ```js\n  // jQuery\n  $('.class');\n\n  // Native\n  document.querySelectorAll('.class');\n\n  // or\n  document.getElementsByClassName('class');\n  ```\n\n- [1.2](#1.2) <a name='1.2'></a> Query by id\n\n  ```js\n  // jQuery\n  $('#id');\n\n  // Native\n  document.querySelector('#id');\n\n  // or\n  document.getElementById('id');\n\n  // or\n  window['id']\n  ```\n\n- [1.3](#1.3) <a name='1.3'></a> Query by attribute\n\n  ```js\n  // jQuery\n  $('a[target=_blank]');\n\n  // Native\n  document.querySelectorAll('a[target=_blank]');\n  ```\n\n- [1.4](#1.4) <a name='1.4'></a> Query in descendants\n\n  ```js\n  // jQuery\n  $el.find('li');\n\n  // Native\n  el.querySelectorAll('li');\n  ```\n\n- [1.5](#1.5) <a name='1.5'></a> Sibling/Previous/Next Elements\n\n  + All siblings\n\n    ```js\n    // jQuery\n    $el.siblings();\n\n    // Native - latest, Edge13+\n    [...el.parentNode.children].filter((child) =>\n      child !== el\n    );\n    // Native (alternative) - latest, Edge13+\n    Array.from(el.parentNode.children).filter((child) =>\n      child !== el\n    );\n    // Native - IE10+\n    Array.prototype.filter.call(el.parentNode.children, (child) =>\n      child !== el\n    );\n    ```\n\n  + Previous sibling\n\n    ```js\n    // jQuery\n    $el.prev();\n\n    // Native\n    el.previousElementSibling;\n    ```\n  + Next sibling\n\n    ```js\n    // jQuery\n    $el.next();\n\n    // Native\n    el.nextElementSibling;\n    ```\n\n  + All previous siblings\n\n    ```js\n    // jQuery (optional filter selector)\n    $el.prevAll($filter);\n\n    // Native (optional filter function)\n    function getPreviousSiblings(elem, filter) {\n      var sibs = [];\n      while (elem = elem.previousSibling) {\n          if (elem.nodeType === 3) continue; // ignore text nodes\n          if (!filter || filter(elem)) sibs.push(elem);\n      }\n      return sibs;\n    }\n\n  + All next siblings\n\n    ```js\n    // jQuery (optional selector filter)\n    $el.nextAll($filter);\n\n    // Native (optional filter function)\n    function getNextSiblings(elem, filter) {\n            var sibs = [];\n            var nextElem = elem.parentNode.firstChild;\n            do {\n                if (nextElem.nodeType === 3) continue; // ignore text nodes\n                if (nextElem === elem) continue; // ignore elem of target\n                if (nextElem === elem.nextElementSibling) {\n                    if (!filter || filter(elem)) {\n                        sibs.push(nextElem);\n                        elem = nextElem;\n                    }\n                }\n            } while(nextElem = nextElem.nextSibling)\n            return sibs;\n        }\n\nAn example of filter function:\n\n```js\nfunction exampleFilter(elem) {\n  switch (elem.nodeName.toUpperCase()) {\n    case 'DIV':\n      return true;\n    case 'SPAN':\n      return true;\n    default:\n      return false;\n  }\n}\n```\n\n- [1.6](#1.6) <a name='1.6'></a> Closest\n\n  Return the first matched element by provided selector, traversing from current element up through its ancestors in the DOM tree.\n\n  ```js\n  // jQuery\n  $el.closest(selector);\n\n  // Native - Only latest, NO IE\n  el.closest(selector);\n\n  // Native - IE10+\n  function closest(el, selector) {\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    while (el) {\n      if (matchesSelector.call(el, selector)) {\n        return el;\n      } else {\n        el = el.parentElement;\n      }\n    }\n    return null;\n  }\n  ```\n\n- [1.7](#1.7) <a name='1.7'></a> Parents Until\n\n  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.\n\n  ```js\n  // jQuery\n  $el.parentsUntil(selector, filter);\n\n  // Native\n  function parentsUntil(el, selector, filter) {\n    const result = [];\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    // match start from parent\n    el = el.parentElement;\n    while (el && !matchesSelector.call(el, selector)) {\n      if (!filter) {\n        result.push(el);\n      } else {\n        if (matchesSelector.call(el, filter)) {\n          result.push(el);\n        }\n      }\n      el = el.parentElement;\n    }\n    return result;\n  }\n  ```\n\n- [1.8](#1.8) <a name='1.8'></a> Form\n\n  + Input/Textarea\n\n    ```js\n    // jQuery\n    $('#my-input').val();\n\n    // Native\n    document.querySelector('#my-input').value;\n    ```\n\n  + Get index of e.currentTarget between `.radio`\n\n    ```js\n    // jQuery\n    $('.radio').index(e.currentTarget);\n\n    // Native\n    Array.from(document.querySelectorAll('.radio')).indexOf(e.currentTarget);\n    or\n    Array.prototype.indexOf.call(document.querySelectorAll('.radio'), e.currentTarget);\n    ```\n\n- [1.9](#1.9) <a name='1.9'></a> Iframe Contents\n\n  `$('iframe').contents()` returns `contentDocument` for this specific iframe\n\n  + Iframe contents\n\n    ```js\n    // jQuery\n    $iframe.contents();\n\n    // Native\n    iframe.contentDocument;\n    ```\n\n  + Iframe Query\n\n    ```js\n    // jQuery\n    $iframe.contents().find('.css');\n\n    // Native\n    iframe.contentDocument.querySelectorAll('.css');\n    ```\n\n- [1.10](#1.10) <a name='1.10'></a> Get body\n\n  ```js\n  // jQuery\n  $('body');\n\n  // Native\n  document.body;\n  ```\n\n- [1.11](#1.11) <a name='1.11'></a> Attribute getter and setter\n\n  + Get an attribute\n\n    ```js\n    // jQuery\n    $el.attr('foo');\n\n    // Native\n    el.getAttribute('foo');\n    ```\n  + Set an attribute\n\n    ```js\n    // jQuery\n    $el.attr('foo', 'bar');\n\n    // Native\n    el.setAttribute('foo', 'bar');\n    ```\n\n  + Get a `data-` attribute\n\n    ```js\n    // jQuery\n    $el.data('foo');\n\n    // Native (use `getAttribute`)\n    el.getAttribute('data-foo');\n\n    // Native (use `dataset` if only need to support IE 11+)\n    el.dataset['foo'];\n    ```\n\n- [1.12](#1.12) <a name='1.12'></a> Selector containing string (case-sensitive)\n\n    ```js\n    // jQuery\n    $(\"selector:contains('text')\");\n\n    // Native\n    function contains(selector, text) {\n      var elements = document.querySelectorAll(selector);\n      return Array.from(elements).filter(function(element) {\n        return RegExp(text).test(element.textContent);\n      });\n    }\n    ```\n\n**[⬆ back to top](#table-of-contents)**\n\n## CSS & Style\n\n- [2.1](#2.1) <a name='2.1'></a> CSS\n\n  + Get style\n\n    ```js\n    // jQuery\n    $el.css('color');\n\n    // Native\n    // NOTE: Known bug, will return 'auto' if style value is 'auto'\n    const win = el.ownerDocument.defaultView;\n\n    // null means not to return pseudo styles\n    win.getComputedStyle(el, null).color;\n    ```\n\n  + Set style\n\n    ```js\n    // jQuery\n    $el.css({ color: '#f01' });\n\n    // Native\n    el.style.color = '#f01';\n    ```\n\n  + Get/Set Styles\n\n    ```js\n    // jQuery\n    $el.css({ color: '#f01', 'border-color': '#f02' })\n    \n    // Native\n    Object.assign(el.style, { color: '#f01', borderColor: '#f02' }) \n    ```\n\n  + Add class\n\n    ```js\n    // jQuery\n    $el.addClass(className);\n\n    // Native\n    el.classList.add(className);\n    ```\n\n  + Remove class\n\n    ```js\n    // jQuery\n    $el.removeClass(className);\n\n    // Native\n    el.classList.remove(className);\n    ```\n\n  + has class\n\n    ```js\n    // jQuery\n    $el.hasClass(className);\n\n    // Native\n    el.classList.contains(className);\n    ```\n\n  + Toggle class\n\n    ```js\n    // jQuery\n    $el.toggleClass(className);\n\n    // Native\n    el.classList.toggle(className);\n    ```\n\n- [2.2](#2.2) <a name='2.2'></a> Width & Height\n\n  Width and Height are theoretically identical, take Height as example:\n\n  + Window height\n\n    ```js\n    // window height\n    $(window).height();\n\n    // without scrollbar, behaves like jQuery\n    window.document.documentElement.clientHeight;\n\n    // with scrollbar\n    window.innerHeight;\n    ```\n\n  + Document height\n\n    ```js\n    // jQuery\n    $(document).height();\n\n    // Native\n    const body = document.body;\n    const html = document.documentElement;\n    const height = Math.max(\n      body.offsetHeight,\n      body.scrollHeight,\n      html.clientHeight,\n      html.offsetHeight,\n      html.scrollHeight\n    );\n    ```\n\n  + Element height\n\n    ```js\n    // jQuery\n    $el.height();\n\n    // Native\n    function getHeight(el) {\n      const styles = window.getComputedStyle(el);\n      const height = el.offsetHeight;\n      const borderTopWidth = parseFloat(styles.borderTopWidth);\n      const borderBottomWidth = parseFloat(styles.borderBottomWidth);\n      const paddingTop = parseFloat(styles.paddingTop);\n      const paddingBottom = parseFloat(styles.paddingBottom);\n      return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;\n    }\n\n    // accurate to integer（when `border-box`, it's `height - border`; when `content-box`, it's `height + padding`）\n    el.clientHeight;\n\n    // accurate to decimal（when `border-box`, it's `height`; when `content-box`, it's `height + padding + border`）\n    el.getBoundingClientRect().height;\n    ```\n\n- [2.3](#2.3) <a name='2.3'></a> Position & Offset\n\n  + Position\n\n    Get the current coordinates of the element relative to the offset parent.\n\n    ```js\n    // jQuery\n    $el.position();\n\n    // Native\n    { left: el.offsetLeft, top: el.offsetTop }\n    ```\n\n  + Offset\n\n    Get the current coordinates of the element relative to the document.\n\n    ```js\n    // jQuery\n    $el.offset();\n\n    // Native\n    function getOffset (el) {\n      const box = el.getBoundingClientRect();\n\n      return {\n        top: box.top + window.pageYOffset - document.documentElement.clientTop,\n        left: box.left + window.pageXOffset - document.documentElement.clientLeft\n      };\n    }\n    ```\n\n- [2.4](#2.4) <a name='2.4'></a> Scroll Top\n\n  Get the current vertical position of the scroll bar for the element.\n\n  ```js\n  // jQuery\n  $(window).scrollTop();\n\n  // Native\n  (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;\n  ```\n\n**[⬆ back to top](#table-of-contents)**\n\n## DOM Manipulation\n\n- [3.1](#3.1) <a name='3.1'></a> Remove\n\n  Remove the element from the DOM.\n\n  ```js\n  // jQuery\n  $el.remove();\n\n  // Native\n  el.parentNode.removeChild(el);\n  ```\n\n- [3.2](#3.2) <a name='3.2'></a> Text\n\n  + Get text\n\n    Get the combined text contents of the element including their descendants,\n\n    ```js\n    // jQuery\n    $el.text();\n\n    // Native\n    el.textContent;\n    ```\n\n  + Set text\n\n    Set the content of the element to the specified text.\n\n    ```js\n    // jQuery\n    $el.text(string);\n\n    // Native\n    el.textContent = string;\n    ```\n\n- [3.3](#3.3) <a name='3.3'></a> HTML\n\n  + Get HTML\n\n    ```js\n    // jQuery\n    $el.html();\n\n    // Native\n    el.innerHTML;\n    ```\n\n  + Set HTML\n\n    ```js\n    // jQuery\n    $el.html(htmlString);\n\n    // Native\n    el.innerHTML = htmlString;\n    ```\n\n- [3.4](#3.4) <a name='3.4'></a> Append\n\n  Append child element after the last child of parent element\n\n  ```js\n  // jQuery: unified syntax for DOMString and Node objects\n  $parent.append(newEl | '<div id=\"container\">Hello World</div>');\n\n  // Native: different syntax\n  parent.insertAdjacentHTML('beforeend', '<div id=\"container\">Hello World</div>');\n  parent.appendChild(newEl);\n\n  // Native (ES6-way): unified syntax\n  parent.append(newEl | '<div id=\"container\">Hello World</div>');\n  ```\n\n- [3.5](#3.5) <a name='3.5'></a> Prepend\n\n  ```js\n  // jQuery: unified syntax for DOMString and Node objects\n  $parent.prepend(newEl | '<div id=\"container\">Hello World</div>');\n\n  // Native: different syntax\n  parent.insertAdjacentHTML('afterbegin', '<div id=\"container\">Hello World</div>');\n  parent.insertBefore(newEl, parent.firstChild);\n\n  // Native (ES6-way): unified syntax\n  parent.prepend(newEl | '<div id=\"container\">Hello World</div>');\n  ```\n\n- [3.6](#3.6) <a name='3.6'></a> insertBefore\n\n  Insert a new node before the selected elements\n\n  ```js\n  // jQuery\n  $newEl.insertBefore(selector);\n\n  // Native (HTML string)\n  el.insertAdjacentHTML('beforebegin ', '<div id=\"container\">Hello World</div>');\n\n  // Native (Element)\n  const el = document.querySelector(selector);\n  if (el.parentNode) {\n    el.parentNode.insertBefore(newEl, el);\n  }\n  ```\n\n- [3.7](#3.7) <a name='3.7'></a> insertAfter\n\n  Insert a new node after the selected elements\n\n  ```js\n  // jQuery\n  $newEl.insertAfter(selector);\n\n  // Native (HTML string)\n  el.insertAdjacentHTML('afterend', '<div id=\"container\">Hello World</div>');\n\n  // Native (Element)\n  const el = document.querySelector(selector);\n  if (el.parentNode) {\n    el.parentNode.insertBefore(newEl, el.nextSibling);\n  }\n  ```\n\n- [3.8](#3.8) <a name='3.8'></a> is\n\n  Return `true` if it matches the query selector\n\n  ```js\n  // jQuery - Notice `is` also works with a function, an existing jQuery object or a DOM element, which are not of concern here\n  $el.is(selector);\n\n  // Native\n  el.matches(selector);\n  ```\n- [3.9](#3.9) <a name='3.9'></a> clone\n\n  Create a deep copy of an element: it copies the matched element as well as all of its descendant elements and text nodes.\n\n  ```js\n  // jQuery. Sets parameter as `true` to indicate that event handlers should be copied along with the element.\n  $el.clone();\n\n  // Native\n  el.cloneNode();\n\n  ```\n\n- [3.10](#3.10) <a name='3.10'></a> empty\n\n  Remove all child nodes\n\n  ```js\n  // jQuery\n  $el.empty();\n\n  // Native\n  el.innerHTML = null;\n  ```\n\n- [3.11](#3.11) <a name='3.11'></a> wrap\n\n  Wrap an HTML structure around each element\n\n  ```js\n  // jQuery\n  $('.inner').wrap('<div class=\"wrapper\"></div>');\n\n  // Native\n  Array.from(document.querySelectorAll('.inner')).forEach((el) => {\n    const wrapper = document.createElement('div');\n    wrapper.className = 'wrapper';\n    el.parentNode.insertBefore(wrapper, el);\n    wrapper.appendChild(el);\n  });\n  ```\n\n- [3.12](#3.12) <a name='3.12'></a> unwrap\n\n  Remove the parents of the set of matched elements from the DOM\n\n  ```js\n  // jQuery\n  $('.inner').unwrap();\n\n  // Native\n  Array.from(document.querySelectorAll('.inner')).forEach((el) => {\n    let elParentNode = el.parentNode;\n\n    if(elParentNode !== document.body) {\n        elParentNode.parentNode.insertBefore(el, elParentNode);\n        elParentNode.parentNode.removeChild(elParentNode);\n    }\n  });\n  ```\n\n- [3.13](#3.13) <a name='3.13'></a> replaceWith\n\n  Replace each element in the set of matched elements with the provided new content\n\n  ```js\n  // jQuery\n  $('.inner').replaceWith('<div class=\"outer\"></div>');\n\n  // Native (alternative) - latest, Edge17+\n  Array.from(document.querySelectorAll('.inner')).forEach((el) => {\n    const outer = document.createElement('div');\n    outer.className = 'outer';\n    el.replaceWith(outer);\n  });\n\n  // Native\n  Array.from(document.querySelectorAll('.inner')).forEach((el) => {\n    const outer = document.createElement('div');\n    outer.className = 'outer';\n    el.parentNode.replaceChild(outer, el);\n  });\n  ```\n\n- [3.14](#3.14) <a name='3.14'></a> simple parse\n\n  Parse a string into HTML/SVG/XML\n\n  ```js\n  // jQuery\n  $(`<ol>\n    <li>a</li>\n    <li>b</li>\n  </ol>\n  <ol>\n    <li>c</li>\n    <li>d</li>\n  </ol>`);\n\n  // Native\n  range = document.createRange();\n  parse = range.createContextualFragment.bind(range);\n\n  parse(`<ol>\n    <li>a</li>\n    <li>b</li>\n  </ol>\n  <ol>\n    <li>c</li>\n    <li>d</li>\n  </ol>`);\n  ```\n\n\n**[⬆ back to top](#table-of-contents)**\n\n## Ajax\n\n[Fetch API](https://fetch.spec.whatwg.org/) 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.\n\nTry [github/fetch](http://github.com/github/fetch) on IE9+ or [fetch-ie8](https://github.com/camsong/fetch-ie8/) on IE8+, [fetch-jsonp](https://github.com/camsong/fetch-jsonp) to make JSONP requests.\n\n- [4.1](#4.1) <a name='4.1'></a> Load data from the server and place the returned HTML into the matched element.\n\n  ```js\n  // jQuery\n  $(selector).load(url, completeCallback)\n\n  // Native\n  fetch(url).then(data => data.text()).then(data => {\n    document.querySelector(selector).innerHTML = data\n  }).then(completeCallback)\n  ```\n\n**[⬆ back to top](#table-of-contents)**\n\n## Events\n\nFor a complete replacement with namespace and delegation, refer to https://github.com/oneuijs/oui-dom-events\n\n- [5.0](#5.0) <a name='5.0'></a> Document ready by `DOMContentLoaded`\n\n  ```js\n    // jQuery\n    $(document).ready(eventHandler);\n\n    // Native\n    // Check if the DOMContentLoaded has already been completed\n    if (document.readyState !== 'loading') {\n      eventHandler();\n    } else {\n      document.addEventListener('DOMContentLoaded', eventHandler);\n    }\n\n    // Native \n    // Example 2 - Ternary Operator - Async\n    // Check if the DOMContentLoaded has already been completed\n    (async function() {\n      (document.readyState !== 'loading') ?\n        eventHandler() : document.addEventListener('DOMContentLoaded',\n          function() {\n            eventHandler(); // EventHandler\n          });\n    })();\n\n    // Native\n    // Example 3 - Ternary Operator - Non Async\n    // Check if the DOMContentLoaded has already been completed\n    (function() {\n      (document.readyState !== 'loading') ?\n        eventHandler() : document.addEventListener('DOMContentLoaded',\n          function() {\n            eventHandler(); // EventHandler\n          });\n    })();\n  ``` \n\n- [5.1](#5.1) <a name='5.1'></a> Bind an event with on\n\n  ```js\n  // jQuery\n  $el.on(eventName, eventHandler);\n\n  // Native\n  el.addEventListener(eventName, eventHandler);\n  ```\n\n- [5.2](#5.2) <a name='5.2'></a> Unbind an event with off\n\n  ```js\n  // jQuery\n  $el.off(eventName, eventHandler);\n\n  // Native\n  el.removeEventListener(eventName, eventHandler);\n  ```\n\n- [5.3](#5.3) <a name='5.3'></a> Trigger\n\n  ```js\n  // jQuery\n  $(el).trigger('custom-event', {key1: 'data'});\n\n  // Native\n  if (window.CustomEvent) {\n    const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});\n  } else {\n    const event = document.createEvent('CustomEvent');\n    event.initCustomEvent('custom-event', true, true, {key1: 'data'});\n  }\n\n  el.dispatchEvent(event);\n  ```\n\n**[⬆ back to top](#table-of-contents)**\n\n## Utilities\n\nMost 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](https://lodash.com) is a recommended replacement.\n\n- [6.1](#6.1) <a name='6.1'></a> Basic utilities\n\n  + isArray\n\n  Determine whether the argument is an array.\n\n  ```js\n  // jQuery\n  $.isArray(array);\n\n  // Native\n  Array.isArray(array);\n  ```\n\n  + isWindow\n\n  Determine whether the argument is a window.\n\n  ```js\n  // jQuery\n  $.isWindow(obj);\n\n  // Native\n  function isWindow(obj) {\n    return obj !== null && obj !== undefined && obj === obj.window;\n  }\n  ```\n\n  + inArray\n\n  Search for a specified value within an array and return its index (or -1 if not found).\n\n  ```js\n  // jQuery\n  $.inArray(item, array);\n\n  // Native\n  array.indexOf(item) > -1;\n\n  // ES6-way\n  array.includes(item);\n  ```\n\n  + isNumeric\n\n  Determine if the argument passed is numerical.\n  Use `typeof` to decide the type or the `type` example for better accuracy.\n\n  ```js\n  // jQuery\n  $.isNumeric(item);\n\n  // Native\n  function isNumeric(n) {\n    return !isNaN(parseFloat(n)) && isFinite(n);\n  }\n  ```\n\n  + isFunction\n\n  Determine if the argument passed is a JavaScript function object.\n\n  ```js\n  // jQuery\n  $.isFunction(item);\n\n  // Native\n  function isFunction(item) {\n    if (typeof item === 'function') {\n      return true;\n    }\n    var type = Object.prototype.toString.call(item);\n    return type === '[object Function]' || type === '[object GeneratorFunction]';\n  }\n  ```\n\n  + isEmptyObject\n\n  Check to see if an object is empty (contains no enumerable properties).\n\n  ```js\n  // jQuery\n  $.isEmptyObject(obj);\n\n  // Native\n  function isEmptyObject(obj) {\n    return Object.keys(obj).length === 0;\n  }\n  ```\n\n  + isPlainObject\n\n  Check to see if an object is a plain object (created using “{}” or “new Object”).\n\n  ```js\n  // jQuery\n  $.isPlainObject(obj);\n\n  // Native\n  function isPlainObject(obj) {\n    if (typeof (obj) !== 'object' || obj.nodeType || obj !== null && obj !== undefined && obj === obj.window) {\n      return false;\n    }\n\n    if (obj.constructor &&\n        !Object.prototype.hasOwnProperty.call(obj.constructor.prototype, 'isPrototypeOf')) {\n      return false;\n    }\n\n    return true;\n  }\n  ```\n\n  + extend\n\n  Merge the contents of two or more objects together into a new object, without modifying either argument.\n  object.assign is part of ES6 API, and you could also use a [polyfill](https://github.com/ljharb/object.assign).\n\n  ```js\n  // jQuery\n  $.extend({}, object1, object2);\n\n  // Native\n  Object.assign({}, object1, object2);\n  ```\n\n  + trim\n\n  Remove the white-space from the beginning and end of a string.\n\n  ```js\n  // jQuery\n  $.trim(string);\n\n  // Native\n  string.trim();\n  ```\n\n  + map\n\n  Translate all items in an array or object to new array of items.\n\n  ```js\n  // jQuery\n  $.map(array, (value, index) => {\n  });\n\n  // Native\n  array.map((value, index) => {\n  });\n  ```\n\n  + each\n\n  A generic iterator function, which can be used to seamlessly iterate over both objects and arrays.\n\n  ```js\n  // jQuery\n  $.each(array, (index, value) => {\n  });\n\n  // Native\n  array.forEach((value, index) => {\n  });\n  ```\n\n  + grep\n\n  Finds the elements of an array which satisfy a filter function.\n\n  ```js\n  // jQuery\n  $.grep(array, (value, index) => {\n  });\n\n  // Native\n  array.filter((value, index) => {\n  });\n  ```\n\n  + type\n\n  Determine the internal JavaScript [Class] of an object.\n\n  ```js\n  // jQuery\n  $.type(obj);\n\n  // Native\n  function type(item) {\n    const reTypeOf = /(?:^\\[object\\s(.*?)\\]$)/;\n    return Object.prototype.toString.call(item)\n      .replace(reTypeOf, '$1')\n      .toLowerCase();\n  }\n  ```\n\n  + merge\n\n  Merge the contents of two arrays together into the first array.\n\n  ```js\n  // jQuery, doesn't remove duplicate items\n  $.merge(array1, array2);\n\n  // Native, doesn't remove duplicate items\n  function merge(...args) {\n    return [].concat(...args)\n  }\n\n  // ES6-way, doesn't remove duplicate items\n  array1 = [...array1, ...array2]\n\n  // Set version, does remove duplicate items\n  function merge(...args) {\n    return Array.from(new Set([].concat(...args)))\n  }\n  ```\n\n  + now\n\n  Return a number representing the current time.\n\n  ```js\n  // jQuery\n  $.now();\n\n  // Native\n  Date.now();\n  ```\n\n  + proxy\n\n  Takes a function and returns a new one that will always have a particular context.\n\n  ```js\n  // jQuery\n  $.proxy(fn, context);\n\n  // Native\n  fn.bind(context);\n  ```\n\n  <a name=\"makeArray\"></a>+ makeArray\n\n  Convert an array-like object into a true JavaScript array.\n\n  ```js\n  // jQuery\n  $.makeArray(arrayLike);\n\n  // Native\n  Array.prototype.slice.call(arrayLike);\n\n  // ES6-way: Array.from() method\n  Array.from(arrayLike);\n\n  // ES6-way: spread operator\n  [...arrayLike];\n  ```\n\n- [6.2](#6.2) <a name='6.2'></a> Contains\n\n  Check to see if a DOM element is a descendant of another DOM element.\n\n  ```js\n  // jQuery\n  $.contains(el, child);\n\n  // Native\n  el !== child && el.contains(child);\n  ```\n\n- [6.3](#6.3) <a name='6.3'></a> Globaleval\n\n  Execute some JavaScript code globally.\n\n  ```js\n  // jQuery\n  $.globaleval(code);\n\n  // Native\n  function Globaleval(code) {\n    const script = document.createElement('script');\n    script.text = code;\n\n    document.head.appendChild(script).parentNode.removeChild(script);\n  }\n\n  // Use eval, but context of eval is current, context of $.Globaleval is global.\n  eval(code);\n  ```\n\n- [6.4](#6.4) <a name='6.4'></a> parse\n\n  + parseHTML\n\n  Parses a string into an array of DOM nodes.\n\n  ```js\n  // jQuery\n  $.parseHTML(htmlString);\n\n  // Native\n  function parseHTML(string) {\n    const context = document.implementation.createHTMLDocument();\n\n    // Set the base href for the created document so any parsed elements with URLs\n    // are based on the document's URL\n    const base = context.createElement('base');\n    base.href = document.location.href;\n    context.head.appendChild(base);\n\n    context.body.innerHTML = string;\n    return context.body.children;\n  }\n  ```\n- [6.5](#6.4) <a name='6.5'></a> exists\n\n+ exists\n\n  Check if an element exists in the DOM\n\n  ```js\n  // jQuery\n  if ($('selector').length) {\n     // exists\n  }\n\n  // Native\n  var element =  document.getElementById('elementId');\n  if (typeof(element) != 'undefined' && element != null)\n  {\n     // exists\n  }\n  ```\n\n**[⬆ back to top](#table-of-contents)**\n\n## Promises\n\nA 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+](http://promises-aplus.github.io/promises-spec/) specification.\n\n- [7.1](#7.1) <a name='7.1'></a> done, fail, always\n\n  `done` is called when promise is resolved, `fail` is called when promise is rejected, `always` is called when promise is either resolved or rejected.\n\n  ```js\n  // jQuery\n  $promise.done(doneCallback).fail(failCallback).always(alwaysCallback)\n\n  // Native\n  promise.then(doneCallback, failCallback).then(alwaysCallback, alwaysCallback)\n  ```\n\n- [7.2](#7.2) <a name='7.2'></a> when\n\n  `when` is used to handle multiple promises. It will resolve when all promises are resolved, and reject if either one is rejected.\n\n  ```js\n  // jQuery\n  $.when($promise1, $promise2).done((promise1Result, promise2Result) => {\n  });\n\n  // Native\n  Promise.all([$promise1, $promise2]).then([promise1Result, promise2Result] => {});\n  ```\n\n- [7.3](#7.3) <a name='7.3'></a> Deferred\n\n  Deferred is a way to create promises.\n\n  ```js\n  // jQuery\n  function asyncFunc() {\n    const defer = new $.Deferred();\n    setTimeout(() => {\n      if(true) {\n        defer.resolve('some_value_computed_asynchronously');\n      } else {\n        defer.reject('failed');\n      }\n    }, 1000);\n\n    return defer.promise();\n  }\n\n  // Native\n  function asyncFunc() {\n    return new Promise((resolve, reject) => {\n      setTimeout(() => {\n        if (true) {\n          resolve('some_value_computed_asynchronously');\n        } else {\n          reject('failed');\n        }\n      }, 1000);\n    });\n  }\n\n  // Deferred way\n  function defer() {\n    const deferred = {};\n    const promise = new Promise((resolve, reject) => {\n      deferred.resolve = resolve;\n      deferred.reject = reject;\n    });\n\n    deferred.promise = () => {\n      return promise;\n    };\n\n    return deferred;\n  }\n\n  function asyncFunc() {\n    const defer = defer();\n    setTimeout(() => {\n      if(true) {\n        defer.resolve('some_value_computed_asynchronously');\n      } else {\n        defer.reject('failed');\n      }\n    }, 1000);\n\n    return defer.promise();\n  }\n  ```\n\n**[⬆ back to top](#table-of-contents)**\n\n## Animation\n\n- [8.1](#8.1) <a name='8.1'></a> Show & Hide\n\n  ```js\n  // jQuery\n  $el.show();\n  $el.hide();\n\n  // Native\n  // More detail about show method, please refer to https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L363\n  el.style.display = ''|'inline'|'inline-block'|'inline-table'|'block';\n  el.style.display = 'none';\n  ```\n\n- [8.2](#8.2) <a name='8.2'></a> Toggle\n\n  Display or hide the element.\n\n  ```js\n  // jQuery\n  $el.toggle();\n\n  // Native\n  if (el.ownerDocument.defaultView.getComputedStyle(el, null).display === 'none') {\n    el.style.display = ''|'inline'|'inline-block'|'inline-table'|'block';\n  } else {\n    el.style.display = 'none';\n  }\n  ```\n\n- [8.3](#8.3) <a name='8.3'></a> FadeIn & FadeOut\n\n  ```js\n  // jQuery\n  $el.fadeIn(3000);\n  $el.fadeOut(3000);\n\n  // Native fadeOut\n  function fadeOut(el, ms) {\n    if (ms) {\n      el.style.transition = `opacity ${ms} ms`;\n      el.addEventListener(\n        'transitionend',\n        function(event) {\n          el.style.display = 'none';\n        },\n        false\n      );\n    }\n    el.style.opacity = '0';\n  }\n\n  // Native fadeIn\n  function fadeIn(elem, ms) {\n    elem.style.opacity = 0;\n\n    if (ms) {\n      let opacity = 0;\n      const timer = setInterval(function() {\n        opacity += 50 / ms;\n        if (opacity >= 1) {\n          clearInterval(timer);\n          opacity = 1;\n        }\n        elem.style.opacity = opacity;\n      }, 50);\n    } else {\n      elem.style.opacity = 1;\n    }\n  }\n  ```\n\n- [8.4](#8.4) <a name='8.4'></a> FadeTo\n\n  Adjust the opacity of the element.\n\n  ```js\n  // jQuery\n  $el.fadeTo('slow',0.15);\n  // Native\n  el.style.transition = 'opacity 3s'; // assume 'slow' equals 3 seconds\n  el.style.opacity = '0.15';\n  ```\n\n- [8.5](#8.5) <a name='8.5'></a> FadeToggle\n\n  Display or hide the element by animating their opacity.\n\n  ```js\n  // jQuery\n  $el.fadeToggle();\n\n  // Native\n  el.style.transition = 'opacity 3s';\n  const { opacity } = el.ownerDocument.defaultView.getComputedStyle(el, null);\n  if (opacity === '1') {\n    el.style.opacity = '0';\n  } else {\n    el.style.opacity = '1';\n  }\n  ```\n\n- [8.6](#8.6) <a name='8.6'></a> SlideUp & SlideDown\n\n  ```js\n  // jQuery\n  $el.slideUp();\n  $el.slideDown();\n\n  // Native\n  const originHeight = '100px';\n  el.style.transition = 'height 3s';\n  // slideUp\n  el.style.height = '0px';\n  // slideDown\n  el.style.height = originHeight;\n  ```\n\n- [8.7](#8.7) <a name='8.7'></a> SlideToggle\n\n  Display or hide the element with a sliding motion.\n\n  ```js\n  // jQuery\n  $el.slideToggle();\n\n  // Native\n  const originHeight = '100px';\n  el.style.transition = 'height 3s';\n  const { height } = el.ownerDocument.defaultView.getComputedStyle(el, null);\n  if (parseInt(height, 10) === 0) {\n    el.style.height = originHeight;\n  } else {\n   el.style.height = '0px';\n  }\n  ```\n\n- [8.8](#8.8) <a name='8.8'></a> Animate\n\n  Perform a custom animation of a set of CSS properties.\n\n  ```js\n  // jQuery\n  $el.animate({ params }, speed);\n\n  // Native\n  el.style.transition = 'all ' + speed;\n  Object.keys(params).forEach((key) => {\n    el.style[key] = params[key];\n  });\n  ```\n\n## Alternatives\n\n* [You Might Not Need jQuery](http://youmightnotneedjquery.com/) - Examples of how to do common event, element, ajax etc with plain javascript.\n* [npm-dom](http://github.com/npm-dom) and [webmodules](http://github.com/webmodules) - Organizations you can find individual DOM modules on NPM\n\n## Browser Support\n\n![Chrome][chrome-image] | ![Firefox][firefox-image] | ![IE][ie-image] | ![Opera][opera-image] | ![Safari][safari-image]\n--- | --- | --- | --- | --- |\nLatest ✔ | Latest ✔ | 10+ ✔ | Latest ✔ | 6.1+ ✔ |\n\n# License\n\nMIT\n\n[chrome-image]: https://raw.github.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png\n[firefox-image]: https://raw.github.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png\n[ie-image]: https://raw.github.com/alrra/browser-logos/master/src/archive/internet-explorer_9-11/internet-explorer_9-11_48x48.png\n[opera-image]: https://raw.github.com/alrra/browser-logos/master/src/opera/opera_48x48.png\n[safari-image]: https://raw.github.com/alrra/browser-logos/master/src/safari/safari_48x48.png\n"
  },
  {
    "path": "README.pt-BR.md",
    "content": "## You (Might) Don't Need jQuery\n\nVocê não precisa de jQuery\n---\n\nAmbientes Frontend evoluem rapidamente nos dias de hoje, navegadores modernos já implementaram uma grande parte das APIs DOM/BOM que são boas o suficiente. Nós não temos que aprender jQuery a partir do zero para manipulação do DOM ou eventos. Nesse meio tempo, graças a bibliotecas frontend como React, Angular e Vue, a manipulação direta do DOM torna-se um anti-padrão, jQuery é menos importante do que nunca. Este projeto resume a maioria das alternativas dos métodos jQuery em implementação nativa, com suporte ao IE 10+.\n\n## Tabela de conteúdos\n\n1. [Translations](#translations)\n1. [Query Selector](#query-selector)\n1. [CSS & Estilo](#css--estilo)\n1. [Manipulação do DOM](#manipulação-do-dom)\n1. [Ajax](#ajax)\n1. [Eventos](#eventos)\n1. [Utilitários](#utilitários)\n1. [Suporte dos Navegadores](#suporte-dos-navegadores)\n\n## Translations\n\n* [한국어](./README.ko-KR.md)\n* [正體中文](./README.zh-TW.md)\n* [简体中文](./README.zh-CN.md)\n* [Bahasa Melayu](./README-my.md)\n* [Bahasa Indonesia](./README-id.md)\n* [Português(PT-BR)](./README.pt-BR.md)\n* [Tiếng Việt Nam](./README-vi.md)\n* [Español](./README-es.md)\n* [Русский](./README-ru.md)\n* [Кыргызча](./README-kg.md)\n* [Türkçe](./README-tr.md)\n* [Italiano](./README-it.md)\n* [Français](./README-fr.md)\n* [日本語](./README-ja.md)\n* [Polski](./README-pl.md)\n\n## Query Selector\n\nNo lugar de seletores comuns como classe, id ou atributo podemos usar `document.querySelector` ou `document.querySelectorAll` para substituição. As diferenças são:\n* `document.querySelector` retorna o primeiro elemento correspondente\n* `document.querySelectorAll` retorna todos os elementos correspondentes como NodeList. Pode ser convertido para Array usando `[].slice.call(document.querySelectorAll(selector) || []);`\n* Se não tiver elementos correspondentes, jQuery retornaria `[]` considerando que a DOM API irá retornar `null`. Preste atenção ao Null Pointer Exception. Você também pode usar `||` para definir um valor padrão caso nenhum elemento seja encontrado, como `document.querySelectorAll(selector) || []`\n\n> Aviso: `document.querySelector` e `document.querySelectorAll` são bastante **LENTOS**, tente usar `getElementById`, `document.getElementsByClassName` ou `document.getElementsByTagName` se você quer ter uma maior performance.\n\n- [1.0](#1.0) <a name='1.0'></a> Query por seletor\n\n  ```js\n  // jQuery\n  $('selector');\n\n  // Nativo\n  document.querySelectorAll('selector');\n  ```\n\n- [1.1](#1.1) <a name='1.1'></a> Query por classe\n\n  ```js\n  // jQuery\n  $('.class');\n\n  // Nativo\n  document.querySelectorAll('.class');\n\n  // ou\n  document.getElementsByClassName('class');\n  ```\n\n- [1.2](#1.2) <a name='1.2'></a> Query por id\n\n  ```js\n  // jQuery\n  $('#id');\n\n  // Nativo\n  document.querySelector('#id');\n\n  // ou\n  document.getElementById('id');\n  ```\n\n- [1.3](#1.3) <a name='1.3'></a> Query por atributo\n\n  ```js\n  // jQuery\n  $('a[target=_blank]');\n\n  // Nativo\n  document.querySelectorAll('a[target=_blank]');\n  ```\n\n- [1.4](#1.4) <a name='1.4'></a> Find sth.\n\n  + Busca por nós\n\n    ```js\n    // jQuery\n    $el.find('li');\n\n    // Nativo\n    el.querySelectorAll('li');\n    ```\n\n  + Buscar `body`\n\n    ```js\n    // jQuery\n    $('body');\n\n    // Nativo\n    document.body;\n    ```\n\n  + Buscar atributos\n\n    ```js\n    // jQuery\n    $el.attr('foo');\n\n    // Nativo\n    e.getAttribute('foo');\n    ```\n\n  + Buscar atributos `data-`\n\n    ```js\n    // jQuery\n    $el.data('foo');\n\n    // Nativo\n    // usando getAttribute\n    el.getAttribute('data-foo');\n    // você também pode usar `dataset` se você precisar suportar apenas IE 11+\n    el.dataset['foo'];\n    ```\n\n- [1.5](#1.5) <a name='1.5'></a> Sibling/Previous/Next Elements\n\n  + Sibling elements\n\n    ```js\n    // jQuery\n    $el.siblings();\n\n    // Nativo\n    [].filter.call(el.parentNode.children, function(child) {\n      return child !== el;\n    });\n    ```\n\n  + Previous elements\n\n    ```js\n    // jQuery\n    $el.prev();\n\n    // Nativo\n    el.previousElementSibling;\n\n    ```\n\n  + Next elements\n\n    ```js\n    // jQuery\n    $el.next();\n\n    // Nativo\n    el.nextElementSibling;\n    ```\n\n- [1.6](#1.6) <a name='1.6'></a> Closest\n\n  Retorna o primeiro elemento que corresponda ao seletor, partindo do elemento atual para o document.\n\n  ```js\n  // jQuery\n  $el.closest(queryString);\n\n  // Nativo\n  function closest(el, selector) {\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    while (el) {\n      if (matchesSelector.call(el, selector)) {\n        return el;\n      } else {\n        el = el.parentElement;\n      }\n    }\n    return null;\n  }\n  ```\n\n- [1.7](#1.7) <a name='1.7'></a> Parents Until\n\n  Obtém os ancestrais de cada elemento no atual conjunto de elementos combinados, mas não inclui o elemento correspondente pelo seletor, nó do DOM, ou objeto jQuery.\n\n  ```js\n  // jQuery\n  $el.parentsUntil(selector, filter);\n\n  // Nativo\n  function parentsUntil(el, selector, filter) {\n    const result = [];\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    // match start from parent\n    el = el.parentElement;\n    while (el && !matchesSelector.call(el, selector)) {\n      if (!filter) {\n        result.push(el);\n      } else {\n        if (matchesSelector.call(el, filter)) {\n          result.push(el);\n        }\n      }\n      el = el.parentElement;\n    }\n    return result;\n  }\n  ```\n\n- [1.8](#1.8) <a name='1.8'></a> Form\n\n  + Input/Textarea\n\n    ```js\n    // jQuery\n    $('#my-input').val();\n\n    // Nativo\n    document.querySelector('#my-input').value;\n    ```\n\n  + Obter o índice do e.currentTarget entre `.radio`\n\n    ```js\n    // jQuery\n    $(e.currentTarget).index('.radio');\n\n    // Nativo\n    [].indexOf.call(document.querySelectAll('.radio'), e.currentTarget);\n    ```\n\n- [1.9](#1.9) <a name='1.9'></a> Iframe Contents\n\n  `$('iframe').contents()` retorna `contentDocument` para este iframe específico\n\n  + Iframe contents\n\n    ```js\n    // jQuery\n    $iframe.contents();\n\n    // Nativo\n    iframe.contentDocument;\n    ```\n\n  + Iframe Query\n\n    ```js\n    // jQuery\n    $iframe.contents().find('.css');\n\n    // Nativo\n    iframe.contentDocument.querySelectorAll('.css');\n    ```\n\n**[⬆ ir para o topo](#tabela-de-conteúdos)**\n\n\n## CSS & Estilo\n\n- [2.1](#2.1) <a name='2.1'></a> CSS\n\n  + Obter estilo\n\n    ```js\n    // jQuery\n    $el.css(\"color\");\n\n    // Nativo\n    // AVISO: Bug conhecido, irá retornar 'auto' se o valor do estilo for 'auto'\n    const win = el.ownerDocument.defaultView;\n    // null significa não retornar estilos\n    win.getComputedStyle(el, null).color;\n    ```\n\n  + Definir Estilo\n\n    ```js\n    // jQuery\n    $el.css({ color: \"#ff0011\" });\n\n    // Nativo\n    el.style.color = '#ff0011';\n    ```\n\n  + Get/Set Styles\n\n    Observe que se você deseja setar vários estilos de uma vez, você pode optar por [setStyles](https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L194) método no pacote oui-dom-utils.\n\n\n  + Adicionar classe\n\n    ```js\n    // jQuery\n    $el.addClass(className);\n\n    // Nativo\n    el.classList.add(className);\n    ```\n\n  + Remover classe\n\n    ```js\n    // jQuery\n    $el.removeClass(className);\n\n    // Nativo\n    el.classList.remove(className);\n    ```\n\n  + Verificar classe\n\n    ```js\n    // jQuery\n    $el.hasClass(className);\n\n    // Nativo\n    el.classList.contains(className);\n    ```\n\n  + Toggle class\n\n    ```js\n    // jQuery\n    $el.toggleClass(className);\n\n    // Nativo\n    el.classList.toggle(className);\n    ```\n\n- [2.2](#2.2) <a name='2.2'></a> Largura e Altura\n\n  `width` e `height` são teoricamente idênticos, vamos pegar `height` como exemplo:\n\n  + Altura da janela\n\n    ```js\n    // window height\n    $(window).height();\n    // sem scrollbar, se comporta como jQuery\n    window.document.documentElement.clientHeight;\n    // com scrollbar\n    window.innerHeight;\n    ```\n\n  + Altura do Documento\n\n    ```js\n    // jQuery\n    $(document).height();\n\n    // Nativo\n    document.documentElement.scrollHeight;\n    ```\n\n  + Altura do Elemento\n\n    ```js\n    // jQuery\n    $el.height();\n\n    // Nativo\n    function getHeight(el) {\n      const styles = this.getComputedStyles(el);\n      const height = el.offsetHeight;\n      const borderTopWidth = parseFloat(styles.borderTopWidth);\n      const borderBottomWidth = parseFloat(styles.borderBottomWidth);\n      const paddingTop = parseFloat(styles.paddingTop);\n      const paddingBottom = parseFloat(styles.paddingBottom);\n      return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;\n    }\n    // preciso para inteiro（quando `border-box`, é `height - border`; quando `content-box`, é `height + padding`）\n    el.clientHeight;\n    // preciso para decimal（quando `border-box`, é `height`; quando `content-box`, é `height + padding + border`）\n    el.getBoundingClientRect().height;\n    ```\n\n- [2.3](#2.3) <a name='2.3'></a> Position & Offset\n\n  + Position\n\n    ```js\n    // jQuery\n    $el.position();\n\n    // Nativo\n    { left: el.offsetLeft, top: el.offsetTop }\n    ```\n\n  + Offset\n\n    ```js\n    // jQuery\n    $el.offset();\n\n    // Nativo\n    function getOffset (el) {\n      const box = el.getBoundingClientRect();\n\n      return {\n        top: box.top + window.pageYOffset - document.documentElement.clientTop,\n        left: box.left + window.pageXOffset - document.documentElement.clientLeft\n      }\n    }\n    ```\n\n- [2.4](#2.4) <a name='2.4'></a> Rolar para o topo\n\n  ```js\n  // jQuery\n  $(window).scrollTop();\n\n  // Nativo\n  (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;\n  ```\n\n**[⬆ ir para o topo](#tabela-de-conteúdos)**\n\n## Manipulação do Dom\n\n- [3.1](#3.1) <a name='3.1'></a> Remover\n  ```js\n  // jQuery\n  $el.remove();\n\n  // Nativo\n  el.parentNode.removeChild(el);\n  ```\n\n- [3.2](#3.2) <a name='3.2'></a> Texto\n\n  + Obter texto\n\n    ```js\n    // jQuery\n    $el.text();\n\n    // Nativo\n    el.textContent;\n    ```\n\n  + Definir texto\n\n    ```js\n    // jQuery\n    $el.text(string);\n\n    // Nativo\n    el.textContent = string;\n    ```\n\n- [3.3](#3.3) <a name='3.3'></a> HTML\n\n  + Obter HTML\n\n    ```js\n    // jQuery\n    $el.html();\n\n    // Nativo\n    el.innerHTML;\n    ```\n\n  + Definir HTML\n\n    ```js\n    // jQuery\n    $el.html(htmlString);\n\n    // Nativo\n    el.innerHTML = htmlString;\n    ```\n\n- [3.4](#3.4) <a name='3.4'></a> Append\n\n  Incluir elemento filho após o último filho do elemento pai.\n\n  ```js\n  // jQuery\n  $el.append(\"<div id='container'>hello</div>\");\n\n  // Nativo\n  let newEl = document.createElement('div');\n  newEl.setAttribute('id', 'container');\n  newEl.innerHTML = 'hello';\n  el.appendChild(newEl);\n  ```\n\n- [3.5](#3.5) <a name='3.5'></a> Prepend\n\n  ```js\n  // jQuery\n  $el.prepend(\"<div id='container'>hello</div>\");\n\n  // Nativo\n  let newEl = document.createElement('div');\n  newEl.setAttribute('id', 'container');\n  newEl.innerHTML = 'hello';\n  el.insertBefore(newEl, el.firstChild);\n  ```\n\n- [3.6](#3.6) <a name='3.6'></a> insertBefore\n\n  Insere um novo nó antes dos elementos selecionados.\n\n  ```js\n  // jQuery\n  $newEl.insertBefore(queryString);\n\n  // Nativo\n  const target = document.querySelector(queryString);\n  target.parentNode.insertBefore(newEl, target);\n  ```\n\n- [3.7](#3.7) <a name='3.7'></a> insertAfter\n\n  Insere um novo nó após os elementos selecionados.\n\n  ```js\n  // jQuery\n  $newEl.insertAfter(queryString);\n\n  // Nativo\n  const target = document.querySelector(queryString);\n  target.parentNode.insertBefore(newEl, target.nextSibling);\n  ```\n\n**[⬆ ir para o topo](#tabela-de-conteúdos)**\n\n## Ajax\n\nSubstitua por [fetch](https://github.com/camsong/fetch-ie8) e [fetch-jsonp](https://github.com/camsong/fetch-jsonp)\n\n**[⬆ ir para o topo](#tabela-de-conteúdos)**\n\n## Eventos\n\nPara uma substituição completa com namespace e delegation, consulte https://github.com/oneuijs/oui-dom-events\n\n- [5.1](#5.1) <a name='5.1'></a> `Bind` num evento com `on`\n\n  ```js\n  // jQuery\n  $el.on(eventName, eventHandler);\n\n  // Nativo\n  el.addEventListener(eventName, eventHandler);\n  ```\n\n- [5.2](#5.2) <a name='5.2'></a> `Unbind` num evento com `off`\n\n  ```js\n  // jQuery\n  $el.off(eventName, eventHandler);\n\n  // Nativo\n  el.removeEventListener(eventName, eventHandler);\n  ```\n\n- [5.3](#5.3) <a name='5.3'></a> Trigger\n\n  ```js\n  // jQuery\n  $(el).trigger('custom-event', {key1: 'data'});\n\n  // Nativo\n  if (window.CustomEvent) {\n    const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});\n  } else {\n    const event = document.createEvent('CustomEvent');\n    event.initCustomEvent('custom-event', true, true, {key1: 'data'});\n  }\n\n  el.dispatchEvent(event);\n  ```\n\n**[⬆ ir para o topo](#tabela-de-conteúdos)**\n\n## Utilitários\n\n- [6.1](#6.1) <a name='6.1'></a> isArray\n\n  ```js\n  // jQuery\n  $.isArray(range);\n\n  // Nativo\n  Array.isArray(range);\n  ```\n\n- [6.2](#6.2) <a name='6.2'></a> Trim\n\n  ```js\n  // jQuery\n  $.trim(string);\n\n  // Nativo\n  string.trim();\n  ```\n\n- [6.3](#6.3) <a name='6.3'></a> Object Assign\n\n  Use o polyfill `object.assign` para eetender um Object: https://github.com/ljharb/object.assign\n\n  ```js\n  // jQuery\n  $.extend({}, defaultOpts, opts);\n\n  // Nativo\n  Object.assign({}, defaultOpts, opts);\n  ```\n\n- [6.4](#6.4) <a name='6.4'></a> Contains\n\n  ```js\n  // jQuery\n  $.contains(el, child);\n\n  // Nativo\n  el !== child && el.contains(child);\n  ```\n\n**[⬆ ir para o topo](#tabela-de-conteúdos)**\n\n## Suporte dos Navegadores\n\n![Chrome](https://raw.github.com/alrra/browser-logos/master/chrome/chrome_48x48.png) | ![Firefox](https://raw.github.com/alrra/browser-logos/master/firefox/firefox_48x48.png) | ![IE](https://raw.github.com/alrra/browser-logos/master/internet-explorer/internet-explorer_48x48.png) | ![Opera](https://raw.github.com/alrra/browser-logos/master/opera/opera_48x48.png) | ![Safari](https://raw.github.com/alrra/browser-logos/master/safari/safari_48x48.png)\n--- | --- | --- | --- | --- |\nLatest ✔ | Latest ✔ | 10+ ✔ | Latest ✔ | 6.1+ ✔ |\n\n# Licença\n\nMIT\n"
  },
  {
    "path": "README.zh-CN.md",
    "content": "## 你也许不需要 jQuery （You (Might) Don't Need jQuery）\n\n前端发展很快，现代浏览器原生 API 已经足够好用。我们并不需要为了操作 DOM、Event 等再学习一下 jQuery 的 API。同时由于 React、Angular、Vue 等框架的流行，直接操作 DOM 不再是好的模式，jQuery 使用场景大大减少。本项目总结了大部分 jQuery API 替代的方法，暂时只支持 IE10 以上浏览器。\n\n## 目录\n\n1. [翻译](#翻译)\n2. [Query 选择器](#query-选择器)\n3. [CSS & Style](#css--style)\n4. [DOM 操作](#dom-操作)\n5. [Ajax](#ajax)\n6. [事件](#事件)\n7. [实用工具](#实用工具)\n8. [Promises](#promises)\n9. [动画](#动画)\n10. [替代品](#替代品)\n11. [浏览器支持](#浏览器支持)\n\n## 翻译\n\n* [한국어](./README.ko-KR.md)\n* [正體中文](./README.zh-TW.md)\n* [简体中文](./README.zh-CN.md)\n* [Bahasa Melayu](./README-my.md)\n* [Bahasa Indonesia](./README-id.md)\n* [Português(PT-BR)](./README.pt-BR.md)\n* [Tiếng Việt Nam](./README-vi.md)\n* [Español](./README-es.md)\n* [Русский](./README-ru.md)\n* [Кыргызча](./README-kg.md)\n* [Türkçe](./README-tr.md)\n* [Italiano](./README-it.md)\n* [Français](./README-fr.md)\n* [日本語](./README-ja.md)\n* [Polski](./README-pl.md)\n\n## Query 选择器\n\n常用的 class、id、属性 选择器都可以使用 `document.querySelector` 或 `document.querySelectorAll` 替代。区别是\n* `document.querySelector` 返回第一个匹配的 Element\n* `document.querySelectorAll` 返回所有匹配的 Element 组成的 NodeList。它可以通过 `[].slice.call()` 把它转成 Array\n* 如果匹配不到任何 Element，jQuery 返回空数组 `[]`，但 `document.querySelector` 返回 `null`，注意空指针异常。当找不到时，也可以使用 `||` 设置默认的值，如 `document.querySelectorAll(selector) || []`\n\n> 注意：`document.querySelector` 和 `document.querySelectorAll` 性能很**差**。如果想提高性能，尽量使用 `document.getElementById`、`document.getElementsByClassName` 或 `document.getElementsByTagName`。\n\n- [1.0](#1.0) <a name='1.0'></a> 选择器查询\n\n  ```js\n  // jQuery\n  $('selector');\n\n  // Native\n  document.querySelectorAll('selector');\n  ```\n\n- [1.1](#1.1) <a name='1.1'></a> class 查询\n\n  ```js\n  // jQuery\n  $('.class');\n\n  // Native\n  document.querySelectorAll('.class');\n\n  // or\n  document.getElementsByClassName('class');\n  ```\n\n- [1.2](#1.2) <a name='1.2'></a> id 查询\n\n  ```js\n  // jQuery\n  $('#id');\n\n  // Native\n  document.querySelector('#id');\n\n  // or\n  document.getElementById('id');\n  \n  // or\n  window['id']\n  ```\n\n- [1.3](#1.3) <a name='1.3'></a> 属性查询\n\n  ```js\n  // jQuery\n  $('a[target=_blank]');\n\n  // Native\n  document.querySelectorAll('a[target=_blank]');\n  ```\n\n- [1.4](#1.4) <a name='1.4'></a> 后代查询\n\n  ```js\n  // jQuery\n  $el.find('li');\n\n  // Native\n  el.querySelectorAll('li');\n  ```\n\n- [1.5](#1.5) <a name='1.5'></a> 兄弟及上下元素\n\n  + 兄弟元素\n\n    ```js\n    // jQuery\n    $el.siblings();\n\n    // Native - latest, Edge13+\n    [...el.parentNode.children].filter((child) =>\n      child !== el\n    );\n    // Native (alternative) - latest, Edge13+\n    Array.from(el.parentNode.children).filter((child) =>\n      child !== el\n    );\n    // Native - IE10+\n    Array.prototype.filter.call(el.parentNode.children, (child) =>\n      child !== el\n    );\n    ```\n\n  + 上一个元素\n\n    ```js\n    // jQuery\n    $el.prev();\n\n    // Native\n    el.previousElementSibling;\n\n    ```\n\n  + 下一个元素\n\n    ```js\n    // next\n    $el.next();\n\n    // Native\n    el.nextElementSibling;\n    ```\n\n- [1.6](#1.6) <a name='1.6'></a> Closest\n\n  Closest 获得匹配选择器的第一个祖先元素，从当前元素开始沿 DOM 树向上。\n\n  ```js\n  // jQuery\n  $el.closest(queryString);\n\n  // Native - Only latest, NO IE\n  el.closest(selector);\n\n  // Native - IE10+\n  function closest(el, selector) {\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    while (el) {\n      if (matchesSelector.call(el, selector)) {\n        return el;\n      } else {\n        el = el.parentElement;\n      }\n    }\n    return null;\n  }\n  ```\n\n- [1.7](#1.7) <a name='1.7'></a> Parents Until\n\n  获取当前每一个匹配元素集的祖先，不包括匹配元素的本身。\n\n  ```js\n  // jQuery\n  $el.parentsUntil(selector, filter);\n\n  // Native\n  function parentsUntil(el, selector, filter) {\n    const result = [];\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    // match start from parent\n    el = el.parentElement;\n    while (el && !matchesSelector.call(el, selector)) {\n      if (!filter) {\n        result.push(el);\n      } else {\n        if (matchesSelector.call(el, filter)) {\n          result.push(el);\n        }\n      }\n      el = el.parentElement;\n    }\n    return result;\n  }\n  ```\n\n- [1.8](#1.8) <a name='1.8'></a> Form\n\n  + Input/Textarea\n\n    ```js\n    // jQuery\n    $('#my-input').val();\n\n    // Native\n    document.querySelector('#my-input').value;\n    ```\n\n  + 获取 e.currentTarget 在 `.radio` 中的数组索引\n\n    ```js\n    // jQuery\n    $('.radio').index(e.currentTarget);\n\n    // Native\n    Array.prototype.indexOf.call(document.querySelectorAll('.radio'), e.currentTarget);\n    ```\n\n- [1.9](#1.9) <a name='1.9'></a> Iframe Contents\n\n  jQuery 对象的 iframe `contents()` 返回的是 iframe 内的 `document`\n\n  + Iframe contents\n\n    ```js\n    // jQuery\n    $iframe.contents();\n\n    // Native\n    iframe.contentDocument;\n    ```\n\n  + Iframe Query\n\n    ```js\n    // jQuery\n    $iframe.contents().find('.css');\n\n    // Native\n    iframe.contentDocument.querySelectorAll('.css');\n    ```\n\n- [1.10](#1.10) <a name='1.10'></a> 获取 body\n\n  ```js\n  // jQuery\n  $('body');\n\n  // Native\n  document.body;\n  ```\n\n- [1.11](#1.11) <a name='1.11'></a> 获取或设置属性\n\n  + 获取属性\n\n    ```js\n    // jQuery\n    $el.attr('foo');\n\n    // Native\n    el.getAttribute('foo');\n    ```\n  + 设置属性\n\n    ```js\n    // jQuery, note that this works in memory without change the DOM\n    $el.attr('foo', 'bar');\n\n    // Native\n    el.setAttribute('foo', 'bar');\n    ```\n\n  + 获取 `data-` 属性\n\n    ```js\n    // jQuery\n    $el.data('foo');\n\n    // Native (use `getAttribute`)\n    el.getAttribute('data-foo');\n\n    // Native (use `dataset` if only need to support IE 11+)\n    el.dataset['foo'];\n    ```\n\n**[⬆ 回到顶部](#目录)**\n\n## CSS & Style\n\n- [2.1](#2.1) <a name='2.1'></a> CSS\n\n  + Get style\n\n    ```js\n    // jQuery\n    $el.css(\"color\");\n\n    // Native\n    // 注意：此处为了解决当 style 值为 auto 时，返回 auto 的问题\n    const win = el.ownerDocument.defaultView;\n\n    // null 的意思是不返回伪类元素\n    win.getComputedStyle(el, null).color;\n    ```\n\n  + Set style\n\n    ```js\n    // jQuery\n    $el.css({ color: \"#ff0011\" });\n\n    // Native\n    el.style.color = '#ff0011';\n    ```\n\n  + Get/Set Styles\n\n    注意，如果想一次设置多个 style，可以参考 oui-dom-utils 中 [setStyles](https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L194) 方法\n\n  + Add class\n\n    ```js\n    // jQuery\n    $el.addClass(className);\n\n    // Native\n    el.classList.add(className);\n    ```\n\n  + Remove class\n\n    ```js\n    // jQuery\n    $el.removeClass(className);\n\n    // Native\n    el.classList.remove(className);\n    ```\n\n  + has class\n\n    ```js\n    // jQuery\n    $el.hasClass(className);\n\n    // Native\n    el.classList.contains(className);\n    ```\n\n  + Toggle class\n\n    ```js\n    // jQuery\n    $el.toggleClass(className);\n\n    // Native\n    el.classList.toggle(className);\n    ```\n\n- [2.2](#2.2) <a name='2.2'></a> Width & Height\n\n  Width 与 Height 获取方法相同，下面以 Height 为例：\n\n  + Window height\n\n    ```js\n    // window height\n    $(window).height();\n\n    // 不含 scrollbar，与 jQuery 行为一致\n    window.document.documentElement.clientHeight;\n\n    // 含 scrollbar\n    window.innerHeight;\n    ```\n\n  + Document height\n\n    ```js\n    // jQuery\n    $(document).height();\n\n    // Native\n    const body = document.body;\n    const html = document.documentElement;\n    const height = Math.max(\n      body.offsetHeight,\n      body.scrollHeight,\n      html.clientHeight,\n      html.offsetHeight,\n      html.scrollHeight\n    );\n    ```\n\n  + Element height\n\n    ```js\n    // jQuery\n    $el.height();\n\n    // Native\n    function getHeight(el) {\n      const styles = this.getComputedStyle(el);\n      const height = el.offsetHeight;\n      const borderTopWidth = parseFloat(styles.borderTopWidth);\n      const borderBottomWidth = parseFloat(styles.borderBottomWidth);\n      const paddingTop = parseFloat(styles.paddingTop);\n      const paddingBottom = parseFloat(styles.paddingBottom);\n      return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;\n    }\n\n    // 精确到整数（border-box 时为 height - border 值，content-box 时为 height + padding 值）\n    el.clientHeight;\n\n    // 精确到小数（border-box 时为 height 值，content-box 时为 height + padding + border 值）\n    el.getBoundingClientRect().height;\n    ```\n\n- [2.3](#2.3) <a name='2.3'></a> Position & Offset\n\n  + Position\n\n    获得匹配元素相对父元素的偏移\n\n    ```js\n    // jQuery\n    $el.position();\n\n    // Native\n    { left: el.offsetLeft, top: el.offsetTop }\n    ```\n\n  + Offset\n\n    获得匹配元素相对文档的偏移\n\n    ```js\n    // jQuery\n    $el.offset();\n\n    // Native\n    function getOffset (el) {\n      const box = el.getBoundingClientRect();\n\n      return {\n        top: box.top + window.pageYOffset - document.documentElement.clientTop,\n        left: box.left + window.pageXOffset - document.documentElement.clientLeft\n      }\n    }\n    ```\n\n- [2.4](#2.4) <a name='2.4'></a> Scroll Top\n\n\n  获取元素滚动条垂直位置。\n\n  ```js\n  // jQuery\n  $(window).scrollTop();\n\n  // Native\n  (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;\n  ```\n\n**[⬆ 回到顶部](#目录)**\n\n## DOM 操作\n\n- [3.1](#3.1) <a name='3.1'></a> Remove\n\n  从 DOM 中移除元素。\n\n  ```js\n  // jQuery\n  $el.remove();\n\n  // Native\n  el.parentNode.removeChild(el);\n\n  // Native - Only latest, NO IE\n  el.remove();\n  ```\n\n- [3.2](#3.2) <a name='3.2'></a> Text\n\n  + Get text\n\n    返回指定元素及其后代的文本内容。\n\n    ```js\n    // jQuery\n    $el.text();\n\n    // Native\n    el.textContent;\n    ```\n\n  + Set text\n\n    设置元素的文本内容。\n\n    ```js\n    // jQuery\n    $el.text(string);\n\n    // Native\n    el.textContent = string;\n    ```\n\n- [3.3](#3.3) <a name='3.3'></a> HTML\n\n  + Get HTML\n\n    ```js\n    // jQuery\n    $el.html();\n\n    // Native\n    el.innerHTML;\n    ```\n\n  + Set HTML\n\n    ```js\n    // jQuery\n    $el.html(htmlString);\n\n    // Native\n    el.innerHTML = htmlString;\n    ```\n\n- [3.4](#3.4) <a name='3.4'></a> Append\n\n  Append 插入到子节点的末尾\n\n  ```js\n  // jQuery\n  $el.append(\"<div id='container'>hello</div>\");\n\n  // Native (HTML string)\n  el.insertAdjacentHTML('beforeend', '<div id=\"container\">Hello World</div>');\n\n  // Native (Element)\n  el.appendChild(newEl);\n  ```\n\n- [3.5](#3.5) <a name='3.5'></a> Prepend\n\n  ```js\n  // jQuery\n  $el.prepend(\"<div id='container'>hello</div>\");\n\n  // Native (HTML string)\n  el.insertAdjacentHTML('afterbegin', '<div id=\"container\">Hello World</div>');\n\n  // Native (Element)\n  el.insertBefore(newEl, el.firstChild);\n  ```\n\n- [3.6](#3.6) <a name='3.6'></a> insertBefore\n\n  在选中元素前插入新节点\n\n  ```js\n  // jQuery\n  $newEl.insertBefore(queryString);\n\n  // Native (HTML string)\n  el.insertAdjacentHTML('beforebegin ', '<div id=\"container\">Hello World</div>');\n\n  // Native (Element)\n  const el = document.querySelector(selector);\n  if (el.parentNode) {\n    el.parentNode.insertBefore(newEl, el);\n  }\n  ```\n\n- [3.7](#3.7) <a name='3.7'></a> insertAfter\n\n  在选中元素后插入新节点\n\n  ```js\n  // jQuery\n  $newEl.insertAfter(queryString);\n\n  // Native (HTML string)\n  el.insertAdjacentHTML('afterend', '<div id=\"container\">Hello World</div>');\n\n  // Native (Element)\n  const el = document.querySelector(selector);\n  if (el.parentNode) {\n    el.parentNode.insertBefore(newEl, el.nextSibling);\n  }\n  ```\n\n- [3.8](#3.8) <a name='3.8'></a> is\n\n  如果匹配给定的选择器，返回true\n\n    ```js\n    // jQuery\n    $el.is(selector);\n\n    // Native\n    el.matches(selector);\n    ```\n\n- [3.9](#3.9) <a name='3.9'></a> clone\n\n  深拷贝被选元素。（生成被选元素的副本，包含子节点、文本和属性。）\n\n  ```js\n  //jQuery\n  $el.clone();\n\n  //Native\n  //深拷贝添加参数'true'\n  el.cloneNode();\n  ```\n\n- [3.10](#3.10) <a name='3.10'></a> empty\n\n  移除所有子节点\n\n  ```js\n  //jQuery\n  $el.empty();\n\n  //Native\n  el.innerHTML = '';\n  ```\n\n- [3.11](#3.11) <a name='3.11'></a> wrap\n\n  把每个被选元素放置在指定的HTML结构中。\n\n  ```js\n  //jQuery\n  $(\".inner\").wrap('<div class=\"wrapper\"></div>');\n\n  //Native\n  Array.from(document.querySelectorAll('.inner')).forEach((el) => {\n    const wrapper = document.createElement('div');\n    wrapper.className = 'wrapper';\n    el.parentNode.insertBefore(wrapper, el);\n    el.parentNode.removeChild(el);\n    wrapper.appendChild(el);\n  });\n  ```\n\n- [3.12](#3.12) <a name=\"3.12\"></a> unwrap\n\n  移除被选元素的父元素的DOM结构\n\n  ```js\n  // jQuery\n  $('.inner').unwrap();\n\n  // Native\n  Array.prototype.forEach.call(document.querySelectorAll('.inner'), (el) => {\n        let elParentNode = el.parentNode\n\n        if(elParentNode !== document.body) {\n            elParentNode.parentNode.insertBefore(el, elParentNode)\n            elParentNode.parentNode.removeChild(elParentNode)\n        }\n  });\n  ```\n\n- [3.13](#3.13) <a name=\"3.13\"></a> replaceWith\n\n  用指定的元素替换被选的元素\n\n  ```js\n  //jQuery\n  $('.inner').replaceWith('<div class=\"outer\"></div>');\n\n  //Native\n  Array.prototype.forEach.call(document.querySelectorAll('.inner'),(el) => {\n    const outer = document.createElement(\"div\");\n    outer.className = \"outer\";\n    el.parentNode.insertBefore(outer, el);\n    el.parentNode.removeChild(el);\n  });\n  ```\n\n- [3.14](#3.14) <a name='3.14'></a> simple parse\n\n  解析 HTML/SVG/XML 字符串\n\n  ```js\n  // jQuery\n  $(`<ol>\n    <li>a</li>\n    <li>b</li>\n  </ol>\n  <ol>\n    <li>c</li>\n    <li>d</li>\n  </ol>`);\n\n  // Native\n  range = document.createRange();\n  parse = range.createContextualFragment.bind(range);\n\n  parse(`<ol>\n    <li>a</li>\n    <li>b</li>\n  </ol>\n  <ol>\n    <li>c</li>\n    <li>d</li>\n  </ol>`);\n  ```\n\n**[⬆ 回到顶部](#目录)**\n\n## Ajax\n\n[Fetch API](https://fetch.spec.whatwg.org/) 是用于替换 XMLHttpRequest 处理 ajax 的新标准，Chrome 和 Firefox 均支持，旧浏览器可以使用 polyfills 提供支持。\n\nIE9+ 请使用 [github/fetch](http://github.com/github/fetch)，IE8+ 请使用 [fetch-ie8](https://github.com/camsong/fetch-ie8/)，JSONP 请使用 [fetch-jsonp](https://github.com/camsong/fetch-jsonp)。\n\n- [4.1](#4.1) <a name='4.1'></a> 从服务器读取数据并替换匹配元素的内容。\n\n  ```js\n  // jQuery\n  $(selector).load(url, completeCallback)\n\n  // Native\n  fetch(url).then(data => data.text()).then(data => {\n    document.querySelector(selector).innerHTML = data\n  }).then(completeCallback)\n  ```\n\n**[⬆ 回到顶部](#目录)**\n\n## 事件\n\n完整地替代命名空间和事件代理，链接到 https://github.com/oneuijs/oui-dom-events\n\n- [5.0](#5.0) <a name='5.0'></a> Document ready by `DOMContentLoaded`\n\n  ```js\n  // jQuery\n  $(document).ready(eventHandler);\n\n  // Native\n  // 检测 DOMContentLoaded 是否已完成\n  if (document.readyState !== 'loading') {\n    eventHandler();\n  } else {\n    document.addEventListener('DOMContentLoaded', eventHandler);\n  }\n  ```\n\n- [5.1](#5.1) <a name='5.1'></a> 使用 on 绑定事件\n\n  ```js\n  // jQuery\n  $el.on(eventName, eventHandler);\n\n  // Native\n  el.addEventListener(eventName, eventHandler);\n  ```\n\n- [5.2](#5.2) <a name='5.2'></a> 使用 off 解绑事件\n\n  ```js\n  // jQuery\n  $el.off(eventName, eventHandler);\n\n  // Native\n  el.removeEventListener(eventName, eventHandler);\n  ```\n\n- [5.3](#5.3) <a name='5.3'></a> Trigger\n\n  ```js\n  // jQuery\n  $(el).trigger('custom-event', {key1: 'data'});\n\n  // Native\n  if (window.CustomEvent) {\n    const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});\n  } else {\n    const event = document.createEvent('CustomEvent');\n    event.initCustomEvent('custom-event', true, true, {key1: 'data'});\n  }\n\n  el.dispatchEvent(event);\n  ```\n\n**[⬆ 回到顶部](#目录)**\n\n## 实用工具\n\n大部分实用工具都能在 native API 中找到. 其他高级功能可以选用专注于该领域的稳定性和性能都更好的库来代替，推荐 [lodash](https://lodash.com)。\n\n- [6.1](#6.1) <a name='6.1'></a> 基本工具\n\n  + isArray\n\n  检测参数是不是数组。\n\n  ```js\n  // jQuery\n  $.isArray(range);\n\n  // Native\n  Array.isArray(range);\n  ```\n\n  + isWindow\n\n  检测参数是不是 window。\n\n  ```js\n  // jQuery\n  $.isWindow(obj);\n\n  // Native\n  function isWindow(obj) {\n    return obj !== null && obj !== undefined && obj === obj.window;\n  }\n  ```\n\n  + inArray\n\n  在数组中搜索指定值并返回索引 (找不到则返回 -1)。\n\n  ```js\n  // jQuery\n  $.inArray(item, array);\n\n  // Native\n  array.indexOf(item) > -1;\n\n  // ES6-way\n  array.includes(item);\n  ```\n\n  + isNumeric\n\n  检测传入的参数是不是数字。\n  Use `typeof` to decide the type or the `type` example for better accuracy.\n\n  ```js\n  // jQuery\n  $.isNumeric(item);\n\n  // Native\n  function isNumeric(value) {\n    return !isNaN(parseFloat(value)) && isFinite(value);\n  }\n  ```\n\n  + isFunction\n\n  检测传入的参数是不是 JavaScript 函数对象。\n\n  ```js\n  // jQuery\n  $.isFunction(item);\n\n  // Native\n  function isFunction(item) {\n    if (typeof item === 'function') {\n      return true;\n    }\n    var type = Object.prototype.toString(item);\n    return type === '[object Function]' || type === '[object GeneratorFunction]';\n  }\n  ```\n\n  + isEmptyObject\n\n  检测对象是否为空 (包括不可枚举属性)。\n\n  ```js\n  // jQuery\n  $.isEmptyObject(obj);\n\n  // Native\n  function isEmptyObject(obj) {\n    return Object.keys(obj).length === 0;\n  }\n  ```\n\n  + isPlainObject\n\n  检测是不是扁平对象 (使用 “{}” 或 “new Object” 创建)。\n\n  ```js\n  // jQuery\n  $.isPlainObject(obj);\n\n  // Native\n  function isPlainObject(obj) {\n    if (typeof (obj) !== 'object' || obj.nodeType || obj !== null && obj !== undefined && obj === obj.window) {\n      return false;\n    }\n\n    if (obj.constructor &&\n        !Object.prototype.hasOwnProperty.call(obj.constructor.prototype, 'isPrototypeOf')) {\n      return false;\n    }\n\n    return true;\n  }\n  ```\n\n  + extend\n\n  合并多个对象的内容到第一个对象。\n  object.assign 是 ES6 API，也可以使用 [polyfill](https://github.com/ljharb/object.assign)。\n\n  ```js\n  // jQuery\n  $.extend({}, defaultOpts, opts);\n\n  // Native\n  Object.assign({}, defaultOpts, opts);\n  ```\n\n  + trim\n\n  移除字符串头尾空白。\n\n  ```js\n  // jQuery\n  $.trim(string);\n\n  // Native\n  string.trim();\n  ```\n\n  + map\n\n  将数组或对象转化为包含新内容的数组。\n\n  ```js\n  // jQuery\n  $.map(array, (value, index) => {\n  });\n\n  // Native\n  array.map((value, index) => {\n  });\n  ```\n\n  + each\n\n  轮询函数，可用于平滑的轮询对象和数组。\n\n  ```js\n  // jQuery\n  $.each(array, (index, value) => {\n  });\n\n  // Native\n  array.forEach((value, index) => {\n  });\n  ```\n\n  + grep\n\n  找到数组中符合过滤函数的元素。\n\n  ```js\n  // jQuery\n  $.grep(array, (value, index) => {\n  });\n\n  // Native\n  array.filter((value, index) => {\n  });\n  ```\n\n  + type\n\n  检测对象的 JavaScript [Class] 内部类型。\n\n  ```js\n  // jQuery\n  $.type(obj);\n\n  // Native\n  function type(item) {\n    const reTypeOf = /(?:^\\[object\\s(.*?)\\]$)/;\n    return Object.prototype.toString.call(item)\n      .replace(reTypeOf, '$1')\n      .toLowerCase();\n  }\n  ```\n\n  + merge\n\n  合并第二个数组内容到第一个数组。\n\n  ```js\n  // jQuery\n  $.merge(array1, array2);\n\n  // Native\n  // 使用 concat，不能去除重复值\n  function merge(...args) {\n    return [].concat(...args)\n  }\n\n  // ES6，同样不能去除重复值\n  array1 = [...array1, ...array2]\n\n  // 使用 Set，可以去除重复值\n  function merge(...args) {\n    return Array.from(new Set([].concat(...args)))\n  }\n  ```\n\n  + now\n\n  返回当前时间的数字呈现。\n\n  ```js\n  // jQuery\n  $.now();\n\n  // Native\n  Date.now();\n  ```\n\n  + proxy\n\n  传入函数并返回一个新函数，该函数绑定指定上下文。\n\n  ```js\n  // jQuery\n  $.proxy(fn, context);\n\n  // Native\n  fn.bind(context);\n  ```\n\n  + makeArray\n\n  类数组对象转化为真正的 JavaScript 数组。\n\n  ```js\n  // jQuery\n  $.makeArray(arrayLike);\n\n  // Native\n  Array.prototype.slice.call(arrayLike);\n\n  // ES6-way\n  Array.from(arrayLike);\n  ```\n\n- [6.2](#6.2) <a name='6.2'></a> 包含\n\n  检测 DOM 元素是不是其他 DOM 元素的后代。\n\n  ```js\n  // jQuery\n  $.contains(el, child);\n\n  // Native\n  el !== child && el.contains(child);\n  ```\n\n- [6.3](#6.3) <a name='6.3'></a> Globaleval\n\n  全局执行 JavaScript 代码。\n\n  ```js\n  // jQuery\n  $.globaleval(code);\n\n  // Native\n  function Globaleval(code) {\n    const script = document.createElement('script');\n    script.text = code;\n\n    document.head.appendChild(script).parentNode.removeChild(script);\n  }\n\n  // Use eval, but context of eval is current, context of $.Globaleval is global.\n  eval(code);\n  ```\n\n- [6.4](#6.4) <a name='6.4'></a> 解析\n\n  + parseHTML\n\n  解析字符串为 DOM 节点数组。\n\n  ```js\n  // jQuery\n  $.parseHTML(htmlString);\n\n  // Native\n  function parseHTML(string) {\n    const context = document.implementation.createHTMLDocument();\n\n    // Set the base href for the created document so any parsed elements with URLs\n    // are based on the document's URL\n    const base = context.createElement('base');\n    base.href = document.location.href;\n    context.head.appendChild(base);\n\n    context.body.innerHTML = string;\n    return context.body.children;\n  }\n  ```\n\n  + parseJSON\n\n  传入格式正确的 JSON 字符串并返回 JavaScript 值。\n\n  ```js\n  // jQuery\n  $.parseJSON(str);\n\n  // Native\n  JSON.parse(str);\n  ```\n\n**[⬆ 回到顶部](#目录)**\n\n## Promises\n\nPromise 代表异步操作的最终结果。jQuery 用它自己的方式处理 promises，原生 JavaScript 遵循 [Promises/A+](http://promises-aplus.github.io/promises-spec/) 标准实现了最小 API 来处理 promises。\n\n- [7.1](#7.1) <a name='7.1'></a> done, fail, always\n\n  `done` 会在 promise 解决时调用，`fail` 会在 promise 拒绝时调用，`always` 总会调用。\n\n  ```js\n  // jQuery\n  $promise.done(doneCallback).fail(failCallback).always(alwaysCallback)\n\n  // Native\n  promise.then(doneCallback, failCallback).then(alwaysCallback, alwaysCallback)\n  ```\n\n- [7.2](#7.2) <a name='7.2'></a> when\n\n  `when` 用于处理多个 promises。当全部 promises 被解决时返回，当任一 promise 被拒绝时拒绝。\n\n  ```js\n  // jQuery\n  $.when($promise1, $promise2).done((promise1Result, promise2Result) => {\n  });\n\n  // Native\n  Promise.all([$promise1, $promise2]).then([promise1Result, promise2Result] => {});\n  ```\n\n- [7.3](#7.3) <a name='7.3'></a> Deferred\n\n  Deferred 是创建 promises 的一种方式。\n\n  ```js\n  // jQuery\n  function asyncFunc() {\n    const defer = new $.Deferred();\n    setTimeout(() => {\n      if(true) {\n        defer.resolve('some_value_computed_asynchronously');\n      } else {\n        defer.reject('failed');\n      }\n    }, 1000);\n\n    return defer.promise();\n  }\n\n  // Native\n  function asyncFunc() {\n    return new Promise((resolve, reject) => {\n      setTimeout(() => {\n        if (true) {\n          resolve('some_value_computed_asynchronously');\n        } else {\n          reject('failed');\n        }\n      }, 1000);\n    });\n  }\n\n  // Deferred way\n  function defer() {\n    const deferred = {};\n    const promise = new Promise((resolve, reject) => {\n      deferred.resolve = resolve;\n      deferred.reject = reject;\n    });\n\n    deferred.promise = () => {\n      return promise;\n    };\n\n    return deferred;\n  }\n\n  function asyncFunc() {\n    const defer = defer();\n    setTimeout(() => {\n      if(true) {\n        defer.resolve('some_value_computed_asynchronously');\n      } else {\n        defer.reject('failed');\n      }\n    }, 1000);\n\n    return defer.promise();\n  }\n  ```\n\n**[⬆ 回到顶部](#目录)**\n\n## 动画\n\n- [8.1](#8.1) <a name='8.1'></a> Show & Hide\n\n  ```js\n  // jQuery\n  $el.show();\n  $el.hide();\n\n  // Native\n  // 更多 show 方法的细节详见 https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L363\n  el.style.display = ''|'inline'|'inline-block'|'inline-table'|'block';\n  el.style.display = 'none';\n  ```\n\n- [8.2](#8.2) <a name='8.2'></a> Toggle\n\n  显示或隐藏元素。\n\n  ```js\n  // jQuery\n  $el.toggle();\n\n  // Native\n  if (el.ownerDocument.defaultView.getComputedStyle(el, null).display === 'none') {\n    el.style.display = ''|'inline'|'inline-block'|'inline-table'|'block';\n  } else {\n    el.style.display = 'none';\n  }\n  ```\n\n- [8.3](#8.3) <a name='8.3'></a> FadeIn & FadeOut\n\n  ```js\n  // jQuery\n  $el.fadeIn(3000);\n  $el.fadeOut(3000);\n\n  // Native\n  el.style.transition = 'opacity 3s';\n  // fadeIn\n  el.style.opacity = '1';\n  // fadeOut\n  el.style.opacity = '0';\n  ```\n\n- [8.4](#8.4) <a name='8.4'></a> FadeTo\n\n  调整元素透明度。\n\n  ```js\n  // jQuery\n  $el.fadeTo('slow',0.15);\n  // Native\n  el.style.transition = 'opacity 3s'; // 假设 'slow' 等于 3 秒\n  el.style.opacity = '0.15';\n  ```\n\n- [8.5](#8.5) <a name='8.5'></a> FadeToggle\n\n  动画调整透明度用来显示或隐藏。\n\n  ```js\n  // jQuery\n  $el.fadeToggle();\n\n  // Native\n  el.style.transition = 'opacity 3s';\n  const { opacity } = el.ownerDocument.defaultView.getComputedStyle(el, null);\n  if (opacity === '1') {\n    el.style.opacity = '0';\n  } else {\n    el.style.opacity = '1';\n  }\n  ```\n\n- [8.6](#8.6) <a name='8.6'></a> SlideUp & SlideDown\n\n  ```js\n  // jQuery\n  $el.slideUp();\n  $el.slideDown();\n\n  // Native\n  const originHeight = '100px';\n  el.style.transition = 'height 3s';\n  // slideUp\n  el.style.height = '0px';\n  // slideDown\n  el.style.height = originHeight;\n  ```\n\n- [8.7](#8.7) <a name='8.7'></a> SlideToggle\n\n  滑动切换显示或隐藏。\n\n  ```js\n  // jQuery\n  $el.slideToggle();\n\n  // Native\n  const originHeight = '100px';\n  el.style.transition = 'height 3s';\n  const { height } = el.ownerDocument.defaultView.getComputedStyle(el, null);\n  if (parseInt(height, 10) === 0) {\n    el.style.height = originHeight;\n  }\n  else {\n   el.style.height = '0px';\n  }\n  ```\n\n- [8.8](#8.8) <a name='8.8'></a> Animate\n\n  执行一系列 CSS 属性动画。\n\n  ```js\n  // jQuery\n  $el.animate({ params }, speed);\n\n  // Native\n  el.style.transition = 'all ' + speed;\n  Object.keys(params).forEach((key) => {\n    el.style[key] = params[key];\n  });\n  ```\n\n**[⬆ 回到顶部](#目录)**\n\n## 替代品\n\n* [你可能不需要 jQuery (You Might Not Need jQuery)](http://youmightnotneedjquery.com/) - 如何使用原生 JavaScript 实现通用事件，元素，ajax 等用法。\n* [npm-dom](http://github.com/npm-dom) 以及 [webmodules](http://github.com/webmodules) - 在 NPM 上提供独立 DOM 模块的组织\n\n## 浏览器支持\n\n![Chrome][chrome-image] | ![Firefox][firefox-image] | ![IE][ie-image] | ![Opera][opera-image] | ![Safari][safari-image]\n--- | --- | --- | --- | --- |\nLatest ✔ | Latest ✔ | 10+ ✔ | Latest ✔ | 6.1+ ✔ |\n\n# License\n\nMIT\n\n[chrome-image]: https://raw.github.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png\n[firefox-image]: https://raw.github.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png\n[ie-image]: https://raw.github.com/alrra/browser-logos/master/src/archive/internet-explorer_9-11/internet-explorer_9-11_48x48.png\n[opera-image]: https://raw.github.com/alrra/browser-logos/master/src/opera/opera_48x48.png\n[safari-image]: https://raw.github.com/alrra/browser-logos/master/src/safari/safari_48x48.png\n"
  },
  {
    "path": "README.zh-TW.md",
    "content": "## You (Might) Don't Need jQuery\n\n當今的前端環境發展迅速，現代瀏覽器已經提供了夠好用的 DOM/BOM API，我們不需要為了 DOM 操作或事件處理而從頭開始學 jQuery。同時，由於 React、Angular 和 Vue 等前端框架的普及，直接操作 DOM 變成了反模式，jQuery 的使用性大幅減少。本專案概述了大部份 Javascript 替代 jQuery 的方式，支援 IE 10 以上。\n\n備註：jQuery 仍然是一個很棒的函式庫，有很多有效的案例。不用刻意為了變而改變 !\n\n\n## 目錄\n\n1. [Translations](#translations)\n1. [Query Selector](#query-selector)\n1. [CSS & Style](#css--style)\n1. [DOM Manipulation](#dom-manipulation)\n1. [Ajax](#ajax)\n1. [Events](#events)\n1. [Utilities](#utilities)\n1. [Promises](#promises)\n1. [Animation](#animation)\n1. [Alternatives](#alternatives)\n1. [Browser Support](#browser-support)\n\n## Translations\n\n* [한국어](./README.ko-KR.md)\n* [正體中文](./README.zh-TW.md)\n* [简体中文](./README.zh-CN.md)\n* [Bahasa Melayu](./README-my.md)\n* [Bahasa Indonesia](./README-id.md)\n* [Português(PT-BR)](./README.pt-BR.md)\n* [Tiếng Việt Nam](./README-vi.md)\n* [Español](./README-es.md)\n* [Русский](./README-ru.md)\n* [Кыргызча](./README-kg.md)\n* [Türkçe](./README-tr.md)\n* [Italiano](./README-it.md)\n* [Français](./README-fr.md)\n* [日本語](./README-ja.md)\n* [Polski](./README-pl.md)\n\n## Query Selector\n\n常見的 class、id、屬性等選擇器，我們可以使用 `document.querySelector` 或 `document.querySelectorAll` 替代。差別是\n* `document.querySelector` 返回第一個匹配的 Element\n* `document.querySelectorAll` 返回所有匹配的 Element 組成的 NodeList。它可以通過 `[].slice.call()` 轉換成 Array 使用\n* 如果匹配不到任何 Element，jQuery 和 `document.querySelectorAll` 將會返回 `[]`，但 `document.querySelector` 會返回 `null`。\n\n> 注意：`document.querySelector` 和 `document.querySelectorAll` 效能**很差**。如果想提高效能，盡量使用 `document.getElementById`、`document.getElementsByClassName` 或 `document.getElementsByTagName`。\n\n- [1.0](#1.0) <a name='1.0'></a> Query by selector 選擇器查詢 \n\n  ```js\n  // jQuery\n  $('selector');\n\n  // Native\n  document.querySelectorAll('selector');\n  ```\n\n- [1.1](#1.1) <a name='1.1'></a> Query by class 查詢 class\n\n  ```js\n  // jQuery\n  $('.class');\n\n  // Native\n  document.querySelectorAll('.class');\n\n  // 或\n  document.getElementsByClassName('class');\n  ```\n\n- [1.2](#1.2) <a name='1.2'></a> Query by id 查詢 id \n\n  ```js\n  // jQuery\n  $('#id');\n\n  // Native\n  document.querySelector('#id');\n\n  // 或\n  document.getElementById('id');\n  ```\n\n- [1.3](#1.3) <a name='1.3'></a> Query by attribute 屬性查詢 \n\n  ```js\n  // jQuery\n  $('a[target=_blank]');\n\n  // Native\n  document.querySelectorAll('a[target=_blank]');\n  ```\n\n- [1.4](#1.4) <a name='1.4'></a> Query in descendants 後代查詢 \n\n  ```js\n  // jQuery\n  $el.find('li');\n\n  // Native\n  el.querySelectorAll('li');\n  ```\n\n- [1.5](#1.5) <a name='1.5'></a> Sibling/Previous/Next Elements 同層相鄰及前後元素 \n\n  + All siblings 同層相鄰 (兄弟元素) \n\n    ```js\n    // jQuery\n    $el.siblings();\n\n    // Native - latest, Edge13+\n    [...el.parentNode.children].filter((child) =>\n      child !== el\n    );\n    // Native (alternative) - latest, Edge13+\n    Array.from(el.parentNode.children).filter((child) =>\n      child !== el\n    );\n    // Native - IE10+\n    Array.prototype.filter.call(el.parentNode.children, (child) =>\n      child !== el\n    );\n    ```\n\n  + Previous sibling 同層前一個元素 \n\n    ```js\n    // jQuery\n    $el.prev();\n\n    // Native\n    el.previousElementSibling;\n\n    ```\n\n  + Next sibling 同層後一個元素 \n\n    ```js\n    // next\n    $el.next();\n\n    // Native\n    el.nextElementSibling;\n    ```\n    \n  + All previous siblings 所有同層裡之前的元素 \n\n    ```js\n    // jQuery (可選的過濾選擇器)\n    $el.prevAll($filter);\n\n    // Native (可選的過濾函式)\n    function getPreviousSiblings(elem, filter) {\n      var sibs = [];\n      while (elem = elem.previousSibling) {\n          if (elem.nodeType === 3) continue; // ignore text nodes\n          if (!filter || filter(elem)) sibs.push(elem);\n      }\n      return sibs;\n    }\n\n  + All next siblings 所有同層裡之後的元素 \n\n    ```js\n    // jQuery (可選的過濾選擇器)\n    $el.nextAll($filter);\n\n    // Native (可選的過濾函式)\n    function getNextSiblings(elem, filter) {\n            var sibs = [];\n            var nextElem = elem.parentNode.firstChild;\n            do {\n                if (nextElem.nodeType === 3) continue; // ignore text nodes\n                if (nextElem === elem) continue; // ignore elem of target\n                if (nextElem === elem.nextElementSibling) {\n                    if (!filter || filter(elem)) {\n                        sibs.push(nextElem);\n                        elem = nextElem;\n                    }\n                }\n            } while(nextElem = nextElem.nextSibling)\n            return sibs;\n        }\n\n一個篩選函式範例：\n\n```js\nfunction exampleFilter(elem) {\n  switch (elem.nodeName.toUpperCase()) {\n    case 'DIV':\n      return true;\n    case 'SPAN':\n      return true;\n    default:\n      return false;\n  }\n}\n```\n\n- [1.6](#1.6) <a name='1.6'></a> Closest 遍尋\n\n  Closest 返回匹配選擇器的第一個父元素，從當前元素開始沿 DOM 樹向上遍尋。\n\n  ```js\n  // jQuery\n  $el.closest(queryString);\n\n  // Native - 只支援最新版本，NO IE\n  el.closest(selector);\n\n  // Native - IE10+\n  function closest(el, selector) {\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    while (el) {\n      if (matchesSelector.call(el, selector)) {\n        return el;\n      } else {\n        el = el.parentElement;\n      }\n    }\n    return null;\n  }\n  ```\n\n- [1.7](#1.7) <a name='1.7'></a> Parents Until\n\n  獲取當前每一個匹配元素的祖先們，不包含匹配元素本身，DOM node 或 jQuery 物件。\n\n  ```js\n  // jQuery\n  $el.parentsUntil(selector, filter);\n\n  // Native\n  function parentsUntil(el, selector, filter) {\n    const result = [];\n    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;\n\n    // 從父母開始匹配\n    el = el.parentElement;\n    while (el && !matchesSelector.call(el, selector)) {\n      if (!filter) {\n        result.push(el);\n      } else {\n        if (matchesSelector.call(el, filter)) {\n          result.push(el);\n        }\n      }\n      el = el.parentElement;\n    }\n    return result;\n  }\n  ```\n\n- [1.8](#1.8) <a name='1.8'></a> Form 表單\n\n  + Input / Textarea 輸入欄位\n\n    ```js\n    // jQuery\n    $('#my-input').val();\n\n    // Native\n    document.querySelector('#my-input').value;\n    ```\n\n  + 獲取 e.currentTarget 在 `.radio` 中的索引值\n\n    ```js\n    // jQuery\n    $('.radio').index(e.currentTarget);\n\n    // Native\n    Array.from(document.querySelectorAll('.radio')).indexOf(e.currentTarget);\n    or\n    Array.prototype.indexOf.call(document.querySelectorAll('.radio'), e.currentTarget);\n    ```\n\n- [1.9](#1.9) <a name='1.9'></a> Iframe Contents\n\n  `$('iframe').contents()` 在 jQuery 返回的是 iframe 内的 `document`\n\n  + Iframe contents\n\n    ```js\n    // jQuery\n    $iframe.contents();\n\n    // Native\n    iframe.contentDocument;\n    ```\n\n  + Iframe Query\n\n    ```js\n    // jQuery\n    $iframe.contents().find('.css');\n\n    // Native\n    iframe.contentDocument.querySelectorAll('.css');\n    ```\n\n- [1.10](#1.10) <a name='1.10'></a> 獲取 body\n\n  ```js\n  // jQuery\n  $('body');\n\n  // Native\n  document.body;\n  ```\n\n- [1.11](#1.11) <a name='1.11'></a> 獲取或設置屬性\n\n  + Get an attribute 獲取屬性 \n\n    ```js\n    // jQuery\n    $el.attr('foo');\n\n    // Native\n    el.getAttribute('foo');\n    ```\n  + Set an attribute 設置屬性 \n\n    ```js\n    // jQuery, 請注意，這可以在記憶體中工作，無需更改 DOM\n    $el.attr('foo', 'bar');\n\n    // Native\n    el.setAttribute('foo', 'bar');\n    ```\n\n  + 獲取 `data-` 屬性 \n\n    ```js\n    // jQuery\n    $el.data('foo');\n\n    // Native (使用 `getAttribute`)\n    el.getAttribute('data-foo');\n\n    // Native (如果只需要支援 IE 11 以上，可以使用 `dataset`)\n    el.dataset['foo'];\n    ```\n\n- [1.12](#1.12) <a name='1.12'></a> 包含字串的選擇器 (區分大小寫)\n\n    ```js\n    // jQuery\n    $(\"selector:contains('text')\");\n\n    // Native\n    function contains(selector, text) {\n      var elements = document.querySelectorAll(selector);\n      return Array.from(elements).filter(function(element) {\n        return RegExp(text).test(element.textContent);\n      });\n    }\n    ```\n\n**[⬆ 回到頂部](#目錄)**\n\n## CSS & Style\n\n- [2.1](#2.1) <a name='2.1'></a> CSS\n\n  + 獲取樣式\n\n    ```js\n    // jQuery\n    $el.css(\"color\");\n\n    // Native\n    // 注意: 已知問題，如果樣式的值為 'auto'，將會返回 'auto'\n    const win = el.ownerDocument.defaultView;\n\n    // null 意指不返回偽樣式\n    win.getComputedStyle(el, null).color;\n    ```\n\n  + 設置樣式\n\n    ```js\n    // jQuery\n    $el.css({ color: \"#ff0011\" });\n\n    // Native\n    el.style.color = '#ff0011';\n    ```\n\n  + 獲取 / 設置樣式\n\n    注意：如果想一次設置多個樣式，可以參考 oui-dom-utils 裡 [setStyles](https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L194) 的方法\n\n  + Add class 增加樣式 \n\n    ```js\n    // jQuery\n    $el.addClass(className);\n\n    // Native\n    el.classList.add(className);\n    ```\n\n  + remove class 移除樣式 \n\n    ```js\n    // jQuery\n    $el.removeClass(className);\n\n    // Native\n    el.classList.remove(className);\n    ```\n\n  + has class 是否有樣式 \n\n    ```js\n    // jQuery\n    $el.hasClass(className);\n\n    // Native\n    el.classList.contains(className);\n    ```\n\n  + Toggle class 觸發樣式 \n\n    ```js\n    // jQuery\n    $el.toggleClass(className);\n\n    // Native\n    el.classList.toggle(className);\n    ```\n\n- [2.2](#2.2) <a name='2.2'></a> Width & Height\n\n  Width 與 Height 獲取方式相同，下面以 Height 為例：\n\n  + Window height\n\n    ```js\n    // window height\n    $(window).height();\n\n    // 沒有捲軸，行為像 jQuery\n    window.document.documentElement.clientHeight;\n\n    // 有捲軸\n    window.innerHeight;\n    ```\n\n  + Document height\n\n    ```js\n    // jQuery\n    $(document).height();\n\n    // Native\n    const body = document.body;\n    const html = document.documentElement;\n    const height = Math.max(\n      body.offsetHeight,\n      body.scrollHeight,\n      html.clientHeight,\n      html.offsetHeight,\n      html.scrollHeight\n    );\n    ```\n\n  + Element height\n\n    ```js\n    // jQuery\n    $el.height();\n\n    // Native\n    function getHeight(el) {\n      const styles = this.getComputedStyle(el);\n      const height = el.offsetHeight;\n      const borderTopWidth = parseFloat(styles.borderTopWidth);\n      const borderBottomWidth = parseFloat(styles.borderBottomWidth);\n      const paddingTop = parseFloat(styles.paddingTop);\n      const paddingBottom = parseFloat(styles.paddingBottom);\n      return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;\n    }\n\n    // 精準到整數（當 `border-box` 時為 `height - border` 值；當 `content-box` 時為 `height + padding` 值）\n    el.clientHeight;\n\n    // 精準到小數（當 `border-box` 時為 `height` 值；當 `content-box` 時為 `height + padding + border` 值）\n    el.getBoundingClientRect().height;\n    ```\n\n- [2.3](#2.3) <a name='2.3'></a> Position & Offset 定位和位移 \n\n  + Position 定位 \n\n    獲得匹配元素相對於父元素的坐標\n\n    ```js\n    // jQuery\n    $el.position();\n\n    // Native\n    { left: el.offsetLeft, top: el.offsetTop }\n    ```\n\n  + Offset 位移 \n\n    獲得匹配元素相對於文件的坐標\n\n    ```js\n    // jQuery\n    $el.offset();\n\n    // Native\n    function getOffset (el) {\n      const box = el.getBoundingClientRect();\n\n      return {\n        top: box.top + window.pageYOffset - document.documentElement.clientTop,\n        left: box.left + window.pageXOffset - document.documentElement.clientLeft\n      }\n    }\n    ```\n\n- [2.4](#2.4) <a name='2.4'></a> Scroll Top\n\n\n  獲取元素滾動條的當前垂直位置。\n\n  ```js\n  // jQuery\n  $(window).scrollTop();\n\n  // Native\n  (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;\n  ```\n\n**[⬆ 回到頂部](#目錄)**\n\n## DOM Manipulation DOM 操作 \n\n- [3.1](#3.1) <a name='3.1'></a> Remove 移除 \n\n  從 DOM 中移除元素。\n\n  ```js\n  // jQuery\n  $el.remove();\n\n  // Native\n  el.parentNode.removeChild(el);\n  ```\n\n- [3.2](#3.2) <a name='3.2'></a> Text 文字 \n\n  + Get text 獲取文字 \n\n    返回元素的文本內容，包含其後代。\n\n    ```js\n    // jQuery\n    $el.text();\n\n    // Native\n    el.textContent;\n    ```\n\n  + Set text 設置文字 \n\n    設置元素的文本內容。\n\n    ```js\n    // jQuery\n    $el.text(string);\n\n    // Native\n    el.textContent = string;\n    ```\n\n- [3.3](#3.3) <a name='3.3'></a> HTML\n\n  + Get HTML 獲取 HTML \n\n    ```js\n    // jQuery\n    $el.html();\n\n    // Native\n    el.innerHTML;\n    ```\n\n  + Set HTML 設置 HTML \n\n    ```js\n    // jQuery\n    $el.html(htmlString);\n\n    // Native\n    el.innerHTML = htmlString;\n    ```\n\n- [3.4](#3.4) <a name='3.4'></a> Append 追加 \n\n  Append 在父元素的最後一個子元素後追加子元素\n\n  ```js\n  // jQuery\n  $el.append(\"<div id='container'>hello</div>\");\n\n  // Native (HTML 字串)\n  el.insertAdjacentHTML('beforeend', '<div id=\"container\">Hello World</div>');\n\n  // Native (元素)\n  el.appendChild(newEl);\n  ```\n\n- [3.5](#3.5) <a name='3.5'></a> Prepend 前置 \n\n  ```js\n  // jQuery\n  $el.prepend(\"<div id='container'>hello</div>\");\n\n  // Native (HTML 字串)\n  el.insertAdjacentHTML('afterbegin', '<div id=\"container\">Hello World</div>');\n\n  // Native (元素)\n  el.insertBefore(newEl, el.firstChild);\n  ```\n\n- [3.6](#3.6) <a name='3.6'></a> insertBefore 在元素前方插入 \n\n  在選取的元素前插入新節點\n\n  ```js\n  // jQuery\n  $newEl.insertBefore(queryString);\n\n  // Native (HTML 字串)\n  el.insertAdjacentHTML('beforebegin ', '<div id=\"container\">Hello World</div>');\n\n  // Native (元素)\n  const el = document.querySelector(selector);\n  if (el.parentNode) {\n    el.parentNode.insertBefore(newEl, el);\n  }\n  ```\n\n- [3.7](#3.7) <a name='3.7'></a> insertAfter 在元素後方插入 \n\n  在選取的元素插入新節點\n\n  ```js\n  // jQuery\n  $newEl.insertAfter(queryString);\n\n  // Native (HTML 字串)\n  el.insertAdjacentHTML('afterend', '<div id=\"container\">Hello World</div>');\n\n  // Native (元素)\n  const el = document.querySelector(selector);\n  if (el.parentNode) {\n    el.parentNode.insertBefore(newEl, el.nextSibling);\n  }\n  ```\n\n- [3.8](#3.8) <a name='3.8'></a> is\n\n  如果匹配 query selector，返回 `true`\n\n    ```js\n    // jQuery\n    $el.is(selector);\n\n    // Native\n    el.matches(selector);\n    ```\n\n- [3.9](#3.9) <a name='3.9'></a> clone\n\n  創造一個深拷貝元素：此拷貝包含匹配元素及其所有後代元素和文本節點。\n\n  ```js\n  // jQuery. 將參數設為 `true` 以表示應將事件處理程序與元素一起複製。\n  $el.clone();\n\n  // Native\n  el.cloneNode();\n  ```\n\n- [3.10](#3.10) <a name='3.10'></a> empty\n\n  移除所有子節點\n\n```js\n// jQuery\n$el.empty();\n\n// Native\nel.innerHTML = '';\n```\n\n- [3.11](#3.11) <a name='3.11'></a> wrap\n\n 把每個被選取的元素放到指定的 HTML 結構裡\n\n ```js\n // jQuery\n $(\".inner\").wrap('<div class=\"wrapper\"></div>');\n\n // Native\n Array.from(document.querySelectorAll('.inner')).forEach((el) => {\n    const wrapper = document.createElement('div');\n    wrapper.className = 'wrapper';\n    el.parentNode.insertBefore(wrapper, el);\n    el.parentNode.removeChild(el);\n    wrapper.appendChild(el);\n });\n\n ```\n\n- [3.12](#3.12) <a name=\"3.12\"></a> unwrap\n\n  從 DOM 結構移除匹配元素的父元素\n\n  ```js\n  // jQuery\n  $('.inner').unwrap();\n\n  // Native\n  Array.from(document.querySelectorAll('.inner')).forEach((el) => {\n    let elParentNode = el.parentNode\n\n    if(elParentNode !== document.body) {\n      elParentNode.parentNode.insertBefore(el, elParentNode)\n      elParentNode.parentNode.removeChild(elParentNode)\n    }\n  });\n  ```\n\n- [3.13](#3.13) <a name=\"3.13\"></a> replaceWith\n\n  用提供的新內容取代任何匹配元素集中的每個元素\n\n  ```js\n  // jQuery\n  $('.inner').replaceWith('<div class=\"outer\"></div>');\n\n  // Native (方案一) - 最新版或 Edge17+\n  Array.from(document.querySelectorAll('.inner')).forEach((el) => {\n    const outer = document.createElement('div');\n    outer.className = 'outer';\n    el.replaceWith(outer);\n  });\n\n  // Native\n  Array.from(document.querySelectorAll('.inner')).forEach((el) => {\n    const outer = document.createElement(\"div\");\n    outer.className = \"outer\";\n    el.parentNode.replaceChild(outer, el);\n  });\n  ```\n\n- [3.14](#3.14) <a name='3.14'></a> simple parse\n\n  解析 HTML / SVG / XML 字串\n\n  ```js\n  // jQuery\n  $(`<ol>\n    <li>a</li>\n    <li>b</li>\n  </ol>\n  <ol>\n    <li>c</li>\n    <li>d</li>\n  </ol>`);\n\n  // Native\n  range = document.createRange();\n  parse = range.createContextualFragment.bind(range);\n\n  parse(`<ol>\n    <li>a</li>\n    <li>b</li>\n  </ol>\n  <ol>\n    <li>c</li>\n    <li>d</li>\n  </ol>`);\n  ```\n\n**[⬆ 回到頂部](#目錄)**\n\n## Ajax\n\n[Fetch API](https://fetch.spec.whatwg.org/) 是一個用是來替換 XMLHttpRequest 執行 ajax 的新標準。適用於 Chrome 和 Firefox，你可以使用 polyfill 讓它在舊版瀏覽器上運行。。\n\nIE9+ 請使用 [github/fetch](http://github.com/github/fetch)，IE8+ 請使用 [fetch-ie8](https://github.com/camsong/fetch-ie8/)，JSONP 請使用 [fetch-jsonp](https://github.com/camsong/fetch-jsonp)。\n\n- [4.1](#4.1) <a name='4.1'></a> 從伺服器載入數據並將返回的 HTML 放入匹配的元素中。\n\n  ```js\n  // jQuery\n  $(selector).load(url, completeCallback)\n\n  // Native\n  fetch(url).then(data => data.text()).then(data => {\n    document.querySelector(selector).innerHTML = data\n  }).then(completeCallback)\n  ```\n\n**[⬆ 回到頂部](#目錄)**\n\n## Events\n\n完整的替代命名空間及事件處理，請參考 https://github.com/oneuijs/oui-dom-events\n\n- [5.0](#5.0) <a name='5.0'></a> Document ready by `DOMContentLoaded`\n\n  ```js\n  // jQuery\n  $(document).ready(eventHandler);\n\n  // Native\n  // 檢查 DOMContentLoaded 是否已經完成\n  if (document.readyState !== 'loading') {\n    eventHandler();\n  } else {\n    document.addEventListener('DOMContentLoaded', eventHandler);\n  }\n  ```\n\n- [5.1](#5.1) <a name='5.1'></a> 使用 on 綁定事件\n\n  ```js\n  // jQuery\n  $el.on(eventName, eventHandler);\n\n  // Native\n  el.addEventListener(eventName, eventHandler);\n  ```\n\n- [5.2](#5.2) <a name='5.2'></a> 使用 off 綁定事件\n\n  ```js\n  // jQuery\n  $el.off(eventName, eventHandler);\n\n  // Native\n  el.removeEventListener(eventName, eventHandler);\n  ```\n\n- [5.3](#5.3) <a name='5.3'></a> Trigger\n\n  ```js\n  // jQuery\n  $(el).trigger('custom-event', {key1: 'data'});\n\n  // Native\n  if (window.CustomEvent) {\n    const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});\n  } else {\n    const event = document.createEvent('CustomEvent');\n    event.initCustomEvent('custom-event', true, true, {key1: 'data'});\n  }\n\n  el.dispatchEvent(event);\n  ```\n\n**[⬆ 回到頂部](#目錄)**\n\n## Utilities\n\n大部份的 jQuery 實用工具都能在 native API 中找到。其它進階功能可以選用專注於穩定及效能的優質工具庫，推薦 [lodash](https://lodash.com)。\n\n- [6.1](#6.1) <a name='6.1'></a> 基本工具\n\n  + isArray\n\n  判斷參數是否為陣列。\n\n  ```js\n  // jQuery\n  $.isArray(array);\n\n  // Native\n  Array.isArray(array);\n  ```\n\n  + isWindow\n\n  判斷參數是否為 window\n\n  ```js\n  // jQuery\n  $.isWindow(obj);\n\n  // Native\n  function isWindow(obj) {\n    return obj !== null && obj !== undefined && obj === obj.window;\n  }\n  ```\n\n  + inArray\n\n  在陣列中搜尋指定值並返回索引值 (找不到則返回 -1)。\n\n  ```js\n  // jQuery\n  $.inArray(item, array);\n\n  // Native\n  array.indexOf(item) > -1;\n\n  // ES6-way\n  array.includes(item);\n  ```\n\n  + isNumeric\n\n  判斷傳入的參數是否為數字。\n  為了更好的準確性，請使用 `typeof` 確定型別，或參考下方 `type` 範例。\n\n  ```js\n  // jQuery\n  $.isNumeric(item);\n\n  // Native\n  function isNumeric(n) {\n    return !isNaN(parseFloat(n)) && isFinite(n);\n  }\n  ```\n\n  + isFunction\n\n  判斷傳入的參數是否為 Javascript 函式。\n\n  ```js\n  // jQuery\n  $.isFunction(item);\n\n  // Native\n  function isFunction(item) {\n    if (typeof item === 'function') {\n      return true;\n    }\n    var type = Object.prototype.toString.call(item);\n    return type === '[object Function]' || type === '[object GeneratorFunction]';\n  }\n  ```\n\n  + isEmptyObject\n\n  檢測物件是否為空值 (包含不可枚舉的屬性)\n\n  ```js\n  // jQuery\n  $.isEmptyObject(obj);\n\n  // Native\n  function isEmptyObject(obj) {\n    return Object.keys(obj).length === 0;\n  }\n  ```\n\n  + isPlainObject\n\n  檢測物件是否為純對象 (使用 “{}” 或 “new Object” 創建)\n\n  ```js\n  // jQuery\n  $.isPlainObject(obj);\n\n  // Native\n  function isPlainObject(obj) {\n    if (typeof (obj) !== 'object' || obj.nodeType || obj !== null && obj !== undefined && obj === obj.window) {\n      return false;\n    }\n\n    if (obj.constructor &&\n        !Object.prototype.hasOwnProperty.call(obj.constructor.prototype, 'isPrototypeOf')) {\n      return false;\n    }\n\n    return true;\n  }\n  ```\n\n  + extend\n\n  將二個或多個物件的內容合併到一個新物件中，且不修改任一個參數。\n  object.assign 是 ES6 API，你也可以使用 [polyfill](https://github.com/ljharb/object.assign)。\n\n  ```js\n  // jQuery\n  $.extend({}, object1, object2);\n\n  // Native\n  Object.assign({}, object1, object2);\n  ```\n\n  + trim\n\n  刪除字串開頭和結尾的空白。\n\n  ```js\n  // jQuery\n  $.trim(string);\n\n  // Native\n  string.trim();\n  ```\n\n  + map\n\n  將陣列或物件裡的所有項目轉換為新的陣列項目。\n\n  ```js\n  // jQuery\n  $.map(array, (value, index) => {\n  });\n\n  // Native\n  array.map((value, index) => {\n  });\n  ```\n\n  + each\n\n  通用迭代函式，可用於無縫迭代物件或陣列。\n\n  ```js\n  // jQuery\n  $.each(array, (index, value) => {\n  });\n\n  // Native\n  array.forEach((value, index) => {\n  });\n  ```\n\n  + grep\n\n  找到陣列中符合過濾函式的元素。\n\n  ```js\n  // jQuery\n  $.grep(array, (value, index) => {\n  });\n\n  // Native\n  array.filter((value, index) => {\n  });\n  ```\n\n  + type\n\n  檢測物件中的 JavaScript [Class] 內部型態。\n\n  ```js\n  // jQuery\n  $.type(obj);\n\n  // Native\n  function type(item) {\n    const reTypeOf = /(?:^\\[object\\s(.*?)\\]$)/;\n    return Object.prototype.toString.call(item)\n      .replace(reTypeOf, '$1')\n      .toLowerCase();\n  }\n  ```\n\n  + merge\n\n  將二個陣列的內容合併到第一個陣列裡。\n\n  ```js\n  // jQuery, 不會刪除重複的項目\n  $.merge(array1, array2);\n\n  // Native, 不會刪除重複的項目\n  function merge(...args) {\n    return [].concat(...args)\n  }\n\n  // ES6-way, 不會刪除重複的項目\n  array1 = [...array1, ...array2]\n\n  // Set version, 不會刪除重複的項目\n  function merge(...args) {\n    return Array.from(new Set([].concat(...args)))\n  }\n  ```\n\n  + now\n\n  返回表示當前時間的數字。\n\n  ```js\n  // jQuery\n  $.now();\n\n  // Native\n  Date.now();\n  ```\n\n  + proxy\n\n  傳入一個函式並返回一個新的函式，該函式綁定指定的上下文。\n\n  ```js\n  // jQuery\n  $.proxy(fn, context);\n\n  // Native\n  fn.bind(context);\n  ```\n\n  <a name=\"makeArray\"></a>+ makeArray\n\n  將類似陣列的物件轉換為真正的 JavaScript 陣列。\n\n  ```js\n  // jQuery\n  $.makeArray(arrayLike);\n\n  // Native\n  Array.prototype.slice.call(arrayLike);\n\n  // ES6-way: Array.from() method\n  Array.from(arrayLike);\n\n  // ES6-way: spread operator 展開運算式\n  [...arrayLike];\n  ```\n\n- [6.2](#6.2) <a name='6.2'></a> Contains\n\n  檢查 DOM 元素是否為其它 DOM 元素的後代。\n\n  ```js\n  // jQuery\n  $.contains(el, child);\n\n  // Native\n  el !== child && el.contains(child);\n  ```\n\n- [6.3](#6.3) <a name='6.3'></a> Globaleval\n\n  執行一些 JavaScript 的全域域代碼。\n\n  ```js\n  // jQuery\n  $.globaleval(code);\n\n  // Native\n  function Globaleval(code) {\n    const script = document.createElement('script');\n    script.text = code;\n\n    document.head.appendChild(script).parentNode.removeChild(script);\n  }\n\n  // 使用 eval，但 eval 的上下文是當前的，而 $.Globaleval 的上下文是 global 全域的。\n  eval(code);\n  ```\n\n- [6.4](#6.4) <a name='6.4'></a> parse\n\n  + parseHTML\n\n  將字串解析為 DOM nodes 陣列。\n\n  ```js\n  // jQuery\n  $.parseHTML(htmlString);\n\n  // Native\n  function parseHTML(string) {\n    const context = document.implementation.createHTMLDocument();\n\n    // Set the base href for the created document so any parsed elements with URLs\n    // are based on the document's URL\n    const base = context.createElement('base');\n    base.href = document.location.href;\n    context.head.appendChild(base);\n\n    context.body.innerHTML = string;\n    return context.body.children;\n  }\n  ```\n- [6.5](#6.4) <a name='6.5'></a> exists\n\n+ exists\n\n  檢查元素是否存在於 DOM 裡。\n\n  ```js\n  // jQuery\n  if ($('selector').length) {\n     // exists\n  }\n\n  // Native\n  var element =  document.getElementById('elementId');\n  if (typeof(element) != 'undefined' && element != null)\n  {\n     // exists\n  }\n  ```\n\n**[⬆ 回到頂部](#目錄)**\n\n## Promises\n\npromise 表示異步操作的最終結果。 jQuery 用它自己的方式來處理 promises。原生 JavaScript 依據 [Promises/A+](http://promises-aplus.github.io/promises-spec/) 標準來實現最小 API 處理 promises。\n\n- [7.1](#7.1) <a name='7.1'></a> done, fail, always\n\n  `done` 會在 promise 解決時調用，`fail` 會在 promise 拒絕時調用，`always` 無論 promise 解決或拒絕時都會調用。\n\n  ```js\n  // jQuery\n  $promise.done(doneCallback).fail(failCallback).always(alwaysCallback)\n\n  // Native\n  promise.then(doneCallback, failCallback).then(alwaysCallback, alwaysCallback)\n  ```\n\n- [7.2](#7.2) <a name='7.2'></a> when\n\n  `when` 用於處理多個 promises。當全部 promises 被解決時返回，當任一 promises 被拒絕時拒絕。\n\n  ```js\n  // jQuery\n  $.when($promise1, $promise2).done((promise1Result, promise2Result) => {\n  });\n\n  // Native\n  Promise.all([$promise1, $promise2]).then([promise1Result, promise2Result] => {});\n  ```\n\n- [7.3](#7.3) <a name='7.3'></a> Deferred\n\n  Deferred 是創建 promises 的一種方式。\n\n  ```js\n  // jQuery\n  function asyncFunc() {\n    const defer = new $.Deferred();\n    setTimeout(() => {\n      if(true) {\n        defer.resolve('some_value_computed_asynchronously');\n      } else {\n        defer.reject('failed');\n      }\n    }, 1000);\n\n    return defer.promise();\n  }\n\n  // Native\n  function asyncFunc() {\n    return new Promise((resolve, reject) => {\n      setTimeout(() => {\n        if (true) {\n          resolve('some_value_computed_asynchronously');\n        } else {\n          reject('failed');\n        }\n      }, 1000);\n    });\n  }\n\n  // Deferred way\n  function defer() {\n    const deferred = {};\n    const promise = new Promise((resolve, reject) => {\n      deferred.resolve = resolve;\n      deferred.reject = reject;\n    });\n\n    deferred.promise = () => {\n      return promise;\n    };\n\n    return deferred;\n  }\n\n  function asyncFunc() {\n    const defer = defer();\n    setTimeout(() => {\n      if(true) {\n        defer.resolve('some_value_computed_asynchronously');\n      } else {\n        defer.reject('failed');\n      }\n    }, 1000);\n\n    return defer.promise();\n  }\n  ```\n\n**[⬆ 回到頂部](#目錄)**\n\n## Animation\n\n- [8.1](#8.1) <a name='8.1'></a> Show & Hide\n\n  ```js\n  // jQuery\n  $el.show();\n  $el.hide();\n\n  // Native\n  // 更多 show 方法的細節，請參考 https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L363\n  el.style.display = ''|'inline'|'inline-block'|'inline-table'|'block';\n  el.style.display = 'none';\n  ```\n\n- [8.2](#8.2) <a name='8.2'></a> Toggle\n\n  顯示或隱藏元素。\n\n  ```js\n  // jQuery\n  $el.toggle();\n\n  // Native\n  if (el.ownerDocument.defaultView.getComputedStyle(el, null).display === 'none') {\n    el.style.display = ''|'inline'|'inline-block'|'inline-table'|'block';\n  } else {\n    el.style.display = 'none';\n  }\n  ```\n\n- [8.3](#8.3) <a name='8.3'></a> FadeIn & FadeOut\n\n  ```js\n  // jQuery\n  $el.fadeIn(3000);\n  $el.fadeOut(3000);\n\n  // Native fadeOut\n  function fadeOut(el, ms) {\n    if (ms) {\n      el.style.transition = `opacity ${ms} ms`;\n      el.addEventListener(\n        'transitionend',\n        function(event) {\n          el.style.display = 'none';\n        },\n        false\n      );\n    }\n    el.style.opacity = '0';\n  }\n\n  // Native fadeIn\n  function fadeIn(elem, ms) {\n    elem.style.opacity = 0;\n\n    if (ms) {\n      let opacity = 0;\n      const timer = setInterval(function() {\n        opacity += 50 / ms;\n        if (opacity >= 1) {\n          clearInterval(timer);\n          opacity = 1;\n        }\n        elem.style.opacity = opacity;\n      }, 50);\n    } else {\n      elem.style.opacity = 1;\n    }\n  }\n  ```\n\n- [8.4](#8.4) <a name='8.4'></a> FadeTo\n\n  調整元素的透明度。\n\n  ```js\n  // jQuery\n  $el.fadeTo('slow',0.15);\n  // Native\n  el.style.transition = 'opacity 3s'; // assume 'slow' equals 3 seconds\n  el.style.opacity = '0.15';\n  ```\n\n- [8.5](#8.5) <a name='8.5'></a> FadeToggle\n\n  動畫調整透明度來顯示或隱藏。\n\n  ```js\n  // jQuery\n  $el.fadeToggle();\n\n  // Native\n  el.style.transition = 'opacity 3s';\n  const { opacity } = el.ownerDocument.defaultView.getComputedStyle(el, null);\n  if (opacity === '1') {\n    el.style.opacity = '0';\n  } else {\n    el.style.opacity = '1';\n  }\n  ```\n\n- [8.6](#8.6) <a name='8.6'></a> SlideUp & SlideDown\n\n  ```js\n  // jQuery\n  $el.slideUp();\n  $el.slideDown();\n\n  // Native\n  const originHeight = '100px';\n  el.style.transition = 'height 3s';\n  // slideUp\n  el.style.height = '0px';\n  // slideDown\n  el.style.height = originHeight;\n  ```\n\n- [8.7](#8.7) <a name='8.7'></a> SlideToggle\n\n  滑動效果來顯示或隱藏元素。\n\n  ```js\n  // jQuery\n  $el.slideToggle();\n\n  // Native\n  const originHeight = '100px';\n  el.style.transition = 'height 3s';\n  const { height } = el.ownerDocument.defaultView.getComputedStyle(el, null);\n  if (parseInt(height, 10) === 0) {\n    el.style.height = originHeight;\n  } else {\n   el.style.height = '0px';\n  }\n  ```\n\n- [8.8](#8.8) <a name='8.8'></a> Animate\n\n  執行一組自定義動畫的 CSS 屬性。\n\n  ```js\n  // jQuery\n  $el.animate({ params }, speed);\n\n  // Native\n  el.style.transition = 'all ' + speed;\n  Object.keys(params).forEach((key) => {\n    el.style[key] = params[key];\n  });\n  ```\n\n## Alternatives\n\n* [You Might Not Need jQuery](http://youmightnotneedjquery.com/) - Examples of how to do common event, element, ajax etc with plain javascript.\n* [npm-dom](http://github.com/npm-dom) and [webmodules](http://github.com/webmodules) - Organizations you can find individual DOM modules on NPM\n\n## Browser Support\n\n![Chrome][chrome-image] | ![Firefox][firefox-image] | ![IE][ie-image] | ![Opera][opera-image] | ![Safari][safari-image]\n--- | --- | --- | --- | --- |\nLatest ✔ | Latest ✔ | 10+ ✔ | Latest ✔ | 6.1+ ✔ |\n\n# License\n\nMIT\n\n[chrome-image]: https://raw.github.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png\n[firefox-image]: https://raw.github.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png\n[ie-image]: https://raw.github.com/alrra/browser-logos/master/src/archive/internet-explorer_9-11/internet-explorer_9-11_48x48.png\n[opera-image]: https://raw.github.com/alrra/browser-logos/master/src/opera/opera_48x48.png\n[safari-image]: https://raw.github.com/alrra/browser-logos/master/src/safari/safari_48x48.png\n"
  },
  {
    "path": "karma.conf.js",
    "content": "// Karma configuration\n// Generated on Sun Nov 22 2015 22:10:47 GMT+0800 (CST)\nrequire('babel-core/register');\nprocess.env.CHROME_BIN = require('puppeteer').executablePath();\n\nmodule.exports = function(config) {\n  config.set({\n    // base path that will be used to resolve all patterns (eg. files, exclude)\n    basePath: '.',\n\n    // frameworks to use\n    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter\n    frameworks: ['mocha'],\n\n    // list of files / patterns to load in the browser\n    files: [\n      './test/**/*.spec.js'\n    ],\n\n    // list of files to exclude\n    exclude: [\n    ],\n\n    // preprocess matching files before serving them to the browser\n    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor\n    preprocessors: {\n      'test/**/*.spec.js': ['webpack', 'sourcemap']\n    },\n\n    // test results reporter to use\n    // possible values: 'dots', 'progress'\n    // available reporters: https://npmjs.org/browse/keyword/karma-reporter\n    reporters: ['progress'],\n\n    coverageReporter: {\n      reporters: [\n        {type: 'text'},\n        {type: 'html', dir: 'coverage'},\n      ]\n    },\n\n    webpackMiddleware: {\n      stats: 'minimal'\n    },\n\n    webpack: {\n      cache: true,\n      devtool: 'inline-source-map',\n      module: {\n        loaders: [{\n          test: /\\.jsx?$/,\n          loader: 'babel-loader',\n          exclude: /node_modules/\n        }],\n        postLoaders: [{\n          test: /\\.js/,\n          exclude: /(test|node_modules)/,\n          loader: 'istanbul-instrumenter'\n        }],\n      },\n      resolve: {\n        extensions: ['', '.js', '.jsx']\n      }\n    },\n\n    // web server port\n    port: 9876,\n\n    // enable / disable colors in the output (reporters and logs)\n    colors: true,\n\n    // level of logging\n    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG\n    logLevel: config.LOG_INFO,\n\n    // enable / disable watching file and executing tests whenever any file changes\n    autoWatch: true,\n\n    // start these browsers\n    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher\n    browsers: ['ChromeHeadless'],\n\n    // Continuous Integration mode\n    // if true, Karma captures browsers, runs the tests and exits\n    // singleRun: false,\n\n    // Concurrency level\n    // how many browser should be started simultanous\n    // concurrency: Infinity,\n\n    // plugins: ['karma-phantomjs-launcher', 'karma-sourcemap-loader', 'karma-webpack']\n  })\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"You-Dont-Need-jQuery\",\n  \"version\": \"2.0.0\",\n  \"description\": \"Examples of how to do query, style, dom, ajax, event etc like jQuery with plain javascript.\",\n  \"scripts\": {\n    \"test\": \"karma start --single-run\",\n    \"tdd\": \"karma start --auto-watch --no-single-run\",\n    \"test-cov\": \"karma start --auto-watch --single-run --reporters progress,coverage\",\n    \"lint\": \"eslint src test\"\n  },\n  \"devDependencies\": {\n    \"babel-cli\": \"^6.23.0\",\n    \"babel-core\": \"^6.23.1\",\n    \"babel-eslint\": \"^7.1.1\",\n    \"babel-loader\": \"^6.4.0\",\n    \"babel-preset-es2015\": \"^6.22.0\",\n    \"babel-preset-stage-0\": \"^6.22.0\",\n    \"chai\": \"^3.5.0\",\n    \"eslint\": \"^3.17.1\",\n    \"eslint-config-airbnb\": \"^14.1.0\",\n    \"eslint-plugin-import\": \"^2.2.0\",\n    \"eslint-plugin-jsx-a11y\": \"^4.0.0\",\n    \"eslint-plugin-react\": \"^6.10.0\",\n    \"isparta\": \"^4.0.0\",\n    \"istanbul-instrumenter-loader\": \"^2.0.0\",\n    \"jquery\": \"^3.1.1\",\n    \"karma\": \"^1.5.0\",\n    \"karma-chrome-launcher\": \"^3.1.0\",\n    \"karma-coverage\": \"^1.1.1\",\n    \"karma-mocha\": \"^1.3.0\",\n    \"karma-sourcemap-loader\": \"^0.3.7\",\n    \"karma-webpack\": \"^2.0.2\",\n    \"mocha\": \"^3.2.0\",\n    \"puppeteer\": \"^9.1.1\",\n    \"webpack\": \"^1.12.9\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/nefe/You-Dont-Need-jQuery.git\"\n  },\n  \"keywords\": [\n    \"Vanilla JS\",\n    \"jQuery\",\n    \"convertion guide\",\n    \"es6\",\n    \"es2015\",\n    \"babel\"\n  ],\n  \"author\": \"Cam Song and open source authors\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/nefe/You-Dont-Need-jQuery/issues\"\n  },\n  \"homepage\": \"https://github.com/nefe/You-Dont-Need-jQuery\"\n}\n"
  },
  {
    "path": "test/README.md",
    "content": "# Test cases for all the tips\n\n## Usage\n\nrun all tests once\n```\nnpm run test\n```\n\nrun tests on TDD(Test Driven Development) mode\n```\nnpm run tdd\n```\n"
  },
  {
    "path": "test/css.spec.js",
    "content": "// test for CSS related"
  },
  {
    "path": "test/dom.spec.js",
    "content": "// test for CSS and style related"
  },
  {
    "path": "test/query.spec.js",
    "content": "// tests for Query Selector related\nimport { expect } from 'chai';\nimport $ from 'jquery';\n\ndescribe('query selector', () => {\n  describe('basic', () => {\n    beforeEach(() => {\n      document.body.innerHTML = `\n        <ul id='query-selector-test1' class='list'>\n          <li data-role='red' class='item-i red item'>I</li>\n          <li data-role='blue' class='item-ii blue item'>II</li>\n          <li>III</li>\n          <li>\n            <ul id='nested-ul'>\n              <li data-role='red' class='item-i-i red item'>III.I</li>\n              <li data-role='blue' class='item-i-ii blue item'>III.II</li>\n            </ul>\n          </li>\n        </ul>\n      `;\n    });\n\n    afterEach(() => {\n      const el = document.querySelector('#query-selector-test1');\n      el.parentNode.removeChild(el);\n    });\n\n    it('1.0 Query by selector', () => {\n      const $els = $('li.item[data-role=\"red\"]');\n      const els = document.querySelectorAll('li.item[data-role=\"red\"]');\n\n      expect($els.length).to.equal(2);\n      [].forEach.call($els, ($el, i) => {\n        expect($el).to.equal(els[i]);\n      });\n    });\n\n    it('1.1 Query by class', () => {\n      const $els = $('.item');\n      const els = document.getElementsByClassName('item');\n\n      [].forEach.call($els, ($el, i) => {\n        expect($el).to.equal(els[i]);\n      });\n    });\n\n    it('1.2 Query by id', () => {\n      expect($('#nested-ul')[0]).to.equal(document.getElementById('nested-ul'));\n    });\n\n    it('1.3 Query by attribute', () => {\n      const $els = $('[data-role=\"blue\"]');\n      const els = document.querySelectorAll('[data-role=\"blue\"]');\n\n      expect($els.length).to.equal(2);\n      [].forEach.call($els, ($el, i) => {\n        expect($el).to.equal(els[i]);\n      });\n    });\n\n    it('1.4 Query in descendants', () => {\n      const $els = $('#query-selector-test1').find('.item');\n      const els = document.getElementById('query-selector-test1').querySelectorAll('.item');\n\n      expect($els.length).to.equal(4);\n      [].forEach.call($els, ($el, i) => {\n        expect($el).to.equal(els[i]);\n      });\n    });\n  });\n});"
  },
  {
    "path": "test/utilities.spec.js",
    "content": "// test for Utilities related"
  }
]