Fixtures
This commit is contained in:
Родитель
fcead0ccea
Коммит
683a747ae1
|
@ -0,0 +1 @@
|
|||
ref: refs/heads/master
|
|
@ -0,0 +1,6 @@
|
|||
[core]
|
||||
repositoryformatversion = 0
|
||||
filemode = true
|
||||
bare = false
|
||||
logallrefupdates = true
|
||||
ignorecase = true
|
Двоичный файл не отображается.
|
@ -0,0 +1 @@
|
|||
a.txt
|
Двоичные данные
spec/fixtures/ignore.git/objects/65/a457425a679cbe9adf0d2741785d3ceabb44a7
поставляемый
Normal file
Двоичные данные
spec/fixtures/ignore.git/objects/65/a457425a679cbe9adf0d2741785d3ceabb44a7
поставляемый
Normal file
Двоичный файл не отображается.
Двоичные данные
spec/fixtures/ignore.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
поставляемый
Normal file
Двоичные данные
spec/fixtures/ignore.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
поставляемый
Normal file
Двоичный файл не отображается.
Двоичные данные
spec/fixtures/ignore.git/objects/ef/046e9eecaa5255ea5e9817132d4001724d6ae1
поставляемый
Normal file
Двоичные данные
spec/fixtures/ignore.git/objects/ef/046e9eecaa5255ea5e9817132d4001724d6ae1
поставляемый
Normal file
Двоичный файл не отображается.
|
@ -0,0 +1 @@
|
|||
ef046e9eecaa5255ea5e9817132d4001724d6ae1
|
|
@ -0,0 +1 @@
|
|||
ref: refs/heads/master
|
|
@ -0,0 +1,6 @@
|
|||
[core]
|
||||
repositoryformatversion = 0
|
||||
filemode = true
|
||||
bare = false
|
||||
logallrefupdates = true
|
||||
ignorecase = true
|
Двоичный файл не отображается.
Двоичные данные
spec/fixtures/master.git/objects/65/a457425a679cbe9adf0d2741785d3ceabb44a7
поставляемый
Normal file
Двоичные данные
spec/fixtures/master.git/objects/65/a457425a679cbe9adf0d2741785d3ceabb44a7
поставляемый
Normal file
Двоичный файл не отображается.
Двоичные данные
spec/fixtures/master.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
поставляемый
Normal file
Двоичные данные
spec/fixtures/master.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
поставляемый
Normal file
Двоичный файл не отображается.
Двоичные данные
spec/fixtures/master.git/objects/ef/046e9eecaa5255ea5e9817132d4001724d6ae1
поставляемый
Normal file
Двоичные данные
spec/fixtures/master.git/objects/ef/046e9eecaa5255ea5e9817132d4001724d6ae1
поставляемый
Normal file
Двоичный файл не отображается.
|
@ -0,0 +1 @@
|
|||
ef046e9eecaa5255ea5e9817132d4001724d6ae1
|
|
@ -0,0 +1,6 @@
|
|||
[submodule "jstips"]
|
||||
path = jstips
|
||||
url = https://github.com/loverajoel/jstips
|
||||
[submodule "You-Dont-Need-jQuery"]
|
||||
path = You-Dont-Need-jQuery
|
||||
url = https://github.com/oneuijs/You-Dont-Need-jQuery
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
presets: ["es2015", "stage-0"]
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"extends": "eslint-config-airbnb",
|
||||
"env": {
|
||||
"browser": true,
|
||||
"mocha": true,
|
||||
"node": true
|
||||
},
|
||||
"rules": {
|
||||
"valid-jsdoc": 2,
|
||||
"no-param-reassign": 0,
|
||||
"comma-dangle": 0,
|
||||
"one-var": 0,
|
||||
"no-else-return": 1,
|
||||
"no-unused-expressions": 0,
|
||||
"indent": 1,
|
||||
"eol-last": 0
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
.DS_Store
|
||||
*.log
|
||||
node_modules
|
||||
coverage
|
||||
logs
|
|
@ -0,0 +1,10 @@
|
|||
language: node_js
|
||||
node_js:
|
||||
- "5"
|
||||
- "4"
|
||||
before_script:
|
||||
- export DISPLAY=:99.0
|
||||
- sh -e /etc/init.d/xvfb start
|
||||
script:
|
||||
- npm run lint
|
||||
- npm test
|
|
@ -0,0 +1,22 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 oneuijs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
@ -0,0 +1,637 @@
|
|||
|
||||
> #### You Don't Need jQuery
|
||||
|
||||
Tú no necesitas jQuery
|
||||
---
|
||||
El 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+.
|
||||
|
||||
## Tabla de Contenidos
|
||||
|
||||
1. [Query Selector](#query-selector)
|
||||
1. [CSS & Estilo](#css--estilo)
|
||||
1. [Manipulación DOM](#manipulación-dom)
|
||||
1. [Ajax](#ajax)
|
||||
1. [Eventos](#eventos)
|
||||
1. [Utilidades](#utilidades)
|
||||
1. [Traducción](#traducción)
|
||||
1. [Soporte de Navegadores](#soporte-de-navegadores)
|
||||
|
||||
|
||||
## Query Selector
|
||||
|
||||
En lugar de los selectores comunes como clase, id o atributos podemos usar `document.querySelector` o `document.querySelectorAll` como alternativas. Las diferencias radican en:
|
||||
* `document.querySelector` devuelve el primer elemento que cumpla con la condició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) || []);`
|
||||
* 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) || []`
|
||||
|
||||
> Notice: `document.querySelector` and `document.querySelectorAll` are quite **SLOW**, try to use `getElementById`, `document.getElementsByClassName` o `document.getElementsByTagName` if you want to Obtener a performance bonus.
|
||||
|
||||
- [1.0](#1.0) <a name='1.0'></a> Buscar por selector
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('selector');
|
||||
|
||||
// Nativo
|
||||
document.querySelectorAll('selector');
|
||||
```
|
||||
|
||||
- [1.1](#1.1) <a name='1.1'></a> Buscar por Clase
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('.class');
|
||||
|
||||
// Nativo
|
||||
document.querySelectorAll('.class');
|
||||
|
||||
// Forma alternativa
|
||||
document.getElementsByClassName('class');
|
||||
```
|
||||
|
||||
- [1.2](#1.2) <a name='1.2'></a> Buscar por id
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('#id');
|
||||
|
||||
// Nativo
|
||||
document.querySelector('#id');
|
||||
|
||||
// Forma alternativa
|
||||
document.getElementById('id');
|
||||
```
|
||||
|
||||
- [1.3](#1.3) <a name='1.3'></a> Buscar por atributo
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('a[target=_blank]');
|
||||
|
||||
// Nativo
|
||||
document.querySelectorAll('a[target=_blank]');
|
||||
```
|
||||
|
||||
- [1.4](#1.4) <a name='1.4'></a> Buscar
|
||||
|
||||
+ Buscar nodos
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.find('li');
|
||||
|
||||
// Nativo
|
||||
el.querySelectorAll('li');
|
||||
```
|
||||
|
||||
+ Buscar "body"
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('body');
|
||||
|
||||
// Nativo
|
||||
document.body;
|
||||
```
|
||||
|
||||
+ Buscar Atributo
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.attr('foo');
|
||||
|
||||
// Nativo
|
||||
e.getAttribute('foo');
|
||||
```
|
||||
|
||||
+ Buscar atributo "data"
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.data('foo');
|
||||
|
||||
// Nativo
|
||||
// Usando getAttribute
|
||||
el.getAttribute('data-foo');
|
||||
// También puedes utilizar `dataset` desde IE 11+
|
||||
el.dataset['foo'];
|
||||
```
|
||||
|
||||
- [1.5](#1.5) <a name='1.5'></a> Elementos Hermanos/Previos/Siguientes
|
||||
|
||||
+ Elementos hermanos
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.siblings();
|
||||
|
||||
// Nativo
|
||||
[].filter.call(el.parentNode.children, function(child) {
|
||||
return child !== el;
|
||||
});
|
||||
```
|
||||
|
||||
+ Elementos previos
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.prev();
|
||||
|
||||
// Nativo
|
||||
el.previousElementSibling;
|
||||
```
|
||||
|
||||
+ Elementos siguientes
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.next();
|
||||
|
||||
// Nativo
|
||||
el.nextElementSibling;
|
||||
```
|
||||
|
||||
- [1.6](#1.6) <a name='1.6'></a> Closest
|
||||
|
||||
Retorna el elemento más cercano que coincida con la condición, partiendo desde el nodo actual hasta document.
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.closest(queryString);
|
||||
|
||||
// Nativo
|
||||
function closest(el, selector) {
|
||||
const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
|
||||
|
||||
while (el) {
|
||||
if (matchesSelector.call(el, selector)) {
|
||||
return el;
|
||||
} else {
|
||||
el = el.parentElement;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
```
|
||||
|
||||
- [1.7](#1.7) <a name='1.7'></a> Parents Until
|
||||
|
||||
Obtiene los ancestros de cada elemento en el set actual de elementos que cumplan con la condición, sin incluir el actual
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.parentsUntil(selector, filter);
|
||||
|
||||
// Nativo
|
||||
function parentsUntil(el, selector, filter) {
|
||||
const result = [];
|
||||
const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
|
||||
|
||||
// Partir desde el elemento padre
|
||||
el = el.parentElement;
|
||||
while (el && !matchesSelector.call(el, selector)) {
|
||||
if (!filter) {
|
||||
result.push(el);
|
||||
} else {
|
||||
if (matchesSelector.call(el, filter)) {
|
||||
result.push(el);
|
||||
}
|
||||
}
|
||||
el = el.parentElement;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
```
|
||||
|
||||
- [1.8](#1.8) <a name='1.8'></a> Formularios
|
||||
|
||||
+ Input/Textarea
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('#my-input').val();
|
||||
|
||||
// Nativo
|
||||
document.querySelector('#my-input').value;
|
||||
```
|
||||
|
||||
+ Obtener el índice de e.currentTarget en `.radio`
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(e.currentTarget).index('.radio');
|
||||
|
||||
// Nativo
|
||||
[].indexOf.call(document.querySelectAll('.radio'), e.currentTarget);
|
||||
```
|
||||
|
||||
- [1.9](#1.9) <a name='1.9'></a> Contenidos de Iframe
|
||||
|
||||
`$('iframe').contents()` devuelve `contentDocument` para este iframe específico
|
||||
|
||||
+ Contenidos de Iframe
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$iframe.contents();
|
||||
|
||||
// Nativo
|
||||
iframe.contentDocument;
|
||||
```
|
||||
|
||||
+ Buscar dentro de un Iframe
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$iframe.contents().find('.css');
|
||||
|
||||
// Nativo
|
||||
iframe.contentDocument.querySelectorAll('.css');
|
||||
```
|
||||
|
||||
**[⬆ volver al inicio](#tabla-de-contenidos)**
|
||||
|
||||
## CSS & Estilo
|
||||
|
||||
- [2.1](#2.1) <a name='2.1'></a> CSS
|
||||
|
||||
+ Obtener Estilo
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.css("color");
|
||||
|
||||
// Nativo
|
||||
// NOTA: Bug conocido, retornará 'auto' si el valor de estilo es 'auto'
|
||||
const win = el.ownerDocument.defaultView;
|
||||
// null significa que no tiene pseudo estilos
|
||||
win.getComputedStyle(el, null).color;
|
||||
```
|
||||
|
||||
+ Establecer style
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.css({ color: "#ff0011" });
|
||||
|
||||
// Nativo
|
||||
el.style.color = '#ff0011';
|
||||
```
|
||||
|
||||
+ Obtener/Establecer Estilos
|
||||
|
||||
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.
|
||||
|
||||
+ Agregar clase
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.addClass(className);
|
||||
|
||||
// Nativo
|
||||
el.classList.add(className);
|
||||
```
|
||||
|
||||
+ Quitar Clase
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.removeClass(className);
|
||||
|
||||
// Nativo
|
||||
el.classList.remove(className);
|
||||
```
|
||||
|
||||
+ Consultar si tiene clase
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.hasClass(className);
|
||||
|
||||
// Nativo
|
||||
el.classList.contains(className);
|
||||
```
|
||||
|
||||
+ Toggle class
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.toggleClass(className);
|
||||
|
||||
// Nativo
|
||||
el.classList.toggle(className);
|
||||
```
|
||||
|
||||
- [2.2](#2.2) <a name='2.2'></a> Width & Height
|
||||
|
||||
Ancho y Alto son teóricamente idénticos. Usaremos el Alto como ejemplo:
|
||||
|
||||
+ Alto de Ventana
|
||||
|
||||
```js
|
||||
// alto de ventana
|
||||
$(window).height();
|
||||
// Sin scrollbar, se comporta como jQuery
|
||||
window.document.documentElement.clientHeight;
|
||||
// Con scrollbar
|
||||
window.innerHeight;
|
||||
```
|
||||
|
||||
+ Alto de Documento
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(document).height();
|
||||
|
||||
// Nativo
|
||||
document.documentElement.scrollHeight;
|
||||
```
|
||||
|
||||
+ Alto de Elemento
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.height();
|
||||
|
||||
// Nativo
|
||||
function getHeight(el) {
|
||||
const styles = this.getComputedStyles(el);
|
||||
const height = el.offsetHeight;
|
||||
const borderTopWidth = parseFloat(styles.borderTopWidth);
|
||||
const borderBottomWidth = parseFloat(styles.borderBottomWidth);
|
||||
const paddingTop = parseFloat(styles.paddingTop);
|
||||
const paddingBottom = parseFloat(styles.paddingBottom);
|
||||
return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;
|
||||
}
|
||||
// Precisión de integer(when `border-box`, it's `height`; when `content-box`, it's `height + padding + border`)
|
||||
el.clientHeight;
|
||||
// Precisión de decimal(when `border-box`, it's `height`; when `content-box`, it's `height + padding + border`)
|
||||
el.getBoundingClientRect().height;
|
||||
```
|
||||
|
||||
- [2.3](#2.3) <a name='2.3'></a> Posición & Offset
|
||||
|
||||
+ Posición
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.position();
|
||||
|
||||
// Nativo
|
||||
{ left: el.offsetLeft, top: el.offsetTop }
|
||||
```
|
||||
|
||||
+ Offset
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.offset();
|
||||
|
||||
// Nativo
|
||||
function getOffset (el) {
|
||||
const box = el.getBoundingClientRect();
|
||||
|
||||
return {
|
||||
top: box.top + window.pageYOffset - document.documentElement.clientTop,
|
||||
left: box.left + window.pageXOffset - document.documentElement.clientLeft
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [2.4](#2.4) <a name='2.4'></a> Posición del Scroll Vertical
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(window).scrollTop();
|
||||
|
||||
// Nativo
|
||||
(document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
|
||||
```
|
||||
|
||||
**[⬆ volver al inicio](#tabla-de-contenidos)**
|
||||
|
||||
## Manipulación DOM
|
||||
|
||||
- [3.1](#3.1) <a name='3.1'></a> Remove
|
||||
```js
|
||||
// jQuery
|
||||
$el.remove();
|
||||
|
||||
// Nativo
|
||||
el.parentNode.removeChild(el);
|
||||
```
|
||||
|
||||
- [3.2](#3.2) <a name='3.2'></a> Text
|
||||
|
||||
+ Obtener Texto
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.text();
|
||||
|
||||
// Nativo
|
||||
el.textContent;
|
||||
```
|
||||
|
||||
+ Establecer Texto
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.text(string);
|
||||
|
||||
// Nativo
|
||||
el.textContent = string;
|
||||
```
|
||||
|
||||
- [3.3](#3.3) <a name='3.3'></a> HTML
|
||||
|
||||
+ Obtener HTML
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.html();
|
||||
|
||||
// Nativo
|
||||
el.innerHTML;
|
||||
```
|
||||
|
||||
+ Establecer HTML
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.html(htmlString);
|
||||
|
||||
// Nativo
|
||||
el.innerHTML = htmlString;
|
||||
```
|
||||
|
||||
- [3.4](#3.4) <a name='3.4'></a> Append
|
||||
|
||||
Añadir elemento hijo después del último hijo del elemento padre
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.append("<div id='container'>hello</div>");
|
||||
|
||||
// Nativo
|
||||
el.insertAdjacentHTML("beforeend","<div id='container'>hello</div>");
|
||||
```
|
||||
|
||||
- [3.5](#3.5) <a name='3.5'></a> Prepend
|
||||
|
||||
Añadir elemento hijo después del último hijo del elemento padre
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.prepend("<div id='container'>hello</div>");
|
||||
|
||||
// Nativo
|
||||
el.insertAdjacentHTML("afterbegin","<div id='container'>hello</div>");
|
||||
```
|
||||
|
||||
- [3.6](#3.6) <a name='3.6'></a> insertBefore
|
||||
|
||||
Insertar un nuevo nodo antes del primero de los elementos seleccionados
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$newEl.insertBefore(queryString);
|
||||
|
||||
// Nativo
|
||||
const target = document.querySelector(queryString);
|
||||
target.parentNode.insertBefore(newEl, target);
|
||||
```
|
||||
|
||||
- [3.7](#3.7) <a name='3.7'></a> insertAfter
|
||||
|
||||
Insertar un nuevo nodo después de los elementos seleccionados
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$newEl.insertAfter(queryString);
|
||||
|
||||
// Nativo
|
||||
const target = document.querySelector(queryString);
|
||||
target.parentNode.insertBefore(newEl, target.nextSibling);
|
||||
```
|
||||
|
||||
**[⬆ volver al inicio](#tabla-de-contenidos)**
|
||||
|
||||
## Ajax
|
||||
|
||||
Reemplazar con [fetch](https://github.com/camsong/fetch-ie8) y [fetch-jsonp](https://github.com/camsong/fetch-jsonp)
|
||||
+[Fetch API](https://fetch.spec.whatwg.org/) es el nuevo estándar quue reemplaza a XMLHttpRequest para efectuar peticiones AJAX. Funciona en Chrome y Firefox, como también es posible usar un polyfill en otros navegadores.
|
||||
+
|
||||
+Es 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.
|
||||
**[⬆ volver al inicio](#tabla-de-contenidos)**
|
||||
|
||||
## Eventos
|
||||
|
||||
Para un reemplazo completo con namespace y delegación, utilizar https://github.com/oneuijs/oui-dom-events
|
||||
|
||||
- [5.1](#5.1) <a name='5.1'></a> Asignar un evento con "on"
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.on(eventName, eventHandler);
|
||||
|
||||
// Nativo
|
||||
el.addEventListener(eventName, eventHandler);
|
||||
```
|
||||
|
||||
- [5.2](#5.2) <a name='5.2'></a> Desasignar un evento con "off"
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.off(eventName, eventHandler);
|
||||
|
||||
// Nativo
|
||||
el.removeEventListener(eventName, eventHandler);
|
||||
```
|
||||
|
||||
- [5.3](#5.3) <a name='5.3'></a> Trigger
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(el).trigger('custom-event', {key1: 'data'});
|
||||
|
||||
// Nativo
|
||||
if (window.CustomEvent) {
|
||||
const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});
|
||||
} else {
|
||||
const event = document.createEvent('CustomEvent');
|
||||
event.initCustomEvent('custom-event', true, true, {key1: 'data'});
|
||||
}
|
||||
|
||||
el.dispatchEvent(event);
|
||||
```
|
||||
|
||||
**[⬆ volver al inicio](#tabla-de-contenidos)**
|
||||
|
||||
## Utilidades
|
||||
|
||||
- [6.1](#6.1) <a name='6.1'></a> isArray
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.isArray(range);
|
||||
|
||||
// Nativo
|
||||
Array.isArray(range);
|
||||
```
|
||||
|
||||
- [6.2](#6.2) <a name='6.2'></a> Trim
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.trim(string);
|
||||
|
||||
// Nativo
|
||||
string.trim();
|
||||
```
|
||||
|
||||
- [6.3](#6.3) <a name='6.3'></a> Object Assign
|
||||
|
||||
Utilizar polyfill para object.assign https://github.com/ljharb/object.assign
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.extend({}, defaultOpts, opts);
|
||||
|
||||
// Nativo
|
||||
Object.assign({}, defaultOpts, opts);
|
||||
```
|
||||
|
||||
- [6.4](#6.4) <a name='6.4'></a> Contains
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.contains(el, child);
|
||||
|
||||
// Nativo
|
||||
el !== child && el.contains(child);
|
||||
```
|
||||
|
||||
**[⬆ volver al inicio](#tabla-de-contenidos)**
|
||||
|
||||
## Traducción
|
||||
|
||||
* [한국어](./README.ko-KR.md)
|
||||
* [简体中文](./README.zh-CN.md)
|
||||
* [Bahasa Melayu](./README-my.md)
|
||||
* [Bahasa Indonesia](./README-id.md)
|
||||
* [Português(PT-BR)](./README.pt-BR.md)
|
||||
* [Tiếng Việt Nam](./README-vi.md)
|
||||
* [Español](./README-es.md)
|
||||
* [Русский](./README-ru.md)
|
||||
* [Türkçe](./README-tr.md)
|
||||
|
||||
## Soporte de Navegadores
|
||||
|
||||
![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)
|
||||
--- | --- | --- | --- | --- |
|
||||
Última ✔ | Última ✔ | 10+ ✔ | Última ✔ | 6.1+ ✔ |
|
||||
|
||||
# Licencia
|
||||
|
||||
MIT
|
|
@ -0,0 +1,634 @@
|
|||
## Anda tidak memerlukan jQuery
|
||||
|
||||
Dewasa ini perkembangan environment frontend sangatlah pesat, dimana banyak browser sudah mengimplementasikan DOM/BOM APIs dengan baik. Kita tidak perlu lagi belajar jQuery dari nol untuk keperluan manipulasi DOM atau events. Disaat yang sama; dengan berterimakasih kepada library frontend terkini seperti React, Angular dan Vue; Memanipulasi DOM secara langsung telah menjadi anti-pattern alias sesuatu yang tidak perlu dilakukan. 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+.
|
||||
|
||||
|
||||
## Daftar Isi
|
||||
|
||||
1. [Query Selector](#query-selector)
|
||||
1. [CSS & Style](#css-style)
|
||||
1. [DOM Manipulation](#dom-manipulation)
|
||||
1. [Ajax](#ajax)
|
||||
1. [Events](#events)
|
||||
1. [Utilities](#utilities)
|
||||
1. [Translation](#translation)
|
||||
1. [Browser Support](#browser-yang-di-support)
|
||||
|
||||
## Query Selector
|
||||
|
||||
Untuk selector-selector umum seperti class, id atau attribute, kita dapat menggunakan `document.querySelector` atau `document.querySelectorAll` sebagai pengganti. Perbedaan diantaranya adalah:
|
||||
* `document.querySelector` mengembalikan elemen pertama yang cocok
|
||||
* `document.querySelectorAll` mengembalikan semua elemen yang cocok sebagai NodeList. Hasilnya bisa dikonversikan menjadi Array `[].slice.call(document.querySelectorAll(selector) || []);`
|
||||
* Bila tidak ada hasil pengembalian 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) || []`
|
||||
|
||||
> Perhatian: `document.querySelector` dan `document.querySelectorAll` sedikit **LAMBAT**. Silahkan menggunakan `getElementById`, `document.getElementsByClassName` atau `document.getElementsByTagName` jika anda menginginkan tambahan performa.
|
||||
|
||||
- [1.0](#1.0) <a name='1.0'></a> Query by selector
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('selector');
|
||||
|
||||
// Native
|
||||
document.querySelectorAll('selector');
|
||||
```
|
||||
|
||||
- [1.1](#1.1) <a name='1.1'></a> Query by class
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('.class');
|
||||
|
||||
// Native
|
||||
document.querySelectorAll('.class');
|
||||
|
||||
// or
|
||||
document.getElementsByClassName('class');
|
||||
```
|
||||
|
||||
- [1.2](#1.2) <a name='1.2'></a> Query by id
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('#id');
|
||||
|
||||
// Native
|
||||
document.querySelector('#id');
|
||||
|
||||
// or
|
||||
document.getElementById('id');
|
||||
```
|
||||
|
||||
- [1.3](#1.3) <a name='1.3'></a> Query menggunakan attribute
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('a[target=_blank]');
|
||||
|
||||
// Native
|
||||
document.querySelectorAll('a[target=_blank]');
|
||||
```
|
||||
|
||||
- [1.4](#1.4) <a name='1.4'></a> Pencarian.
|
||||
|
||||
+ Mencari nodes
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.find('li');
|
||||
|
||||
// Native
|
||||
el.querySelectorAll('li');
|
||||
```
|
||||
|
||||
+ Mencari body
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('body');
|
||||
|
||||
// Native
|
||||
document.body;
|
||||
```
|
||||
|
||||
+ Mencari Attribute
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.attr('foo');
|
||||
|
||||
// Native
|
||||
e.getAttribute('foo');
|
||||
```
|
||||
|
||||
+ Mencari data attribute
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.data('foo');
|
||||
|
||||
// Native
|
||||
// gunakan getAttribute
|
||||
el.getAttribute('data-foo');
|
||||
// anda juga bisa menggunakan `dataset` bila anda perlu support IE 11+
|
||||
el.dataset['foo'];
|
||||
```
|
||||
|
||||
- [1.5](#1.5) <a name='1.5'></a> Elemen-elemen Sibling/Previous/Next
|
||||
|
||||
+ Elemen Sibling
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.siblings();
|
||||
|
||||
// Native
|
||||
[].filter.call(el.parentNode.children, function(child) {
|
||||
return child !== el;
|
||||
});
|
||||
```
|
||||
|
||||
+ Elemen Previous
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.prev();
|
||||
|
||||
// Native
|
||||
el.previousElementSibling;
|
||||
|
||||
```
|
||||
|
||||
+ Elemen Next
|
||||
|
||||
```js
|
||||
// next
|
||||
$el.next();
|
||||
el.nextElementSibling;
|
||||
```
|
||||
|
||||
- [1.6](#1.6) <a name='1.6'></a> Closest
|
||||
|
||||
Mengembalikan elemen pertama yang cocok dari selector yang digunakan, dengan cara mencari mulai dari elemen-sekarang sampai ke document.
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.closest(queryString);
|
||||
|
||||
// Native
|
||||
function closest(el, selector) {
|
||||
const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
|
||||
|
||||
while (el) {
|
||||
if (matchesSelector.call(el, selector)) {
|
||||
return el;
|
||||
} else {
|
||||
el = el.parentElement;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
```
|
||||
|
||||
- [1.7](#1.7) <a name='1.7'></a> Parents Until
|
||||
|
||||
Digunakan untuk mendapatkan "ancestor" dari setiap elemen yang ditemukan. Namun tidak termasuk elemen-sekarang yang didapat dari pencarian oleh selector, DOM node, atau object jQuery.
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.parentsUntil(selector, filter);
|
||||
|
||||
// Native
|
||||
function parentsUntil(el, selector, filter) {
|
||||
const result = [];
|
||||
const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
|
||||
|
||||
// match start from parent
|
||||
el = el.parentElement;
|
||||
while (el && !matchesSelector.call(el, selector)) {
|
||||
if (!filter) {
|
||||
result.push(el);
|
||||
} else {
|
||||
if (matchesSelector.call(el, filter)) {
|
||||
result.push(el);
|
||||
}
|
||||
}
|
||||
el = el.parentElement;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
```
|
||||
|
||||
- [1.8](#1.8) <a name='1.8'></a> Form
|
||||
|
||||
+ Input/Textarea
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('#my-input').val();
|
||||
|
||||
// Native
|
||||
document.querySelector('#my-input').value;
|
||||
```
|
||||
|
||||
+ Get index of e.currentTarget between `.radio`
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(e.currentTarget).index('.radio');
|
||||
|
||||
// Native
|
||||
[].indexOf.call(document.querySelectAll('.radio'), e.currentTarget);
|
||||
```
|
||||
|
||||
- [1.9](#1.9) <a name='1.9'></a> Iframe Contents
|
||||
|
||||
`$('iframe').contents()` mengembalikan `contentDocument`
|
||||
|
||||
+ Iframe contents
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$iframe.contents();
|
||||
|
||||
// Native
|
||||
iframe.contentDocument;
|
||||
```
|
||||
|
||||
+ Iframe Query
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$iframe.contents().find('.css');
|
||||
|
||||
// Native
|
||||
iframe.contentDocument.querySelectorAll('.css');
|
||||
```
|
||||
|
||||
**[⬆ back to top](#daftar-isi)**
|
||||
|
||||
## CSS Style
|
||||
|
||||
- [2.1](#2.1) <a name='2.1'></a> CSS
|
||||
|
||||
+ Get style
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.css("color");
|
||||
|
||||
// Native
|
||||
// PERHATIAN: ada bug disini, dimana fungsi ini akan mengembalikan nilai 'auto' bila nilai dari atribut style adalah 'auto'
|
||||
const win = el.ownerDocument.defaultView;
|
||||
// null artinya tidak mengembalikan pseudo styles
|
||||
win.getComputedStyle(el, null).color;
|
||||
```
|
||||
|
||||
+ Set style
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.css({ color: "#ff0011" });
|
||||
|
||||
// Native
|
||||
el.style.color = '#ff0011';
|
||||
```
|
||||
|
||||
+ Get/Set Styles
|
||||
|
||||
Mohon dicatat jika anda ingin men-set banyak style 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
|
||||
|
||||
+ Add class
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.addClass(className);
|
||||
|
||||
// Native
|
||||
el.classList.add(className);
|
||||
```
|
||||
|
||||
+ Remove class
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.removeClass(className);
|
||||
|
||||
// Native
|
||||
el.classList.remove(className);
|
||||
```
|
||||
|
||||
+ has class
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.hasClass(className);
|
||||
|
||||
// Native
|
||||
el.classList.contains(className);
|
||||
```
|
||||
|
||||
+ Toggle class
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.toggleClass(className);
|
||||
|
||||
// Native
|
||||
el.classList.toggle(className);
|
||||
```
|
||||
|
||||
- [2.2](#2.2) <a name='2.2'></a> Width & Height
|
||||
|
||||
Secara teori, width dan height identik, contohnya Height:
|
||||
|
||||
+ Window height
|
||||
|
||||
```js
|
||||
// window height
|
||||
$(window).height();
|
||||
// without scrollbar, behaves like jQuery
|
||||
window.document.documentElement.clientHeight;
|
||||
// with scrollbar
|
||||
window.innerHeight;
|
||||
```
|
||||
|
||||
+ Document height
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(document).height();
|
||||
|
||||
// Native
|
||||
document.documentElement.scrollHeight;
|
||||
```
|
||||
|
||||
+ Element height
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.height();
|
||||
|
||||
// Native
|
||||
function getHeight(el) {
|
||||
const styles = this.getComputedStyles(el);
|
||||
const height = el.offsetHeight;
|
||||
const borderTopWidth = parseFloat(styles.borderTopWidth);
|
||||
const borderBottomWidth = parseFloat(styles.borderBottomWidth);
|
||||
const paddingTop = parseFloat(styles.paddingTop);
|
||||
const paddingBottom = parseFloat(styles.paddingBottom);
|
||||
return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;
|
||||
}
|
||||
// accurate to integer(when `border-box`, it's `height`; when `content-box`, it's `height + padding + border`)
|
||||
el.clientHeight;
|
||||
// accurate to decimal(when `border-box`, it's `height`; when `content-box`, it's `height + padding + border`)
|
||||
el.getBoundingClientRect().height;
|
||||
```
|
||||
|
||||
- [2.3](#2.3) <a name='2.3'></a> Position & Offset
|
||||
|
||||
+ Position
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.position();
|
||||
|
||||
// Native
|
||||
{ left: el.offsetLeft, top: el.offsetTop }
|
||||
```
|
||||
|
||||
+ Offset
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.offset();
|
||||
|
||||
// Native
|
||||
function getOffset (el) {
|
||||
const box = el.getBoundingClientRect();
|
||||
|
||||
return {
|
||||
top: box.top + window.pageYOffset - document.documentElement.clientTop,
|
||||
left: box.left + window.pageXOffset - document.documentElement.clientLeft
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [2.4](#2.4) <a name='2.4'></a> Scroll Top
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(window).scrollTop();
|
||||
|
||||
// Native
|
||||
(document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
|
||||
```
|
||||
|
||||
**[⬆ back to top](#daftar-isi)**
|
||||
|
||||
## DOM Manipulation
|
||||
|
||||
- [3.1](#3.1) <a name='3.1'></a> Remove
|
||||
```js
|
||||
// jQuery
|
||||
$el.remove();
|
||||
|
||||
// Native
|
||||
el.parentNode.removeChild(el);
|
||||
```
|
||||
|
||||
- [3.2](#3.2) <a name='3.2'></a> Text
|
||||
|
||||
+ Get text
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.text();
|
||||
|
||||
// Native
|
||||
el.textContent;
|
||||
```
|
||||
|
||||
+ Set text
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.text(string);
|
||||
|
||||
// Native
|
||||
el.textContent = string;
|
||||
```
|
||||
|
||||
- [3.3](#3.3) <a name='3.3'></a> HTML
|
||||
|
||||
+ Get HTML
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.html();
|
||||
|
||||
// Native
|
||||
el.innerHTML;
|
||||
```
|
||||
|
||||
+ Set HTML
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.html(htmlString);
|
||||
|
||||
// Native
|
||||
el.innerHTML = htmlString;
|
||||
```
|
||||
|
||||
- [3.4](#3.4) <a name='3.4'></a> Append
|
||||
|
||||
Menambahkan elemen-anak setelah anak terakhir dari elemen-parent
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.append("<div id='container'>hello</div>");
|
||||
|
||||
// Native
|
||||
let newEl = document.createElement('div');
|
||||
newEl.setAttribute('id', 'container');
|
||||
newEl.innerHTML = 'hello';
|
||||
el.appendChild(newEl);
|
||||
```
|
||||
|
||||
- [3.5](#3.5) <a name='3.5'></a> Prepend
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.prepend("<div id='container'>hello</div>");
|
||||
|
||||
// Native
|
||||
let newEl = document.createElement('div');
|
||||
newEl.setAttribute('id', 'container');
|
||||
newEl.innerHTML = 'hello';
|
||||
el.insertBefore(newEl, el.firstChild);
|
||||
```
|
||||
|
||||
- [3.6](#3.6) <a name='3.6'></a> insertBefore
|
||||
|
||||
Memasukkan node baru sebelum elemen yang dipilih.
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$newEl.insertBefore(queryString);
|
||||
|
||||
// Native
|
||||
const target = document.querySelector(queryString);
|
||||
target.parentNode.insertBefore(newEl, target);
|
||||
```
|
||||
|
||||
- [3.7](#3.7) <a name='3.7'></a> insertAfter
|
||||
|
||||
Memasukkan node baru sesudah elemen yang dipilih.
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$newEl.insertAfter(queryString);
|
||||
|
||||
// Native
|
||||
const target = document.querySelector(queryString);
|
||||
target.parentNode.insertBefore(newEl, target.nextSibling);
|
||||
```
|
||||
|
||||
**[⬆ back to top](#daftar-isi)**
|
||||
|
||||
## Ajax
|
||||
|
||||
Gantikan dengan [fetch](https://github.com/camsong/fetch-ie8) dan [fetch-jsonp](https://github.com/camsong/fetch-jsonp)
|
||||
|
||||
**[⬆ back to top](#daftar-isi)**
|
||||
|
||||
## Events
|
||||
|
||||
Untuk penggantian secara menyeluruh dengan namespace dan delegation, rujuk ke https://github.com/oneuijs/oui-dom-events
|
||||
|
||||
- [5.1](#5.1) <a name='5.1'></a> Bind event dengan menggunakan on
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.on(eventName, eventHandler);
|
||||
|
||||
// Native
|
||||
el.addEventListener(eventName, eventHandler);
|
||||
```
|
||||
|
||||
- [5.2](#5.2) <a name='5.2'></a> Unbind event dengan menggunakan off
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.off(eventName, eventHandler);
|
||||
|
||||
// Native
|
||||
el.removeEventListener(eventName, eventHandler);
|
||||
```
|
||||
|
||||
- [5.3](#5.3) <a name='5.3'></a> Trigger
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(el).trigger('custom-event', {key1: 'data'});
|
||||
|
||||
// Native
|
||||
if (window.CustomEvent) {
|
||||
const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});
|
||||
} else {
|
||||
const event = document.createEvent('CustomEvent');
|
||||
event.initCustomEvent('custom-event', true, true, {key1: 'data'});
|
||||
}
|
||||
|
||||
el.dispatchEvent(event);
|
||||
```
|
||||
|
||||
**[⬆ back to top](#daftar-isi)**
|
||||
|
||||
## Utilities
|
||||
|
||||
- [6.1](#6.1) <a name='6.1'></a> isArray
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.isArray(range);
|
||||
|
||||
// Native
|
||||
Array.isArray(range);
|
||||
```
|
||||
|
||||
- [6.2](#6.2) <a name='6.2'></a> Trim
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.trim(string);
|
||||
|
||||
// Native
|
||||
string.trim();
|
||||
```
|
||||
|
||||
- [6.3](#6.3) <a name='6.3'></a> Object Assign
|
||||
|
||||
Extend, use object.assign polyfill https://github.com/ljharb/object.assign
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.extend({}, defaultOpts, opts);
|
||||
|
||||
// Native
|
||||
Object.assign({}, defaultOpts, opts);
|
||||
```
|
||||
|
||||
- [6.4](#6.4) <a name='6.4'></a> Contains
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.contains(el, child);
|
||||
|
||||
// Native
|
||||
el !== child && el.contains(child);
|
||||
```
|
||||
|
||||
**[⬆ back to top](#daftar-isi)**
|
||||
|
||||
## Terjemahan
|
||||
|
||||
* [한국어](./README.ko-KR.md)
|
||||
* [简体中文](./README.zh-CN.md)
|
||||
* [Bahasa Melayu](./README-my.md)
|
||||
* [Bahasa Indonesia](./README-id.md)
|
||||
* [Português(PT-BR)](./README.pt-BR.md)
|
||||
* [Tiếng Việt Nam](./README-vi.md)
|
||||
* [Русский](./README-ru.md)
|
||||
* [Türkçe](./README-tr.md)
|
||||
|
||||
## Browser yang di Support
|
||||
|
||||
![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)
|
||||
--- | --- | --- | --- | --- |
|
||||
Latest ✔ | Latest ✔ | 10+ ✔ | Latest ✔ | 6.1+ ✔ |
|
||||
|
||||
# License
|
||||
|
||||
MIT
|
|
@ -0,0 +1,651 @@
|
|||
## Non hai bisogno di jQuery
|
||||
|
||||
Il 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+.
|
||||
|
||||
## Tabella contenuti
|
||||
|
||||
1. [Query Selector](#query-selector)
|
||||
1. [CSS & Style](#css--style)
|
||||
1. [Manipolazione DOM](#manipolazione-dom)
|
||||
1. [Ajax](#ajax)
|
||||
1. [Eventi](#eventi)
|
||||
1. [Utilities](#utilities)
|
||||
1. [Alternative](#alternative)
|
||||
1. [Traduzioni](#traduzioni)
|
||||
1. [Supporto Browsers](#supporto-browsers)
|
||||
|
||||
## Query Selector
|
||||
|
||||
Al posto di comuni selettori come class, id o attributi possiamo usare `document.querySelector` o `document.querySelectorAll` per sostituzioni. La differenza risiede in:
|
||||
* `document.querySelector` restituisce il primo elemento combiaciante
|
||||
* `document.querySelectorAll` restituisce tutti gli elementi combiacianti della NodeList. Puo' essere convertito in Array usando `[].slice.call(document.querySelectorAll(selector) || []);`
|
||||
* 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) || []`
|
||||
|
||||
> 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.
|
||||
|
||||
- [1.0](#1.0) <a name='1.0'></a> Query da selettore
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('selector');
|
||||
|
||||
// Nativo
|
||||
document.querySelectorAll('selector');
|
||||
```
|
||||
|
||||
- [1.1](#1.1) <a name='1.1'></a> Query da classe
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('.class');
|
||||
|
||||
// Nativo
|
||||
document.querySelectorAll('.class');
|
||||
|
||||
// or
|
||||
document.getElementsByClassName('class');
|
||||
```
|
||||
|
||||
- [1.2](#1.2) <a name='1.2'></a> Query da id
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('#id');
|
||||
|
||||
// Nativo
|
||||
document.querySelector('#id');
|
||||
|
||||
// o
|
||||
document.getElementById('id');
|
||||
```
|
||||
|
||||
- [1.3](#1.3) <a name='1.3'></a> Query da attributo
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('a[target=_blank]');
|
||||
|
||||
// Nativo
|
||||
document.querySelectorAll('a[target=_blank]');
|
||||
```
|
||||
|
||||
- [1.4](#1.4) <a name='1.4'></a> Trovare qualcosa.
|
||||
|
||||
+ Trovare nodes
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.find('li');
|
||||
|
||||
// Nativo
|
||||
el.querySelectorAll('li');
|
||||
```
|
||||
|
||||
+ Trovare body
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('body');
|
||||
|
||||
// Nativo
|
||||
document.body;
|
||||
```
|
||||
|
||||
+ Trovare Attributi
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.attr('foo');
|
||||
|
||||
// Nativo
|
||||
e.getAttribute('foo');
|
||||
```
|
||||
|
||||
+ Trovare attributo data
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.data('foo');
|
||||
|
||||
// Nativo
|
||||
// using getAttribute
|
||||
el.getAttribute('data-foo');
|
||||
// potete usare `dataset` solo se supportate IE 11+
|
||||
el.dataset['foo'];
|
||||
```
|
||||
|
||||
- [1.5](#1.5) <a name='1.5'></a> Fratelli/Precedento/Successivo Elemento
|
||||
|
||||
+ Elementi fratelli
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.siblings();
|
||||
|
||||
// Nativo
|
||||
[].filter.call(el.parentNode.children, function(child) {
|
||||
return child !== el;
|
||||
});
|
||||
```
|
||||
|
||||
+ Elementi precedenti
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.prev();
|
||||
|
||||
// Nativo
|
||||
el.previousElementSibling;
|
||||
```
|
||||
|
||||
+ Elementi successivi
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.next();
|
||||
|
||||
// Nativo
|
||||
el.nextElementSibling;
|
||||
```
|
||||
|
||||
- [1.6](#1.6) <a name='1.6'></a> Il piu' vicino
|
||||
|
||||
Restituisce il primo elementi combiaciante il selettore fornito, attraversando dall'elemento corrente fino al document .
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.closest(queryString);
|
||||
|
||||
// Nativo - Solo ultimo, NO IE
|
||||
el.closest(selector);
|
||||
|
||||
// Nativo - IE10+
|
||||
function closest(el, selector) {
|
||||
const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
|
||||
|
||||
while (el) {
|
||||
if (matchesSelector.call(el, selector)) {
|
||||
return el;
|
||||
} else {
|
||||
el = el.parentElement;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
```
|
||||
|
||||
- [1.7](#1.7) <a name='1.7'></a> Fino a parenti
|
||||
|
||||
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.
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.parentsUntil(selector, filter);
|
||||
|
||||
// Nativo
|
||||
function parentsUntil(el, selector, filter) {
|
||||
const result = [];
|
||||
const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
|
||||
|
||||
// il match parte dal parente
|
||||
el = el.parentElement;
|
||||
while (el && !matchesSelector.call(el, selector)) {
|
||||
if (!filter) {
|
||||
result.push(el);
|
||||
} else {
|
||||
if (matchesSelector.call(el, filter)) {
|
||||
result.push(el);
|
||||
}
|
||||
}
|
||||
el = el.parentElement;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
```
|
||||
|
||||
- [1.8](#1.8) <a name='1.8'></a> Form
|
||||
|
||||
+ Input/Textarea
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('#my-input').val();
|
||||
|
||||
// Native
|
||||
document.querySelector('#my-input').value;
|
||||
```
|
||||
|
||||
+ Get index of e.currentTarget between `.radio`
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(e.currentTarget).index('.radio');
|
||||
|
||||
// Nativo
|
||||
[].indexOf.call(document.querySelectAll('.radio'), e.currentTarget);
|
||||
```
|
||||
|
||||
- [1.9](#1.9) <a name='1.9'></a> Iframe Contents
|
||||
|
||||
`$('iframe').contents()` restituisce `contentDocument` per questo specifico iframe
|
||||
|
||||
+ Iframe contenuti
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$iframe.contents();
|
||||
|
||||
// Nativo
|
||||
iframe.contentDocument;
|
||||
```
|
||||
|
||||
+ Iframe Query
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$iframe.contents().find('.css');
|
||||
|
||||
// Nativo
|
||||
iframe.contentDocument.querySelectorAll('.css');
|
||||
```
|
||||
|
||||
**[⬆ back to top](#table-of-contents)**
|
||||
|
||||
## CSS & Style
|
||||
|
||||
- [2.1](#2.1) <a name='2.1'></a> CSS
|
||||
|
||||
+ Ottenere style
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.css("color");
|
||||
|
||||
// Nativo
|
||||
// NOTA: Bug conosciuto, restituira' 'auto' se il valore di style e' 'auto'
|
||||
const win = el.ownerDocument.defaultView;
|
||||
// null significa che non restituira' lo psuedo style
|
||||
win.getComputedStyle(el, null).color;
|
||||
```
|
||||
|
||||
+ Settare style
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.css({ color: "#ff0011" });
|
||||
|
||||
// Nativo
|
||||
el.style.color = '#ff0011';
|
||||
```
|
||||
|
||||
+ Ottenere/Settare Styles
|
||||
|
||||
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.
|
||||
|
||||
|
||||
+ Aggiungere classe
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.addClass(className);
|
||||
|
||||
// Nativo
|
||||
el.classList.add(className);
|
||||
```
|
||||
|
||||
+ Rimouvere class
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.removeClass(className);
|
||||
|
||||
// Nativo
|
||||
el.classList.remove(className);
|
||||
```
|
||||
|
||||
+ has class
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.hasClass(className);
|
||||
|
||||
// Nativo
|
||||
el.classList.contains(className);
|
||||
```
|
||||
|
||||
+ Toggle class
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.toggleClass(className);
|
||||
|
||||
// Nativo
|
||||
el.classList.toggle(className);
|
||||
```
|
||||
|
||||
- [2.2](#2.2) <a name='2.2'></a> Width & Height
|
||||
|
||||
Width e Height sono teoricamente identici, prendendo Height come esempio:
|
||||
|
||||
+ Window height
|
||||
|
||||
```js
|
||||
// window height
|
||||
$(window).height();
|
||||
// senza scrollbar, si comporta comporta jQuery
|
||||
window.document.documentElement.clientHeight;
|
||||
// con scrollbar
|
||||
window.innerHeight;
|
||||
```
|
||||
|
||||
+ Document height
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(document).height();
|
||||
|
||||
// Nativo
|
||||
document.documentElement.scrollHeight;
|
||||
```
|
||||
|
||||
+ Element height
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.height();
|
||||
|
||||
// Nativo
|
||||
function getHeight(el) {
|
||||
const styles = this.getComputedStyles(el);
|
||||
const height = el.offsetHeight;
|
||||
const borderTopWidth = parseFloat(styles.borderTopWidth);
|
||||
const borderBottomWidth = parseFloat(styles.borderBottomWidth);
|
||||
const paddingTop = parseFloat(styles.paddingTop);
|
||||
const paddingBottom = parseFloat(styles.paddingBottom);
|
||||
return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;
|
||||
}
|
||||
// preciso a intero(quando `border-box`, e' `height`; quando `content-box`, e' `height + padding + border`)
|
||||
el.clientHeight;
|
||||
// preciso a decimale(quando `border-box`, e' `height`; quando `content-box`, e' `height + padding + border`)
|
||||
el.getBoundingClientRect().height;
|
||||
```
|
||||
|
||||
- [2.3](#2.3) <a name='2.3'></a> Position & Offset
|
||||
|
||||
+ Position
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.position();
|
||||
|
||||
// Nativo
|
||||
{ left: el.offsetLeft, top: el.offsetTop }
|
||||
```
|
||||
|
||||
+ Offset
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.offset();
|
||||
|
||||
// Nativo
|
||||
function getOffset (el) {
|
||||
const box = el.getBoundingClientRect();
|
||||
|
||||
return {
|
||||
top: box.top + window.pageYOffset - document.documentElement.clientTop,
|
||||
left: box.left + window.pageXOffset - document.documentElement.clientLeft
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [2.4](#2.4) <a name='2.4'></a> Scroll Top
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(window).scrollTop();
|
||||
|
||||
// Nativo
|
||||
(document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
|
||||
```
|
||||
|
||||
**[⬆ back to top](#table-of-contents)**
|
||||
|
||||
## Manipolazione DOM
|
||||
|
||||
- [3.1](#3.1) <a name='3.1'></a> Remove
|
||||
```js
|
||||
// jQuery
|
||||
$el.remove();
|
||||
|
||||
// Nativo
|
||||
el.parentNode.removeChild(el);
|
||||
```
|
||||
|
||||
- [3.2](#3.2) <a name='3.2'></a> Text
|
||||
|
||||
+ Get text
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.text();
|
||||
|
||||
// Nativo
|
||||
el.textContent;
|
||||
```
|
||||
|
||||
+ Set text
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.text(string);
|
||||
|
||||
// Nativo
|
||||
el.textContent = string;
|
||||
```
|
||||
|
||||
- [3.3](#3.3) <a name='3.3'></a> HTML
|
||||
|
||||
+ Ottenere HTML
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.html();
|
||||
|
||||
// Nativo
|
||||
el.innerHTML;
|
||||
```
|
||||
|
||||
+ Settare HTML
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.html(htmlString);
|
||||
|
||||
// Nativo
|
||||
el.innerHTML = htmlString;
|
||||
```
|
||||
|
||||
- [3.4](#3.4) <a name='3.4'></a> Append
|
||||
|
||||
appendere elemento figlio dopo l'ultimo elemento figlio del genitore
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.append("<div id='container'>hello</div>");
|
||||
|
||||
// Nativo
|
||||
el.insertAdjacentHTML("beforeend","<div id='container'>hello</div>");
|
||||
```
|
||||
|
||||
- [3.5](#3.5) <a name='3.5'></a> Prepend
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.prepend("<div id='container'>hello</div>");
|
||||
|
||||
// Nativo
|
||||
el.insertAdjacentHTML("afterbegin","<div id='container'>hello</div>");
|
||||
```
|
||||
|
||||
- [3.6](#3.6) <a name='3.6'></a> insertBefore
|
||||
|
||||
Inserire un nuovo node dopo l'elmento selezionato
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$newEl.insertBefore(queryString);
|
||||
|
||||
// Nativo
|
||||
const target = document.querySelector(queryString);
|
||||
target.parentNode.insertBefore(newEl, target);
|
||||
```
|
||||
|
||||
- [3.7](#3.7) <a name='3.7'></a> insertAfter
|
||||
|
||||
Insert a new node after the selected elements
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$newEl.insertAfter(queryString);
|
||||
|
||||
// Nativo
|
||||
const target = document.querySelector(queryString);
|
||||
target.parentNode.insertBefore(newEl, target.nextSibling);
|
||||
```
|
||||
|
||||
- [3.8](#3.8) <a name='3.8'></a> is
|
||||
|
||||
Restituisce `true` se combacia con l'elemento selezionato
|
||||
|
||||
```js
|
||||
// jQuery - Notare `is` funziona anche con `function` o `elements` non di importanza qui
|
||||
$el.is(selector);
|
||||
|
||||
// Nativo
|
||||
el.matches(selector);
|
||||
```
|
||||
|
||||
**[⬆ back to top](#table-of-contents)**
|
||||
|
||||
## Ajax
|
||||
|
||||
Sostituire con [fetch](https://github.com/camsong/fetch-ie8) and [fetch-jsonp](https://github.com/camsong/fetch-jsonp)
|
||||
|
||||
**[⬆ back to top](#table-of-contents)**
|
||||
|
||||
## Eventi
|
||||
|
||||
Per una completa sostituzione con namespace e delegation, riferire a https://github.com/oneuijs/oui-dom-events
|
||||
|
||||
- [5.1](#5.1) <a name='5.1'></a> Bind un evento con on
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.on(eventName, eventHandler);
|
||||
|
||||
// Nativo
|
||||
el.addEventListener(eventName, eventHandler);
|
||||
```
|
||||
|
||||
- [5.2](#5.2) <a name='5.2'></a> Unbind an event with off
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.off(eventName, eventHandler);
|
||||
|
||||
// Nativo
|
||||
el.removeEventListener(eventName, eventHandler);
|
||||
```
|
||||
|
||||
- [5.3](#5.3) <a name='5.3'></a> Trigger
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(el).trigger('custom-event', {key1: 'data'});
|
||||
|
||||
// Nativo
|
||||
if (window.CustomEvent) {
|
||||
const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});
|
||||
} else {
|
||||
const event = document.createEvent('CustomEvent');
|
||||
event.initCustomEvent('custom-event', true, true, {key1: 'data'});
|
||||
}
|
||||
|
||||
el.dispatchEvent(event);
|
||||
```
|
||||
|
||||
**[⬆ back to top](#table-of-contents)**
|
||||
|
||||
## Utilities
|
||||
|
||||
- [6.1](#6.1) <a name='6.1'></a> isArray
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.isArray(range);
|
||||
|
||||
// Nativo
|
||||
Array.isArray(range);
|
||||
```
|
||||
|
||||
- [6.2](#6.2) <a name='6.2'></a> Trim
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.trim(string);
|
||||
|
||||
// Nativo
|
||||
string.trim();
|
||||
```
|
||||
|
||||
- [6.3](#6.3) <a name='6.3'></a> Object Assign
|
||||
|
||||
Extend, usa object.assign polyfill https://github.com/ljharb/object.assign
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.extend({}, defaultOpts, opts);
|
||||
|
||||
// Nativo
|
||||
Object.assign({}, defaultOpts, opts);
|
||||
```
|
||||
|
||||
- [6.4](#6.4) <a name='6.4'></a> Contains
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.contains(el, child);
|
||||
|
||||
// Nativo
|
||||
el !== child && el.contains(child);
|
||||
```
|
||||
|
||||
**[⬆ back to top](#table-of-contents)**
|
||||
|
||||
## Alternative
|
||||
|
||||
* [Forse non hai bisogno di jQuery](http://youmightnotneedjquery.com/) - Esempi di come creare eventi comuni, elementi, ajax etc usando puramente javascript.
|
||||
* [npm-dom](http://github.com/npm-dom) e [webmodules](http://github.com/webmodules) - Organizzazione dove puoi trovare moduli per il DOM individuale su NPM
|
||||
|
||||
## Traduzioni
|
||||
|
||||
* [한국어](./README.ko-KR.md)
|
||||
* [简体中文](./README.zh-CN.md)
|
||||
* [Bahasa Melayu](./README-my.md)
|
||||
* [Bahasa Indonesia](./README-id.md)
|
||||
* [Português(PT-BR)](./README.pt-BR.md)
|
||||
* [Tiếng Việt Nam](./README-vi.md)
|
||||
* [Español](./README-es.md)
|
||||
* [Italiano](./README-it.md)
|
||||
* [Türkçe](./README-tr.md)
|
||||
|
||||
## Supporto Browsers
|
||||
|
||||
![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)
|
||||
--- | --- | --- | --- | --- |
|
||||
Ultimo ✔ | Ultimo ✔ | 10+ ✔ | Ultimo ✔ | 6.1+ ✔ |
|
||||
|
||||
# Licenza
|
||||
|
||||
MIT
|
|
@ -0,0 +1,615 @@
|
|||
## Anda tidak memerlukan jQuery
|
||||
|
||||
Mutakhir 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+.
|
||||
|
||||
## Isi Kandungan
|
||||
|
||||
1. [Pemilihan elemen](#pemilihan-elemen)
|
||||
1. [CSS & Penggayaan](#css-penggayaan)
|
||||
1. [Manipulasi DOM](#manipulasi-dom)
|
||||
1. [Ajax](#ajax)
|
||||
1. [Events](#events)
|
||||
1. [Utiliti](#utiliti)
|
||||
1. [Terjemahan](#terjemahan)
|
||||
1. [Browser Support](#browser-support)
|
||||
|
||||
## Pemilihan Elemen
|
||||
|
||||
Pemilihan elemen yang umum seperti class, id atau atribut, biasanya kita boleh pakai `document.querySelector` atau `document.querySelectorAll` sebagai ganti. Bezanya terletak pada
|
||||
* `document.querySelector` akan mengembalikan elemen pertama sekali yang sepadan dijumpai
|
||||
* `document.querySelectorAll` akan mengembalikan kesemua elemen yang sepadan dijumpai kedalam sebuah NodeList. Ia boleh ditukar kedalam bentuk array menggunakan `[].slice.call`
|
||||
* Sekiranya tiada elemen yang sepadan dijumpai, jQuery akan mengembalikan `[]` dimana API DOM pula akan mengembalikan `null`. Sila ambil perhatian pada Null Pointer Exception
|
||||
|
||||
> AWAS: `document.querySelector` dan `document.querySelectorAll` agak **LEMBAB** berbanding `getElementById`, `document.getElementsByClassName` atau `document.getElementsByTagName` jika anda menginginkan bonus dari segi prestasi.
|
||||
|
||||
- [1.1](#1.1) <a name='1.1'></a> Pemilihan menggunakan class
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('.css');
|
||||
|
||||
// Native
|
||||
document.querySelectorAll('.css');
|
||||
```
|
||||
|
||||
- [1.2](#1.2) <a name='1.2'></a> Pemilihan menggunakan id
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('#id');
|
||||
|
||||
// Native
|
||||
document.querySelector('#id');
|
||||
```
|
||||
|
||||
- [1.3](#1.3) <a name='1.3'></a> Pemilihan menggunakan atribut
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('a[target=_blank]');
|
||||
|
||||
// Native
|
||||
document.querySelectorAll('a[target=_blank]');
|
||||
```
|
||||
|
||||
- [1.4](#1.4) <a name='1.4'></a> Cari sth.
|
||||
|
||||
+ Find nodes
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.find('li');
|
||||
|
||||
// Native
|
||||
el.querySelectorAll('li');
|
||||
```
|
||||
|
||||
+ Cari body
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('body');
|
||||
|
||||
// Native
|
||||
document.body;
|
||||
```
|
||||
|
||||
+ Cari Attribute
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.attr('foo');
|
||||
|
||||
// Native
|
||||
e.getAttribute('foo');
|
||||
```
|
||||
|
||||
+ Cari atribut data
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.data('foo');
|
||||
|
||||
// Native
|
||||
// menggunakan getAttribute
|
||||
el.getAttribute('data-foo');
|
||||
// anda boleh juga gunakan `dataset` jika ingin pakai IE 11+
|
||||
el.dataset['foo'];
|
||||
```
|
||||
|
||||
- [1.5](#1.5) <a name='1.5'></a> Sibling/Previous/Next Elements
|
||||
|
||||
+ Sibling elements
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.siblings();
|
||||
|
||||
// Native
|
||||
[].filter.call(el.parentNode.children, function(child) {
|
||||
return child !== el;
|
||||
});
|
||||
```
|
||||
|
||||
+ Previous elements
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.prev();
|
||||
|
||||
// Native
|
||||
el.previousElementSibling;
|
||||
|
||||
```
|
||||
|
||||
+ Next elements
|
||||
|
||||
```js
|
||||
// next
|
||||
$el.next();
|
||||
el.nextElementSibling;
|
||||
```
|
||||
|
||||
- [1.6](#1.6) <a name='1.6'></a> Closest
|
||||
|
||||
Return the first matched element by provided selector, traversing from current element to document.
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.closest(queryString);
|
||||
|
||||
// Native
|
||||
function closest(el, selector) {
|
||||
const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
|
||||
|
||||
while (el) {
|
||||
if (matchesSelector.call(el, selector)) {
|
||||
return el;
|
||||
} else {
|
||||
el = el.parentElement;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
```
|
||||
|
||||
- [1.7](#1.7) <a name='1.7'></a> Parents Until
|
||||
|
||||
Get the ancestors of each element in the current set of matched elements, up to but not including the element matched by the selector, DOM node, or jQuery object.
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.parentsUntil(selector, filter);
|
||||
|
||||
// Native
|
||||
function parentsUntil(el, selector, filter) {
|
||||
const result = [];
|
||||
const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
|
||||
|
||||
// match start from parent
|
||||
el = el.parentElement;
|
||||
while (el && !matchesSelector.call(el, selector)) {
|
||||
if (!filter) {
|
||||
result.push(el);
|
||||
} else {
|
||||
if (matchesSelector.call(el, filter)) {
|
||||
result.push(el);
|
||||
}
|
||||
}
|
||||
el = el.parentElement;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
```
|
||||
|
||||
- [1.8](#1.8) <a name='1.8'></a> Form
|
||||
|
||||
+ Input/Textarea
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('#my-input').val();
|
||||
|
||||
// Native
|
||||
document.querySelector('#my-input').value;
|
||||
```
|
||||
|
||||
+ Get index of e.currentTarget between `.radio`
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(e.currentTarget).index('.radio');
|
||||
|
||||
// Native
|
||||
[].indexOf.call(document.querySelectAll('.radio'), e.currentTarget);
|
||||
```
|
||||
|
||||
- [1.9](#1.9) <a name='1.9'></a> Iframe Contents
|
||||
|
||||
`$('iframe').contents()` returns `contentDocument` for this specific iframe
|
||||
|
||||
+ Iframe contents
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$iframe.contents();
|
||||
|
||||
// Native
|
||||
iframe.contentDocument;
|
||||
```
|
||||
|
||||
+ Iframe Query
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$iframe.contents().find('.css');
|
||||
|
||||
// Native
|
||||
iframe.contentDocument.querySelectorAll('.css');
|
||||
```
|
||||
|
||||
**[⬆ back to top](#table-of-contents)**
|
||||
|
||||
## CSS & Style
|
||||
|
||||
- [2.1](#2.1) <a name='2.1'></a> CSS
|
||||
|
||||
+ Get style
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.css("color");
|
||||
|
||||
// Native
|
||||
// NOTE: Known bug, will return 'auto' if style value is 'auto'
|
||||
const win = el.ownerDocument.defaultView;
|
||||
// null means not return presudo styles
|
||||
win.getComputedStyle(el, null).color;
|
||||
```
|
||||
|
||||
+ Set style
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.css({ color: "#ff0011" });
|
||||
|
||||
// Native
|
||||
el.style.color = '#ff0011';
|
||||
```
|
||||
|
||||
+ Get/Set Styles
|
||||
|
||||
Note that if you want to set multiple styles once, you could refer to [setStyles](https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L194) method in oui-dom-utils package.
|
||||
|
||||
|
||||
+ Add class
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.addClass(className);
|
||||
|
||||
// Native
|
||||
el.classList.add(className);
|
||||
```
|
||||
|
||||
+ Remove class
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.removeClass(className);
|
||||
|
||||
// Native
|
||||
el.classList.remove(className);
|
||||
```
|
||||
|
||||
+ has class
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.hasClass(className);
|
||||
|
||||
// Native
|
||||
el.classList.contains(className);
|
||||
```
|
||||
|
||||
+ Toggle class
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.toggleClass(className);
|
||||
|
||||
// Native
|
||||
el.classList.toggle(className);
|
||||
```
|
||||
|
||||
- [2.2](#2.2) <a name='2.2'></a> Width & Height
|
||||
|
||||
Width and Height are theoretically identical, take Height as example:
|
||||
|
||||
+ Window height
|
||||
|
||||
```js
|
||||
// window height
|
||||
$(window).height();
|
||||
// without scrollbar, behaves like jQuery
|
||||
window.document.documentElement.clientHeight;
|
||||
// with scrollbar
|
||||
window.innerHeight;
|
||||
```
|
||||
|
||||
+ Document height
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(document).height();
|
||||
|
||||
// Native
|
||||
document.documentElement.scrollHeight;
|
||||
```
|
||||
|
||||
+ Element height
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.height();
|
||||
|
||||
// Native
|
||||
function getHeight(el) {
|
||||
const styles = this.getComputedStyles(el);
|
||||
const height = el.offsetHeight;
|
||||
const borderTopWidth = parseFloat(styles.borderTopWidth);
|
||||
const borderBottomWidth = parseFloat(styles.borderBottomWidth);
|
||||
const paddingTop = parseFloat(styles.paddingTop);
|
||||
const paddingBottom = parseFloat(styles.paddingBottom);
|
||||
return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;
|
||||
}
|
||||
// accurate to integer(when `border-box`, it's `height`; when `content-box`, it's `height + padding + border`)
|
||||
el.clientHeight;
|
||||
// accurate to decimal(when `border-box`, it's `height`; when `content-box`, it's `height + padding + border`)
|
||||
el.getBoundingClientRect().height;
|
||||
```
|
||||
|
||||
- [2.3](#2.3) <a name='2.3'></a> Position & Offset
|
||||
|
||||
+ Position
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.position();
|
||||
|
||||
// Native
|
||||
{ left: el.offsetLeft, top: el.offsetTop }
|
||||
```
|
||||
|
||||
+ Offset
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.offset();
|
||||
|
||||
// Native
|
||||
function getOffset (el) {
|
||||
const box = el.getBoundingClientRect();
|
||||
|
||||
return {
|
||||
top: box.top + window.pageYOffset - document.documentElement.clientTop,
|
||||
left: box.left + window.pageXOffset - document.documentElement.clientLeft
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [2.4](#2.4) <a name='2.4'></a> Scroll Top
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(window).scrollTop();
|
||||
|
||||
// Native
|
||||
(document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
|
||||
```
|
||||
|
||||
**[⬆ back to top](#table-of-contents)**
|
||||
|
||||
## DOM Manipulation
|
||||
|
||||
- [3.1](#3.1) <a name='3.1'></a> Remove
|
||||
```js
|
||||
// jQuery
|
||||
$el.remove();
|
||||
|
||||
// Native
|
||||
el.parentNode.removeChild(el);
|
||||
```
|
||||
|
||||
- [3.2](#3.2) <a name='3.2'></a> Text
|
||||
|
||||
+ Get text
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.text();
|
||||
|
||||
// Native
|
||||
el.textContent;
|
||||
```
|
||||
|
||||
+ Set text
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.text(string);
|
||||
|
||||
// Native
|
||||
el.textContent = string;
|
||||
```
|
||||
|
||||
- [3.3](#3.3) <a name='3.3'></a> HTML
|
||||
|
||||
+ Get HTML
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.html();
|
||||
|
||||
// Native
|
||||
el.innerHTML;
|
||||
```
|
||||
|
||||
+ Set HTML
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.html(htmlString);
|
||||
|
||||
// Native
|
||||
el.innerHTML = htmlString;
|
||||
```
|
||||
|
||||
- [3.4](#3.4) <a name='3.4'></a> Append
|
||||
|
||||
append child element after the last child of parent element
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.append("<div id='container'>hello</div>");
|
||||
|
||||
// Native
|
||||
let newEl = document.createElement('div');
|
||||
newEl.setAttribute('id', 'container');
|
||||
newEl.innerHTML = 'hello';
|
||||
el.appendChild(newEl);
|
||||
```
|
||||
|
||||
- [3.5](#3.5) <a name='3.5'></a> Prepend
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.prepend("<div id='container'>hello</div>");
|
||||
|
||||
// Native
|
||||
let newEl = document.createElement('div');
|
||||
newEl.setAttribute('id', 'container');
|
||||
newEl.innerHTML = 'hello';
|
||||
el.insertBefore(newEl, el.firstChild);
|
||||
```
|
||||
|
||||
- [3.6](#3.6) <a name='3.6'></a> insertBefore
|
||||
|
||||
Insert a new node before the selected elements
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$newEl.insertBefore(queryString);
|
||||
|
||||
// Native
|
||||
const target = document.querySelector(queryString);
|
||||
target.parentNode.insertBefore(newEl, target);
|
||||
```
|
||||
|
||||
- [3.7](#3.7) <a name='3.7'></a> insertAfter
|
||||
|
||||
Insert a new node after the selected elements
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$newEl.insertAfter(queryString);
|
||||
|
||||
// Native
|
||||
const target = document.querySelector(queryString);
|
||||
target.parentNode.insertBefore(newEl, target.nextSibling);
|
||||
```
|
||||
|
||||
**[⬆ back to top](#table-of-contents)**
|
||||
|
||||
## Ajax
|
||||
|
||||
Replace with [fetch](https://github.com/camsong/fetch-ie8) and [fetch-jsonp](https://github.com/camsong/fetch-jsonp)
|
||||
|
||||
**[⬆ back to top](#table-of-contents)**
|
||||
|
||||
## Events
|
||||
|
||||
For a complete replacement with namespace and delegation, refer to https://github.com/oneuijs/oui-dom-events
|
||||
|
||||
- [5.1](#5.1) <a name='5.1'></a> Bind an event with on
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.on(eventName, eventHandler);
|
||||
|
||||
// Native
|
||||
el.addEventListener(eventName, eventHandler);
|
||||
```
|
||||
|
||||
- [5.2](#5.2) <a name='5.2'></a> Unbind an event with off
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.off(eventName, eventHandler);
|
||||
|
||||
// Native
|
||||
el.removeEventListener(eventName, eventHandler);
|
||||
```
|
||||
|
||||
- [5.3](#5.3) <a name='5.3'></a> Trigger
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(el).trigger('custom-event', {key1: 'data'});
|
||||
|
||||
// Native
|
||||
if (window.CustomEvent) {
|
||||
const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});
|
||||
} else {
|
||||
const event = document.createEvent('CustomEvent');
|
||||
event.initCustomEvent('custom-event', true, true, {key1: 'data'});
|
||||
}
|
||||
|
||||
el.dispatchEvent(event);
|
||||
```
|
||||
|
||||
**[⬆ back to top](#table-of-contents)**
|
||||
|
||||
## Utility
|
||||
|
||||
- [6.1](#6.1) <a name='6.1'></a> isArray
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.isArray(range);
|
||||
|
||||
// Native
|
||||
Array.isArray(range);
|
||||
```
|
||||
|
||||
- [6.2](#6.2) <a name='6.2'></a> Trim
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.trim(string);
|
||||
|
||||
// Native
|
||||
String.trim(string);
|
||||
```
|
||||
|
||||
- [6.3](#6.3) <a name='6.3'></a> Object Assign
|
||||
|
||||
Extend, use object.assign polyfill https://github.com/ljharb/object.assign
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.extend({}, defaultOpts, opts);
|
||||
|
||||
// Native
|
||||
Object.assign({}, defaultOpts, opts);
|
||||
```
|
||||
|
||||
- [6.4](#6.4) <a name='6.4'></a> Contains
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.contains(el, child);
|
||||
|
||||
// Native
|
||||
el !== child && el.contains(child);
|
||||
```
|
||||
|
||||
**[⬆ back to top](#table-of-contents)**
|
||||
|
||||
## Terjemahan
|
||||
|
||||
* [한국어](./README.ko-KR.md)
|
||||
* [简体中文](./README.zh-CN.md)
|
||||
* [English](./README.md)
|
||||
* [Русский](./README-ru.md)
|
||||
* [Türkçe](./README-tr.md)
|
||||
|
||||
## Sokongan Pelayar
|
||||
|
||||
![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)
|
||||
--- | --- | --- | --- | --- |
|
||||
Latest ✔ | Latest ✔ | 10+ ✔ | Latest ✔ | 6.1+ ✔ |
|
||||
|
||||
# Lesen
|
||||
|
||||
MIT
|
|
@ -0,0 +1,650 @@
|
|||
## Вам не нужен jQuery
|
||||
|
||||
В наше время среда фронт энд разработки быстро развивается, современные браузеры уже реализовали значимую часть DOM/BOM APIs и это хорошо. Вам не нужно изучать jQuery с нуля для манипуляцией DOM'ом или обектами событий. В то же время, благодаря лидирующим фронт энд библиотекам, таким как React, Angular и Vue, манипуляция DOM'ом напрямую становится противо шаблонной, jQuery никогда не был менее важен. Этот проект суммирует большинство альтернатив методов jQuery в нативном исполнении с поддержкой IE 10+.
|
||||
|
||||
## Содержание
|
||||
|
||||
1. [Query Selector](#query-selector)
|
||||
1. [CSS & Style](#css--style)
|
||||
1. [Манипуляция DOM](#Манипуляции-dom)
|
||||
1. [Ajax](#ajax)
|
||||
1. [События](#События)
|
||||
1. [Утилиты](#Утилиты)
|
||||
1. [Альтернативы](#Альтернативы)
|
||||
1. [Переводы](#Переводы)
|
||||
1. [Поддержка браузеров](#Поддержка-браузеров)
|
||||
|
||||
## Query Selector
|
||||
Для часто используемых селекторов, таких как class, id или attribute мы можем использовать `document.querySelector` или `document.querySelectorAll` для замены. Разница такова:
|
||||
* `document.querySelector` возвращает первый совпавший элемент
|
||||
* `document.querySelectorAll` возвращает все совспавшие элементы как коллекцию узлов(NodeList). Его можно конвертировать в массив используя `[].slice.call(document.querySelectorAll(selector) || []);`
|
||||
* Если никакие элементы не совпадут, jQuery вернет `[]` где DOM API вернет `null`. Обратите внимание на указатель исключения Null (Null Pointer Exception). Вы так же можете использовать `||` для установки значения по умолчанию если не было найдемо совпадений `document.querySelectorAll(selector) || []`
|
||||
|
||||
> Заметка: `document.querySelector` и `document.querySelectorAll` достаточно **МЕДЛЕННЫ**, старайтесь использовать `getElementById`, `document.getElementsByClassName` или `document.getElementsByTagName` если хотите улучшить производительность.
|
||||
|
||||
- [1.0](#1.0) <a name='1.0'></a> Query by selector
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('selector');
|
||||
|
||||
// Нативно
|
||||
document.querySelectorAll('selector');
|
||||
```
|
||||
|
||||
- [1.1](#1.1) <a name='1.1'></a> Запрос по классу
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('.class');
|
||||
|
||||
// Нативно
|
||||
document.querySelectorAll('.class');
|
||||
|
||||
// или
|
||||
document.getElementsByClassName('class');
|
||||
```
|
||||
|
||||
- [1.2](#1.2) <a name='1.2'></a> Запрос по ID
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('#id');
|
||||
|
||||
// Нативно
|
||||
document.querySelector('#id');
|
||||
|
||||
// или
|
||||
document.getElementById('id');
|
||||
```
|
||||
|
||||
- [1.3](#1.3) <a name='1.3'></a> Запрос по атрибуту
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('a[target=_blank]');
|
||||
|
||||
// Нативно
|
||||
document.querySelectorAll('a[target=_blank]');
|
||||
```
|
||||
|
||||
- [1.4](#1.4) <a name='1.4'></a> Найти среди потомков
|
||||
|
||||
+ Найти nodes
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.find('li');
|
||||
|
||||
// Нативно
|
||||
el.querySelectorAll('li');
|
||||
```
|
||||
|
||||
+ Найти body
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('body');
|
||||
|
||||
// Нативно
|
||||
document.body;
|
||||
```
|
||||
|
||||
+ Найти атрибуты
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.attr('foo');
|
||||
|
||||
// Нативно
|
||||
e.getAttribute('foo');
|
||||
```
|
||||
|
||||
+ Найти data attribute
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.data('foo');
|
||||
|
||||
// Нативно
|
||||
// используя getAttribute
|
||||
el.getAttribute('data-foo');
|
||||
// также можно использовать `dataset`, если не требуется поддержка ниже IE 11.
|
||||
el.dataset['foo'];
|
||||
```
|
||||
|
||||
- [1.5](#1.5) <a name='1.5'></a> Родственные/Предыдущие/Следующие Элементы
|
||||
|
||||
+ Родственные элементы
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.siblings();
|
||||
|
||||
// Нативно
|
||||
[].filter.call(el.parentNode.children, function(child) {
|
||||
return child !== el;
|
||||
});
|
||||
```
|
||||
|
||||
+ Предыдущие элементы
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.prev();
|
||||
|
||||
// Нативно
|
||||
el.previousElementSibling;
|
||||
```
|
||||
|
||||
+ Следующие элементы
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.next();
|
||||
|
||||
// Нативно
|
||||
el.nextElementSibling;
|
||||
```
|
||||
|
||||
- [1.6](#1.6) <a name='1.6'></a> Closest
|
||||
|
||||
Возвращает первый совпавший элемент по предоставленному селектору, обоходя от текущего элементы до документа.
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.closest(queryString);
|
||||
|
||||
// Нативно - Only latest, NO IE
|
||||
el.closest(selector);
|
||||
|
||||
// Нативно - IE10+
|
||||
function closest(el, selector) {
|
||||
const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
|
||||
|
||||
while (el) {
|
||||
if (matchesSelector.call(el, selector)) {
|
||||
return el;
|
||||
} else {
|
||||
el = el.parentElement;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
```
|
||||
|
||||
- [1.7](#1.7) <a name='1.7'></a> Родители до
|
||||
|
||||
Получить родителей кажого элемента в текущем сете совпавших элементов, но не включая элемент совпавший с селектором, узел DOM'а, или объект jQuery.
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.parentsUntil(selector, filter);
|
||||
|
||||
// Нативно
|
||||
function parentsUntil(el, selector, filter) {
|
||||
const result = [];
|
||||
const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
|
||||
|
||||
// Совпадать начиная от родителя
|
||||
el = el.parentElement;
|
||||
while (el && !matchesSelector.call(el, selector)) {
|
||||
if (!filter) {
|
||||
result.push(el);
|
||||
} else {
|
||||
if (matchesSelector.call(el, filter)) {
|
||||
result.push(el);
|
||||
}
|
||||
}
|
||||
el = el.parentElement;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
```
|
||||
|
||||
- [1.8](#1.8) <a name='1.8'></a> От
|
||||
|
||||
+ Input/Textarea
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('#my-input').val();
|
||||
|
||||
// Нативно
|
||||
document.querySelector('#my-input').value;
|
||||
```
|
||||
|
||||
+ получить индекс e.currentTarget между `.radio`
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(e.currentTarget).index('.radio');
|
||||
|
||||
// Нативно
|
||||
[].indexOf.call(document.querySelectAll('.radio'), e.currentTarget);
|
||||
```
|
||||
|
||||
- [1.9](#1.9) <a name='1.9'></a> Контент Iframe
|
||||
|
||||
`$('iframe').contents()` возвращает `contentDocument` для именно этого iframe
|
||||
|
||||
+ Контент Iframe
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$iframe.contents();
|
||||
|
||||
// Нативно
|
||||
iframe.contentDocument;
|
||||
```
|
||||
|
||||
+ Iframe Query
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$iframe.contents().find('.css');
|
||||
|
||||
// Нативно
|
||||
iframe.contentDocument.querySelectorAll('.css');
|
||||
```
|
||||
|
||||
**[⬆ Наверх](#Содержание)**
|
||||
|
||||
## CSS & Style
|
||||
|
||||
- [2.1](#2.1) <a name='2.1'></a> CSS
|
||||
|
||||
+ Получить стиль
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.css("color");
|
||||
|
||||
// Нативно
|
||||
// ЗАМЕТКА: Известная ошика, возвращает 'auto' если значение стиля 'auto'
|
||||
const win = el.ownerDocument.defaultView;
|
||||
// null означает не возвращать псевдостили
|
||||
win.getComputedStyle(el, null).color;
|
||||
```
|
||||
|
||||
+ Присвоение style
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.css({ color: "#ff0011" });
|
||||
|
||||
// Нативно
|
||||
el.style.color = '#ff0011';
|
||||
```
|
||||
|
||||
+ Получение/Присвоение стилей
|
||||
|
||||
Заметьте что если вы хотите присвоить несколько стилей за раз, вы можете сослаться на [setStyles](https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L194) метод в oui-dom-utils package.
|
||||
|
||||
|
||||
+ Добавить класс
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.addClass(className);
|
||||
|
||||
// Нативно
|
||||
el.classList.add(className);
|
||||
```
|
||||
|
||||
+ Удалить class
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.removeClass(className);
|
||||
|
||||
// Нативно
|
||||
el.classList.remove(className);
|
||||
```
|
||||
|
||||
+ Имеет класс
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.hasClass(className);
|
||||
|
||||
// Нативно
|
||||
el.classList.contains(className);
|
||||
```
|
||||
|
||||
+ Переключать класс
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.toggleClass(className);
|
||||
|
||||
// Нативно
|
||||
el.classList.toggle(className);
|
||||
```
|
||||
|
||||
- [2.2](#2.2) <a name='2.2'></a> Ширина и Высота
|
||||
|
||||
Ширина и высота теоритечески идентичны, например возьмем высоту:
|
||||
|
||||
+ высота окна
|
||||
|
||||
```js
|
||||
// Высота окна
|
||||
$(window).height();
|
||||
// без скроллбара, ведет себя как jQuery
|
||||
window.document.documentElement.clientHeight;
|
||||
// вместе с скроллбаром
|
||||
window.innerHeight;
|
||||
```
|
||||
|
||||
+ высота документа
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(document).height();
|
||||
|
||||
// Нативно
|
||||
document.documentElement.scrollHeight;
|
||||
```
|
||||
|
||||
+ Высота элемента
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.height();
|
||||
|
||||
// Нативно
|
||||
function getHeight(el) {
|
||||
const styles = this.getComputedStyles(el);
|
||||
const height = el.offsetHeight;
|
||||
const borderTopWidth = parseFloat(styles.borderTopWidth);
|
||||
const borderBottomWidth = parseFloat(styles.borderBottomWidth);
|
||||
const paddingTop = parseFloat(styles.paddingTop);
|
||||
const paddingBottom = parseFloat(styles.paddingBottom);
|
||||
return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;
|
||||
}
|
||||
// С точностью до целого числа(когда `border-box`, это `height`; когда `content-box`, это `height + padding + border`)
|
||||
el.clientHeight;
|
||||
// с точностью до десятых(когда `border-box`, это `height`; когда `content-box`, это `height + padding + border`)
|
||||
el.getBoundingClientRect().height;
|
||||
```
|
||||
|
||||
- [2.3](#2.3) <a name='2.3'></a> Позиция и смещение
|
||||
|
||||
+ Позиция
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.position();
|
||||
|
||||
// Нативно
|
||||
{ left: el.offsetLeft, top: el.offsetTop }
|
||||
```
|
||||
|
||||
+ Смещение
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.offset();
|
||||
|
||||
// Нативно
|
||||
function getOffset (el) {
|
||||
const box = el.getBoundingClientRect();
|
||||
|
||||
return {
|
||||
top: box.top + window.pageYOffset - document.documentElement.clientTop,
|
||||
left: box.left + window.pageXOffset - document.documentElement.clientLeft
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [2.4](#2.4) <a name='2.4'></a> Прокрутка вверх
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(window).scrollTop();
|
||||
|
||||
// Нативно
|
||||
(document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
|
||||
```
|
||||
|
||||
**[⬆ Наверх](#Содержание)**
|
||||
|
||||
## Манипуляции DOM
|
||||
|
||||
- [3.1](#3.1) <a name='3.1'></a> Remove
|
||||
```js
|
||||
// jQuery
|
||||
$el.remove();
|
||||
|
||||
// Нативно
|
||||
el.parentNode.removeChild(el);
|
||||
```
|
||||
|
||||
- [3.2](#3.2) <a name='3.2'></a> Текст
|
||||
|
||||
+ Получить текст
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.text();
|
||||
|
||||
// Нативно
|
||||
el.textContent;
|
||||
```
|
||||
|
||||
+ Присвоить текст
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.text(string);
|
||||
|
||||
// Нативно
|
||||
el.textContent = string;
|
||||
```
|
||||
|
||||
- [3.3](#3.3) <a name='3.3'></a> HTML
|
||||
|
||||
+ Получить HTML
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.html();
|
||||
|
||||
// Нативно
|
||||
el.innerHTML;
|
||||
```
|
||||
|
||||
+ Присвоить HTML
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.html(htmlString);
|
||||
|
||||
// Нативно
|
||||
el.innerHTML = htmlString;
|
||||
```
|
||||
|
||||
- [3.4](#3.4) <a name='3.4'></a> Append
|
||||
|
||||
Добавление элемента ребенка после последнего ребенка элемента родителя
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.append("<div id='container'>hello</div>");
|
||||
|
||||
// Нативно
|
||||
el.insertAdjacentHTML("beforeend","<div id='container'>hello</div>");
|
||||
```
|
||||
|
||||
- [3.5](#3.5) <a name='3.5'></a> Prepend
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.prepend("<div id='container'>hello</div>");
|
||||
|
||||
// Нативно
|
||||
el.insertAdjacentHTML("afterbegin","<div id='container'>hello</div>");
|
||||
```
|
||||
|
||||
- [3.6](#3.6) <a name='3.6'></a> insertBefore
|
||||
|
||||
Вставка нового элемента перед выбранным элементом
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$newEl.insertBefore(queryString);
|
||||
|
||||
// Нативно
|
||||
const target = document.querySelector(queryString);
|
||||
target.parentNode.insertBefore(newEl, target);
|
||||
```
|
||||
|
||||
- [3.7](#3.7) <a name='3.7'></a> insertAfter
|
||||
|
||||
Вставка новго элемента после выбранного элемента
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$newEl.insertAfter(queryString);
|
||||
|
||||
// Нативно
|
||||
const target = document.querySelector(queryString);
|
||||
target.parentNode.insertBefore(newEl, target.nextSibling);
|
||||
```
|
||||
|
||||
- [3.8](#3.8) <a name='3.8'></a> is
|
||||
|
||||
Возвращает `true` если совпадает с селектором запроса
|
||||
|
||||
```js
|
||||
// jQuery - заметьте что `is` так же работает с `function` или `elements` которые не имют к этому отношения
|
||||
$el.is(selector);
|
||||
|
||||
// Нативно
|
||||
el.matches(selector);
|
||||
```
|
||||
|
||||
**[⬆ Наверх](#Содержание)**
|
||||
|
||||
## Ajax
|
||||
|
||||
Заменить с [fetch](https://github.com/camsong/fetch-ie8) и [fetch-jsonp](https://github.com/camsong/fetch-jsonp)
|
||||
|
||||
**[⬆ Наверх](#Содержание)**
|
||||
|
||||
## События
|
||||
|
||||
Для полной замены с пространством имен и делегация, сослаться на [oui-dom-events](https://github.com/oneuijs/oui-dom-events)
|
||||
|
||||
- [5.1](#5.1) <a name='5.1'></a> Связать событие используя on
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.on(eventName, eventHandler);
|
||||
|
||||
// Нативно
|
||||
el.addEventListener(eventName, eventHandler);
|
||||
```
|
||||
|
||||
- [5.2](#5.2) <a name='5.2'></a> Отвязать событие используя off
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.off(eventName, eventHandler);
|
||||
|
||||
// Нативно
|
||||
el.removeEventListener(eventName, eventHandler);
|
||||
```
|
||||
|
||||
- [5.3](#5.3) <a name='5.3'></a> Trigger
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(el).trigger('custom-event', {key1: 'data'});
|
||||
|
||||
// Нативно
|
||||
if (window.CustomEvent) {
|
||||
const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});
|
||||
} else {
|
||||
const event = document.createEvent('CustomEvent');
|
||||
event.initCustomEvent('custom-event', true, true, {key1: 'data'});
|
||||
}
|
||||
|
||||
el.dispatchEvent(event);
|
||||
```
|
||||
|
||||
**[⬆ Наверх](#Содержание)**
|
||||
|
||||
## Утилиты
|
||||
|
||||
- [6.1](#6.1) <a name='6.1'></a> isArray
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.isArray(range);
|
||||
|
||||
// Нативно
|
||||
Array.isArray(range);
|
||||
```
|
||||
|
||||
- [6.2](#6.2) <a name='6.2'></a> Trim
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.trim(string);
|
||||
|
||||
// Нативно
|
||||
string.trim();
|
||||
```
|
||||
|
||||
- [6.3](#6.3) <a name='6.3'></a> Назначение объекта
|
||||
|
||||
Дополнительно, используйте полифил object.assign https://github.com/ljharb/object.assign
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.extend({}, defaultOpts, opts);
|
||||
|
||||
// Нативно
|
||||
Object.assign({}, defaultOpts, opts);
|
||||
```
|
||||
|
||||
- [6.4](#6.4) <a name='6.4'></a> Contains
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.contains(el, child);
|
||||
|
||||
// Нативно
|
||||
el !== child && el.contains(child);
|
||||
```
|
||||
|
||||
**[⬆ Наверх](#Содержание)**
|
||||
|
||||
## Альтернативы
|
||||
|
||||
* [You Might Not Need jQuery](http://youmightnotneedjquery.com/) - Примеры как исполняются частые события, элементы, ajax и тд с ванильным javascript.
|
||||
* [npm-dom](http://github.com/npm-dom) и [webmodules](http://github.com/webmodules) - Отдельные DOM модули можно найти на NPM
|
||||
|
||||
## Переводы
|
||||
|
||||
* [한국어](./README.ko-KR.md)
|
||||
* [简体中文](./README.zh-CN.md)
|
||||
* [Bahasa Melayu](./README-my.md)
|
||||
* [Bahasa Indonesia](./README-id.md)
|
||||
* [Português(PT-BR)](./README.pt-BR.md)
|
||||
* [Tiếng Việt Nam](./README-vi.md)
|
||||
* [Español](./README-es.md)
|
||||
* [Русский](./README-ru.md)
|
||||
* [Türkçe](./README-tr.md)
|
||||
|
||||
## Поддержка браузеров
|
||||
|
||||
![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)
|
||||
--- | --- | --- | --- | --- |
|
||||
Latest ✔ | Latest ✔ | 10+ ✔ | Latest ✔ | 6.1+ ✔ |
|
||||
|
||||
# License
|
||||
|
||||
MIT
|
|
@ -0,0 +1,665 @@
|
|||
## jQuery'e İhtiyacınız Yok [![Build Status](https://travis-ci.org/oneuijs/You-Dont-Need-jQuery.svg)](https://travis-ci.org/oneuijs/You-Dont-Need-jQuery)
|
||||
|
||||
Ö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.
|
||||
|
||||
## İçerik Tablosu
|
||||
|
||||
1. [Sorgu seçiciler](#sorgu-seçiciler)
|
||||
1. [CSS & Stil](#css--stil)
|
||||
1. [DOM düzenleme](#dom-düzenleme)
|
||||
1. [Ajax](#ajax)
|
||||
1. [Olaylar](#olaylar)
|
||||
1. [Araçlar](#araçlar)
|
||||
1. [Alternatifler](#alternatifler)
|
||||
1. [Çeviriler](#Çeviriler)
|
||||
1. [Tarayıcı desteği](#tarayıcı-desteği)
|
||||
|
||||
## Sorgu seçiciler
|
||||
|
||||
Yaygın olan class, id ve özellik seçiciler yerine, `document.querySelector` yada `document.querySelectorAll` kullanabiliriz. Ayrıldıkları nokta:
|
||||
* `document.querySelector` ilk seçilen öğeyi döndürür
|
||||
* `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.
|
||||
* 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) || []`
|
||||
|
||||
> Uyarı: `document.querySelector` ve `document.querySelectorAll` biraz **YAVAŞ** olabilir, Daha hızlısını isterseniz, `getElementById`, `document.getElementsByClassName` yada `document.getElementsByTagName` kullanabilirsiniz.
|
||||
|
||||
- [1.0](#1.0) <a name='1.0'></a> Seçici ile sorgu
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('selector');
|
||||
|
||||
// Yerleşik
|
||||
document.querySelectorAll('selector');
|
||||
```
|
||||
|
||||
- [1.1](#1.1) <a name='1.1'></a> Sınıf ile sorgu
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('.class');
|
||||
|
||||
// Yerleşik
|
||||
document.querySelectorAll('.class');
|
||||
|
||||
// yada
|
||||
document.getElementsByClassName('class');
|
||||
```
|
||||
|
||||
- [1.2](#1.2) <a name='1.2'></a> Id ile sorgu
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('#id');
|
||||
|
||||
// Yerleşik
|
||||
document.querySelector('#id');
|
||||
|
||||
// yada
|
||||
document.getElementById('id');
|
||||
```
|
||||
|
||||
- [1.3](#1.3) <a name='1.3'></a> Özellik ile sorgu
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('a[target=_blank]');
|
||||
|
||||
// Yerleşik
|
||||
document.querySelectorAll('a[target=_blank]');
|
||||
```
|
||||
|
||||
- [1.4](#1.4) <a name='1.4'></a> Öğe erişimi
|
||||
|
||||
+ Node'a erişim
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.find('li');
|
||||
|
||||
// Yerleşik
|
||||
el.querySelectorAll('li');
|
||||
```
|
||||
|
||||
+ Body'e erişim
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('body');
|
||||
|
||||
// Yerleşik
|
||||
document.body;
|
||||
```
|
||||
|
||||
+ Özelliğe erişim
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.attr('foo');
|
||||
|
||||
// Yerleşik
|
||||
el.getAttribute('foo');
|
||||
```
|
||||
|
||||
+ Data özelliğine erişim
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.data('foo');
|
||||
|
||||
// Yerleşik
|
||||
// getAttribute kullanarak
|
||||
el.getAttribute('data-foo');
|
||||
// Eğer IE 11+ kullanıyor iseniz, `dataset` ile de erişebilirsiniz
|
||||
el.dataset['foo'];
|
||||
```
|
||||
|
||||
- [1.5](#1.5) <a name='1.5'></a> Kardeş/Önceki/Sonraki öğeler
|
||||
|
||||
+ Kardeş öğeler
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.siblings();
|
||||
|
||||
// Yerleşik
|
||||
[].filter.call(el.parentNode.children, function(child) {
|
||||
return child !== el;
|
||||
});
|
||||
```
|
||||
|
||||
+ Önceki öğeler
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.prev();
|
||||
|
||||
// Yerleşik
|
||||
el.previousElementSibling;
|
||||
```
|
||||
|
||||
+ Sonraki öğeler
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.next();
|
||||
|
||||
// Yerleşik
|
||||
el.nextElementSibling;
|
||||
```
|
||||
|
||||
- [1.6](#1.6) <a name='1.6'></a> En yakı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.
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.closest(selector);
|
||||
|
||||
// Yerleşik - Sadece en güncellerde, IE desteklemiyor
|
||||
el.closest(selector);
|
||||
|
||||
// Yerleşik - IE10+
|
||||
function closest(el, selector) {
|
||||
const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
|
||||
|
||||
while (el) {
|
||||
if (matchesSelector.call(el, selector)) {
|
||||
return el;
|
||||
} else {
|
||||
el = el.parentElement;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
```
|
||||
|
||||
- [1.7](#1.7) <a name='1.7'></a> Önceki atalar
|
||||
|
||||
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.
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.parentsUntil(selector, filter);
|
||||
|
||||
// Yerleşik
|
||||
function parentsUntil(el, selector, filter) {
|
||||
const result = [];
|
||||
const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
|
||||
|
||||
// eşleştirme, atadan başlar
|
||||
el = el.parentElement;
|
||||
while (el && !matchesSelector.call(el, selector)) {
|
||||
if (!filter) {
|
||||
result.push(el);
|
||||
} else {
|
||||
if (matchesSelector.call(el, filter)) {
|
||||
result.push(el);
|
||||
}
|
||||
}
|
||||
el = el.parentElement;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
```
|
||||
|
||||
- [1.8](#1.8) <a name='1.8'></a> Form
|
||||
|
||||
+ Input/Textarea
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('#my-input').val();
|
||||
|
||||
// Yerleşik
|
||||
document.querySelector('#my-input').value;
|
||||
```
|
||||
|
||||
+ e.currentTarget ile `.radio` arasındaki dizini verir
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(e.currentTarget).index('.radio');
|
||||
|
||||
// Yerleşik
|
||||
[].indexOf.call(document.querySelectAll('.radio'), e.currentTarget);
|
||||
```
|
||||
|
||||
- [1.9](#1.9) <a name='1.9'></a> Iframe İçeriği
|
||||
|
||||
Mevcut Iframe için `$('iframe').contents()` yerine `contentDocument` döndürür.
|
||||
|
||||
+ Iframe İçeriği
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$iframe.contents();
|
||||
|
||||
// Yerleşik
|
||||
iframe.contentDocument;
|
||||
```
|
||||
|
||||
+ Iframe seçici
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$iframe.contents().find('.css');
|
||||
|
||||
// Yerleşik
|
||||
iframe.contentDocument.querySelectorAll('.css');
|
||||
```
|
||||
|
||||
**[⬆ üste dön](#İçerik-tablosu)**
|
||||
|
||||
## CSS & Stil
|
||||
|
||||
- [2.1](#2.1) <a name='2.1'></a> CSS
|
||||
|
||||
+ Stili verir
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.css("color");
|
||||
|
||||
// Yerleşik
|
||||
// NOT: Bilinen bir hata, eğer stil değeri 'auto' ise 'auto' döndürür
|
||||
const win = el.ownerDocument.defaultView;
|
||||
// null sahte tipleri döndürmemesi için
|
||||
win.getComputedStyle(el, null).color;
|
||||
```
|
||||
|
||||
+ Stil değiştir
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.css({ color: "#ff0011" });
|
||||
|
||||
// Yerleşik
|
||||
el.style.color = '#ff0011';
|
||||
```
|
||||
|
||||
+ Stil değeri al/değiştir
|
||||
|
||||
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.
|
||||
|
||||
|
||||
+ Sınıf ekle
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.addClass(className);
|
||||
|
||||
// Yerleşik
|
||||
el.classList.add(className);
|
||||
```
|
||||
|
||||
+ Sınıf çıkart
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.removeClass(className);
|
||||
|
||||
// Yerleşik
|
||||
el.classList.remove(className);
|
||||
```
|
||||
|
||||
+ sınfı var mı?
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.hasClass(className);
|
||||
|
||||
// Yerleşik
|
||||
el.classList.contains(className);
|
||||
```
|
||||
|
||||
+ Sınfı takas et
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.toggleClass(className);
|
||||
|
||||
// Yerleşik
|
||||
el.classList.toggle(className);
|
||||
```
|
||||
|
||||
- [2.2](#2.2) <a name='2.2'></a> Genişlik ve Yükseklik
|
||||
|
||||
Genişlik ve Yükseklik teorik olarak aynı şekilde, örnek olarak Yükseklik veriliyor
|
||||
|
||||
+ Window Yüksekliği
|
||||
|
||||
```js
|
||||
// window yüksekliği
|
||||
$(window).height();
|
||||
// kaydırma çubuğu olmaksızın, jQuery ile aynı
|
||||
window.document.documentElement.clientHeight;
|
||||
// kaydırma çubuğu ile birlikte
|
||||
window.innerHeight;
|
||||
```
|
||||
|
||||
+ Document yüksekliği
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(document).height();
|
||||
|
||||
// Yerleşik
|
||||
document.documentElement.scrollHeight;
|
||||
```
|
||||
|
||||
+ Öğe yüksekliği
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.height();
|
||||
|
||||
// Yerleşik
|
||||
function getHeight(el) {
|
||||
const styles = this.getComputedStyles(el);
|
||||
const height = el.offsetHeight;
|
||||
const borderTopWidth = parseFloat(styles.borderTopWidth);
|
||||
const borderBottomWidth = parseFloat(styles.borderBottomWidth);
|
||||
const paddingTop = parseFloat(styles.paddingTop);
|
||||
const paddingBottom = parseFloat(styles.paddingBottom);
|
||||
return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;
|
||||
}
|
||||
// Tamsayı olarak daha doğru olanı(`border-box` iken, `height` esas; `content-box` ise, `height + padding + border` esas alınır)
|
||||
el.clientHeight;
|
||||
// Ondalık olarak daha doğru olanı(`border-box` iken, `height` esas; `content-box` ise, `height + padding + border` esas alınır)
|
||||
el.getBoundingClientRect().height;
|
||||
```
|
||||
|
||||
- [2.3](#2.3) <a name='2.3'></a> Pozisyon ve Ara-Açıklığı
|
||||
|
||||
+ Pozisyon
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.position();
|
||||
|
||||
// Yerleşik
|
||||
{ left: el.offsetLeft, top: el.offsetTop }
|
||||
```
|
||||
|
||||
+ Ara-Açıklığı
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.offset();
|
||||
|
||||
// Yerleşik
|
||||
function getOffset (el) {
|
||||
const box = el.getBoundingClientRect();
|
||||
|
||||
return {
|
||||
top: box.top + window.pageYOffset - document.documentElement.clientTop,
|
||||
left: box.left + window.pageXOffset - document.documentElement.clientLeft
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [2.4](#2.4) <a name='2.4'></a> Üste kaydır
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(window).scrollTop();
|
||||
|
||||
// Yerleşik
|
||||
(document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
|
||||
```
|
||||
|
||||
**[⬆ üste dön](#İçerik-tablosu)**
|
||||
|
||||
## DOM düzenleme
|
||||
|
||||
- [3.1](#3.1) <a name='3.1'></a> Çıkartma
|
||||
```js
|
||||
// jQuery
|
||||
$el.remove();
|
||||
|
||||
// Yerleşik
|
||||
el.parentNode.removeChild(el);
|
||||
```
|
||||
|
||||
- [3.2](#3.2) <a name='3.2'></a> Metin
|
||||
|
||||
+ Get text
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.text();
|
||||
|
||||
// Yerleşik
|
||||
el.textContent;
|
||||
```
|
||||
|
||||
+ Set text
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.text(string);
|
||||
|
||||
// Yerleşik
|
||||
el.textContent = string;
|
||||
```
|
||||
|
||||
- [3.3](#3.3) <a name='3.3'></a> HTML
|
||||
|
||||
+ HTML'i alma
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.html();
|
||||
|
||||
// Yerleşik
|
||||
el.innerHTML;
|
||||
```
|
||||
|
||||
+ HTML atama
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.html(htmlString);
|
||||
|
||||
// Yerleşik
|
||||
el.innerHTML = htmlString;
|
||||
```
|
||||
|
||||
- [3.4](#3.4) <a name='3.4'></a> Sona ekleme
|
||||
|
||||
Ata öğenin son çocuğundan sonra öğe ekleme
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.append("<div id='container'>hello</div>");
|
||||
|
||||
// Yerleşik
|
||||
el.insertAdjacentHTML("beforeend","<div id='container'>hello</div>");
|
||||
```
|
||||
|
||||
- [3.5](#3.5) <a name='3.5'></a> Öne ekleme
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.prepend("<div id='container'>hello</div>");
|
||||
|
||||
// Yerleşik
|
||||
el.insertAdjacentHTML("afterbegin","<div id='container'>hello</div>");
|
||||
```
|
||||
|
||||
- [3.6](#3.6) <a name='3.6'></a> Öncesine Ekleme
|
||||
|
||||
Seçili öğeden önceki yere yeni öğe ekleme
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$newEl.insertBefore(queryString);
|
||||
|
||||
// Yerleşik
|
||||
const target = document.querySelector(queryString);
|
||||
target.parentNode.insertBefore(newEl, target);
|
||||
```
|
||||
|
||||
- [3.7](#3.7) <a name='3.7'></a> Sonrasına ekleme
|
||||
|
||||
Seçili öğeden sonraki yere yeni öğe ekleme
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$newEl.insertAfter(queryString);
|
||||
|
||||
// Yerleşik
|
||||
const target = document.querySelector(queryString);
|
||||
target.parentNode.insertBefore(newEl, target.nextSibling);
|
||||
```
|
||||
|
||||
- [3.8](#3.8) <a name='3.8'></a> eşit mi?
|
||||
|
||||
Sorgu seçici ile eşleşiyor ise `true` döner
|
||||
|
||||
```js
|
||||
// jQuery için not: `is` aynı zamanda `function` veya `elements` için de geçerlidir fakat burada bir önemi bulunmuyor
|
||||
$el.is(selector);
|
||||
|
||||
// Yerleşik
|
||||
el.matches(selector);
|
||||
```
|
||||
- [3.9](#3.9) <a name='3.9'></a> Klonlama
|
||||
|
||||
Mevcut öğenin bir derin kopyasını oluşturur
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.clone();
|
||||
|
||||
// Yerleşik
|
||||
el.cloneNode();
|
||||
|
||||
// Derin kopya için, `true` parametresi kullanınız
|
||||
```
|
||||
**[⬆ üste dön](#İçerik-tablosu)**
|
||||
|
||||
## Ajax
|
||||
|
||||
[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.
|
||||
|
||||
IE9+ 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.
|
||||
|
||||
**[⬆ üste dön](#İçerik-tablosu)**
|
||||
|
||||
## Olaylar
|
||||
|
||||
Namespace ve Delegasyon ile tam olarak değiştirmek için, https://github.com/oneuijs/oui-dom-events sayfasına bakınız
|
||||
|
||||
- [5.1](#5.1) <a name='5.1'></a> on ile bir öğeye bağlama
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.on(eventName, eventHandler);
|
||||
|
||||
// Yerleşik
|
||||
el.addEventListener(eventName, eventHandler);
|
||||
```
|
||||
|
||||
- [5.2](#5.2) <a name='5.2'></a> off ile bir bağlamayı sonlandırma
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.off(eventName, eventHandler);
|
||||
|
||||
// Yerleşik
|
||||
el.removeEventListener(eventName, eventHandler);
|
||||
```
|
||||
|
||||
- [5.3](#5.3) <a name='5.3'></a> Tetikleyici
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(el).trigger('custom-event', {key1: 'data'});
|
||||
|
||||
// Yerleşik
|
||||
if (window.CustomEvent) {
|
||||
const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});
|
||||
} else {
|
||||
const event = document.createEvent('CustomEvent');
|
||||
event.initCustomEvent('custom-event', true, true, {key1: 'data'});
|
||||
}
|
||||
|
||||
el.dispatchEvent(event);
|
||||
```
|
||||
|
||||
**[⬆ üste dön](#İçerik-tablosu)**
|
||||
|
||||
## Araçlar
|
||||
|
||||
- [6.1](#6.1) <a name='6.1'></a> isArray
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.isArray(range);
|
||||
|
||||
// Yerleşik
|
||||
Array.isArray(range);
|
||||
```
|
||||
|
||||
- [6.2](#6.2) <a name='6.2'></a> Trim
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.trim(string);
|
||||
|
||||
// Yerleşik
|
||||
string.trim();
|
||||
```
|
||||
|
||||
- [6.3](#6.3) <a name='6.3'></a> Nesne atama
|
||||
|
||||
Türetmek için, object.assign polyfill'ini deneyiniz https://github.com/ljharb/object.assign
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.extend({}, defaultOpts, opts);
|
||||
|
||||
// Yerleşik
|
||||
Object.assign({}, defaultOpts, opts);
|
||||
```
|
||||
|
||||
- [6.4](#6.4) <a name='6.4'></a> İçerme
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.contains(el, child);
|
||||
|
||||
// Yerleşik
|
||||
el !== child && el.contains(child);
|
||||
```
|
||||
|
||||
**[⬆ üste dön](#İçerik-tablosu)**
|
||||
|
||||
## Alternatifler
|
||||
|
||||
* [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
|
||||
* [npm-dom](http://github.com/npm-dom) ve [webmodules](http://github.com/webmodules) - NPM için ayrı DOM modül organizasyonları
|
||||
|
||||
## Çeviriler
|
||||
|
||||
* [한국어](./README.ko-KR.md)
|
||||
* [简体中文](./README.zh-CN.md)
|
||||
* [Bahasa Melayu](./README-my.md)
|
||||
* [Bahasa Indonesia](./README-id.md)
|
||||
* [Português(PT-BR)](./README.pt-BR.md)
|
||||
* [Tiếng Việt Nam](./README-vi.md)
|
||||
* [Español](./README-es.md)
|
||||
* [Русский](./README-ru.md)
|
||||
* [Türkçe](./README-tr.md)
|
||||
|
||||
## Tarayıcı Desteği
|
||||
|
||||
![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)
|
||||
--- | --- | --- | --- | --- |
|
||||
Latest ✔ | Latest ✔ | 10+ ✔ | Latest ✔ | 6.1+ ✔ |
|
||||
|
||||
# Lisans
|
||||
|
||||
MIT
|
|
@ -0,0 +1,634 @@
|
|||
## Bạn không cần jQuery nữa đâu
|
||||
|
||||
Ngà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+
|
||||
|
||||
## Danh mục
|
||||
|
||||
1. [Query Selector](#query-selector)
|
||||
1. [CSS & Style](#css--style)
|
||||
1. [Thao tác với DOM](#thao-tác-với-dom)
|
||||
1. [Ajax](#ajax)
|
||||
1. [Events](#events)
|
||||
1. [Hàm tiện ích](#hàm-tiện-ích)
|
||||
1. [Ngôn ngữ khác](#ngôn-ngữ-khác)
|
||||
1. [Các trình duyệt hỗ trợ](#các-trình-duyệt-hỗ-trợ)
|
||||
|
||||
## Query Selector
|
||||
|
||||
Đố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ỗ:
|
||||
|
||||
* `document.querySelector` trả về element đầu tiên được tìm thấy
|
||||
* `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ế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) || []`
|
||||
|
||||
> 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.
|
||||
|
||||
- [1.0](#1.0) <a name='1.0'></a> Query bằng selector
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('selector');
|
||||
|
||||
// Native
|
||||
document.querySelectorAll('selector');
|
||||
```
|
||||
|
||||
- [1.1](#1.1) <a name='1.1'></a> Query bằng class
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('.class');
|
||||
|
||||
// Native
|
||||
document.querySelectorAll('.class');
|
||||
|
||||
// hoặc
|
||||
document.getElementsByClassName('class');
|
||||
```
|
||||
|
||||
- [1.2](#1.2) <a name='1.2'></a> Query bằng id
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('#id');
|
||||
|
||||
// Native
|
||||
document.querySelector('#id');
|
||||
|
||||
// hoặc
|
||||
document.getElementById('id');
|
||||
```
|
||||
|
||||
- [1.3](#1.3) <a name='1.3'></a> Query bằng thuộc tính
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('a[target=_blank]');
|
||||
|
||||
// Native
|
||||
document.querySelectorAll('a[target=_blank]');
|
||||
```
|
||||
|
||||
- [1.4](#1.4) <a name='1.4'></a> Tìm bất cứ gì.
|
||||
|
||||
+ Tìm node
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.find('li');
|
||||
|
||||
// Native
|
||||
el.querySelectorAll('li');
|
||||
```
|
||||
|
||||
+ Tìm body
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('body');
|
||||
|
||||
// Native
|
||||
document.body;
|
||||
```
|
||||
|
||||
+ lấy thuộc tính
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.attr('foo');
|
||||
|
||||
// Native
|
||||
e.getAttribute('foo');
|
||||
```
|
||||
|
||||
+ Lấy giá trị của thuộc tính `data`
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.data('foo');
|
||||
|
||||
// Native
|
||||
// using getAttribute
|
||||
el.getAttribute('data-foo');
|
||||
// you can also use `dataset` if only need to support IE 11+
|
||||
el.dataset['foo'];
|
||||
```
|
||||
|
||||
- [1.5](#1.5) <a name='1.5'></a> Tìm element cùng level/trước/sau
|
||||
|
||||
+ Element cùng level
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.siblings();
|
||||
|
||||
// Native
|
||||
[].filter.call(el.parentNode.children, function(child) {
|
||||
return child !== el;
|
||||
});
|
||||
```
|
||||
|
||||
+ Element ở phía trước
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.prev();
|
||||
|
||||
// Native
|
||||
el.previousElementSibling;
|
||||
|
||||
```
|
||||
|
||||
+ Element ở phía sau
|
||||
|
||||
```js
|
||||
// next
|
||||
$el.next();
|
||||
el.nextElementSibling;
|
||||
```
|
||||
|
||||
- [1.6](#1.6) <a name='1.6'></a> Element gần nhất
|
||||
|
||||
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.
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.closest(queryString);
|
||||
|
||||
// Native
|
||||
function closest(el, selector) {
|
||||
const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
|
||||
|
||||
while (el) {
|
||||
if (matchesSelector.call(el, selector)) {
|
||||
return el;
|
||||
} else {
|
||||
el = el.parentElement;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
```
|
||||
|
||||
- [1.7](#1.7) <a name='1.7'></a> Tìm parent
|
||||
|
||||
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 đó.
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.parentsUntil(selector, filter);
|
||||
|
||||
// Native
|
||||
function parentsUntil(el, selector, filter) {
|
||||
const result = [];
|
||||
const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
|
||||
|
||||
// match start from parent
|
||||
el = el.parentElement;
|
||||
while (el && !matchesSelector.call(el, selector)) {
|
||||
if (!filter) {
|
||||
result.push(el);
|
||||
} else {
|
||||
if (matchesSelector.call(el, filter)) {
|
||||
result.push(el);
|
||||
}
|
||||
}
|
||||
el = el.parentElement;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
```
|
||||
|
||||
- [1.8](#1.8) <a name='1.8'></a> Form
|
||||
|
||||
+ Input/Textarea
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('#my-input').val();
|
||||
|
||||
// Native
|
||||
document.querySelector('#my-input').value;
|
||||
```
|
||||
|
||||
+ Lấy index của e.currentTarget trong danh sách các element khớp với selector `.radio`
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(e.currentTarget).index('.radio');
|
||||
|
||||
// Native
|
||||
[].indexOf.call(document.querySelectAll('.radio'), e.currentTarget);
|
||||
```
|
||||
|
||||
- [1.9](#1.9) <a name='1.9'></a> Nội dung Iframe
|
||||
|
||||
`$('iframe').contents()` trả về thuộc tính `contentDocument` của iframe được tìm thấy
|
||||
|
||||
+ Nọi dung iframe
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$iframe.contents();
|
||||
|
||||
// Native
|
||||
iframe.contentDocument;
|
||||
```
|
||||
|
||||
+ Query Iframe
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$iframe.contents().find('.css');
|
||||
|
||||
// Native
|
||||
iframe.contentDocument.querySelectorAll('.css');
|
||||
```
|
||||
|
||||
**[⬆ Trở về đầu](#danh-mục)**
|
||||
|
||||
## CSS & Style
|
||||
|
||||
- [2.1](#2.1) <a name='2.1'></a> CSS
|
||||
|
||||
+ Lấy style
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.css("color");
|
||||
|
||||
// Native
|
||||
// NOTE: Bug đã được biết, sẽ trả về 'auto' nếu giá trị của style là 'auto'
|
||||
const win = el.ownerDocument.defaultView;
|
||||
// null means not return presudo styles
|
||||
win.getComputedStyle(el, null).color;
|
||||
```
|
||||
|
||||
+ Đặt style
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.css({ color: "#ff0011" });
|
||||
|
||||
// Native
|
||||
el.style.color = '#ff0011';
|
||||
```
|
||||
|
||||
+ Lấy/Đặt Nhiều style
|
||||
|
||||
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.
|
||||
|
||||
|
||||
+ Thêm class và element
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.addClass(className);
|
||||
|
||||
// Native
|
||||
el.classList.add(className);
|
||||
```
|
||||
|
||||
+ Loại bỏ class class ra khỏi element
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.removeClass(className);
|
||||
|
||||
// Native
|
||||
el.classList.remove(className);
|
||||
```
|
||||
|
||||
+ Kiểm tra xem element có class nào đó hay không
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.hasClass(className);
|
||||
|
||||
// Native
|
||||
el.classList.contains(className);
|
||||
```
|
||||
|
||||
+ Toggle class
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.toggleClass(className);
|
||||
|
||||
// Native
|
||||
el.classList.toggle(className);
|
||||
```
|
||||
|
||||
- [2.2](#2.2) <a name='2.2'></a> Chiều rộng, chiều cao
|
||||
|
||||
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:
|
||||
|
||||
+ Chiều rộng của window
|
||||
|
||||
```js
|
||||
// window height
|
||||
$(window).height();
|
||||
// trừ đi scrollbar
|
||||
window.document.documentElement.clientHeight;
|
||||
// Tính luôn scrollbar
|
||||
window.innerHeight;
|
||||
```
|
||||
|
||||
+ Chiều cao của Document
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(document).height();
|
||||
|
||||
// Native
|
||||
document.documentElement.scrollHeight;
|
||||
```
|
||||
|
||||
+ Chiều cao của element
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.height();
|
||||
|
||||
// Native
|
||||
function getHeight(el) {
|
||||
const styles = this.getComputedStyles(el);
|
||||
const height = el.offsetHeight;
|
||||
const borderTopWidth = parseFloat(styles.borderTopWidth);
|
||||
const borderBottomWidth = parseFloat(styles.borderBottomWidth);
|
||||
const paddingTop = parseFloat(styles.paddingTop);
|
||||
const paddingBottom = parseFloat(styles.paddingBottom);
|
||||
return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;
|
||||
}
|
||||
// chính xác tới số nguyên(khi có thuộc tính `box-sizing` là `border-box`, nó là `height`; khi box-sizing là `content-box`, nó là `height + padding + border`)
|
||||
el.clientHeight;
|
||||
// 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`)
|
||||
el.getBoundingClientRect().height;
|
||||
```
|
||||
|
||||
- [2.3](#2.3) <a name='2.3'></a> Position & Offset
|
||||
|
||||
+ Position
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.position();
|
||||
|
||||
// Native
|
||||
{ left: el.offsetLeft, top: el.offsetTop }
|
||||
```
|
||||
|
||||
+ Offset
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.offset();
|
||||
|
||||
// Native
|
||||
function getOffset (el) {
|
||||
const box = el.getBoundingClientRect();
|
||||
|
||||
return {
|
||||
top: box.top + window.pageYOffset - document.documentElement.clientTop,
|
||||
left: box.left + window.pageXOffset - document.documentElement.clientLeft
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [2.4](#2.4) <a name='2.4'></a> Scroll Top
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(window).scrollTop();
|
||||
|
||||
// Native
|
||||
(document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
|
||||
```
|
||||
|
||||
**[⬆ Trở về đầu](#danh-mục)**
|
||||
|
||||
## Thao tác với DOM
|
||||
|
||||
- [3.1](#3.1) <a name='3.1'></a> Loại bỏ
|
||||
```js
|
||||
// jQuery
|
||||
$el.remove();
|
||||
|
||||
// Native
|
||||
el.parentNode.removeChild(el);
|
||||
```
|
||||
|
||||
- [3.2](#3.2) <a name='3.2'></a> Text
|
||||
|
||||
+ Lấy text
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.text();
|
||||
|
||||
// Native
|
||||
el.textContent;
|
||||
```
|
||||
|
||||
+ Đặt giá trị text
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.text(string);
|
||||
|
||||
// Native
|
||||
el.textContent = string;
|
||||
```
|
||||
|
||||
- [3.3](#3.3) <a name='3.3'></a> HTML
|
||||
|
||||
+ Lấy HTML
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.html();
|
||||
|
||||
// Native
|
||||
el.innerHTML;
|
||||
```
|
||||
|
||||
+ Đặt giá trị HTML
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.html(htmlString);
|
||||
|
||||
// Native
|
||||
el.innerHTML = htmlString;
|
||||
```
|
||||
|
||||
- [3.4](#3.4) <a name='3.4'></a> Append
|
||||
|
||||
append một element sau element con cuối cùng của element cha
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.append("<div id='container'>hello</div>");
|
||||
|
||||
// Native
|
||||
let newEl = document.createElement('div');
|
||||
newEl.setAttribute('id', 'container');
|
||||
newEl.innerHTML = 'hello';
|
||||
el.appendChild(newEl);
|
||||
```
|
||||
|
||||
- [3.5](#3.5) <a name='3.5'></a> Prepend
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.prepend("<div id='container'>hello</div>");
|
||||
|
||||
// Native
|
||||
let newEl = document.createElement('div');
|
||||
newEl.setAttribute('id', 'container');
|
||||
newEl.innerHTML = 'hello';
|
||||
el.insertBefore(newEl, el.firstChild);
|
||||
```
|
||||
|
||||
- [3.6](#3.6) <a name='3.6'></a> insertBefore
|
||||
|
||||
Chèn một node vào trước element được query.
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$newEl.insertBefore(queryString);
|
||||
|
||||
// Native
|
||||
const target = document.querySelector(queryString);
|
||||
target.parentNode.insertBefore(newEl, target);
|
||||
```
|
||||
|
||||
- [3.7](#3.7) <a name='3.7'></a> insertAfter
|
||||
|
||||
Chèn node vào sau element được query
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$newEl.insertAfter(queryString);
|
||||
|
||||
// Native
|
||||
const target = document.querySelector(queryString);
|
||||
target.parentNode.insertBefore(newEl, target.nextSibling);
|
||||
```
|
||||
|
||||
**[⬆ Trở về đầu](#danh-mục)**
|
||||
|
||||
## Ajax
|
||||
|
||||
Thay thế bằng [fetch](https://github.com/camsong/fetch-ie8) và [fetch-jsonp](https://github.com/camsong/fetch-jsonp)
|
||||
|
||||
**[⬆ Trở về đầu](#danh-mục)**
|
||||
|
||||
## Events
|
||||
|
||||
Để có một sự thay thế đầy đủ nhất, bạn nên sử dụng https://github.com/oneuijs/oui-dom-events
|
||||
|
||||
- [5.1](#5.1) <a name='5.1'></a> Bind event bằng on
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.on(eventName, eventHandler);
|
||||
|
||||
// Native
|
||||
el.addEventListener(eventName, eventHandler);
|
||||
```
|
||||
|
||||
- [5.2](#5.2) <a name='5.2'></a> Unbind event bằng off
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.off(eventName, eventHandler);
|
||||
|
||||
// Native
|
||||
el.removeEventListener(eventName, eventHandler);
|
||||
```
|
||||
|
||||
- [5.3](#5.3) <a name='5.3'></a> Trigger
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(el).trigger('custom-event', {key1: 'data'});
|
||||
|
||||
// Native
|
||||
if (window.CustomEvent) {
|
||||
const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});
|
||||
} else {
|
||||
const event = document.createEvent('CustomEvent');
|
||||
event.initCustomEvent('custom-event', true, true, {key1: 'data'});
|
||||
}
|
||||
|
||||
el.dispatchEvent(event);
|
||||
```
|
||||
|
||||
**[⬆ Trở về đầu](#danh-mục)**
|
||||
|
||||
## Hàm tiện ích
|
||||
|
||||
- [6.1](#6.1) <a name='6.1'></a> isArray
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.isArray(range);
|
||||
|
||||
// Native
|
||||
Array.isArray(range);
|
||||
```
|
||||
|
||||
- [6.2](#6.2) <a name='6.2'></a> Trim
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.trim(string);
|
||||
|
||||
// Native
|
||||
string.trim();
|
||||
```
|
||||
|
||||
- [6.3](#6.3) <a name='6.3'></a> Object Assign
|
||||
|
||||
Mở rộng, sử dụng object.assign https://github.com/ljharb/object.assign
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.extend({}, defaultOpts, opts);
|
||||
|
||||
// Native
|
||||
Object.assign({}, defaultOpts, opts);
|
||||
```
|
||||
|
||||
- [6.4](#6.4) <a name='6.4'></a> Contains
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.contains(el, child);
|
||||
|
||||
// Native
|
||||
el !== child && el.contains(child);
|
||||
```
|
||||
|
||||
**[⬆ Trở về đầu](#danh-mục)**
|
||||
|
||||
## Ngôn ngữ khác
|
||||
|
||||
* [한국어](./README.ko-KR.md)
|
||||
* [简体中文](./README.zh-CN.md)
|
||||
* [Bahasa Melayu](./README-my.md)
|
||||
* [Português(PT-BR)](./README.pt-BR.md)
|
||||
* [Tiếng Việt Nam](./README-vi.md)
|
||||
* [Русский](./README-ru.md)
|
||||
* [Türkçe](./README-tr.md)
|
||||
|
||||
## Các trình duyệt hỗ trợ
|
||||
|
||||
![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)
|
||||
--- | --- | --- | --- | --- |
|
||||
Latest ✔ | Latest ✔ | 10+ ✔ | Latest ✔ | 6.1+ ✔ |
|
||||
|
||||
# Giấy phép
|
||||
|
||||
MIT
|
709
spec/fixtures/repo-with-submodules/You-Dont-Need-jQuery/README.ko-KR.md
поставляемый
Normal file
709
spec/fixtures/repo-with-submodules/You-Dont-Need-jQuery/README.ko-KR.md
поставляемый
Normal file
|
@ -0,0 +1,709 @@
|
|||
## You Don't Need jQuery
|
||||
|
||||
오늘날 프론트엔드 개발 환경은 급격히 진화하고 있고, 모던 브라우저들은 이미 충분히 많은 DOM/BOM API들을 구현했습니다. 우리는 jQuery를 DOM 처리나 이벤트를 위해 처음부터 배울 필요가 없습니다. React, Angular, Vue같은 프론트엔드 라이브러리들이 주도권을 차지하는 동안 DOM을 바로 처리하는 것은 안티패턴이 되었고, jQuery의 중요성은 줄어들었습니다. 이 프로젝트는 대부분의 jQuery 메소드의 대안을 IE 10+ 이상을 지원하는 네이티브 구현으로 소개합니다.
|
||||
|
||||
## 목차
|
||||
|
||||
1. [Query Selector](#query-selector)
|
||||
1. [CSS & Style](#css--style)
|
||||
1. [DOM 조작](#dom-조작)
|
||||
1. [Ajax](#ajax)
|
||||
1. [이벤트](#이벤트)
|
||||
1. [유틸리티](#유틸리티)
|
||||
1. [대안방법](#대안방법)
|
||||
1. [번역](#번역)
|
||||
1. [브라우저 지원](#브라우저-지원)
|
||||
|
||||
## Query Selector
|
||||
|
||||
평범한 class, id, attribute같은 selecotor는 `document.querySelector`나 `document.querySelectorAll`으로 대체할 수 있습니다.
|
||||
* `document.querySelector`는 처음 매칭된 엘리먼트를 반환합니다.
|
||||
* `document.querySelectorAll`는 모든 매칭된 엘리먼트를 NodeList로 반환합니다. `[].slice.call`을 사용해서 Array로 변환할 수 있습니다.
|
||||
* 만약 매칭된 엘리멘트가 없으면 jQuery는 `[]` 를 반환하지만 DOM API는 `null`을 반환합니다. Null Pointer Exception에 주의하세요.
|
||||
|
||||
> 안내: `document.querySelector`와 `document.querySelectorAll`는 꽤 **느립니다**, `getElementById`나 `document.getElementsByClassName`, `document.getElementsByTagName`를 사용하면 퍼포먼스가 향상을 기대할 수 있습니다.
|
||||
|
||||
- [1.0](#1.0) <a name='1.0'></a> selector로 찾기
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('selector');
|
||||
|
||||
// Native
|
||||
document.querySelectorAll('selector');
|
||||
```
|
||||
|
||||
- [1.1](#1.1) <a name='1.1'></a> class로 찾기
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('.class');
|
||||
|
||||
// Native
|
||||
document.querySelectorAll('.class');
|
||||
|
||||
// or
|
||||
document.getElementsByClassName('class');
|
||||
```
|
||||
|
||||
- [1.2](#1.2) <a name='1.2'></a> id로 찾기
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('#id');
|
||||
|
||||
// Native
|
||||
document.querySelector('#id');
|
||||
|
||||
// or
|
||||
document.getElementById('id');
|
||||
```
|
||||
|
||||
- [1.3](#1.3) <a name='1.3'></a> 속성(attribute)으로 찾기
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('a[target=_blank]');
|
||||
|
||||
// Native
|
||||
document.querySelectorAll('a[target=_blank]');
|
||||
```
|
||||
|
||||
- [1.4](#1.4) <a name='1.4'></a> 자식에서 찾기
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.find('li');
|
||||
|
||||
// Native
|
||||
el.querySelectorAll('li');
|
||||
```
|
||||
|
||||
- [1.5](#1.5) <a name='1.5'></a> 형제/이전/다음 엘리먼트 찾기
|
||||
|
||||
+ 형제 엘리먼트
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.siblings();
|
||||
|
||||
// Native
|
||||
[].filter.call(el.parentNode.children, function(child) {
|
||||
return child !== el;
|
||||
});
|
||||
```
|
||||
|
||||
+ 이전 엘리먼트
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.prev();
|
||||
|
||||
// Native
|
||||
el.previousElementSibling;
|
||||
```
|
||||
|
||||
+ 다음 엘리먼트
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.next();
|
||||
|
||||
// Native
|
||||
el.nextElementSibling;
|
||||
```
|
||||
|
||||
- [1.6](#1.6) <a name='1.6'></a> Closest
|
||||
|
||||
현재 엘리먼트부터 document로 이동하면서 주어진 셀렉터와 일치하는 가장 가까운 엘리먼트를 반환합니다.
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.closest(selector);
|
||||
|
||||
// Native - 최신 브라우저만, IE는 미지원
|
||||
el.closest(selector);
|
||||
|
||||
// Native - IE10 이상
|
||||
function closest(el, selector) {
|
||||
const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
|
||||
|
||||
while (el) {
|
||||
if (matchesSelector.call(el, selector)) {
|
||||
return el;
|
||||
} else {
|
||||
el = el.parentElement;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
```
|
||||
|
||||
- [1.7](#1.7) <a name='1.7'></a> Parents Until
|
||||
|
||||
주어진 셀렉터에 매칭되는 엘리먼트를 찾기까지 부모 태그들을 위로 올라가며 탐색하여 저장해두었다가 DOM 노드 또는 jQuery object로 반환합니다.
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.parentsUntil(selector, filter);
|
||||
|
||||
// Native
|
||||
function parentsUntil(el, selector, filter) {
|
||||
const result = [];
|
||||
const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
|
||||
|
||||
// match start from parent
|
||||
el = el.parentElement;
|
||||
while (el && !matchesSelector.call(el, selector)) {
|
||||
if (!filter) {
|
||||
result.push(el);
|
||||
} else {
|
||||
if (matchesSelector.call(el, filter)) {
|
||||
result.push(el);
|
||||
}
|
||||
}
|
||||
el = el.parentElement;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
```
|
||||
|
||||
- [1.8](#1.8) <a name='1.8'></a> Form
|
||||
|
||||
+ Input/Textarea
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('#my-input').val();
|
||||
|
||||
// Native
|
||||
document.querySelector('#my-input').value;
|
||||
```
|
||||
|
||||
+ e.currentTarget이 `.radio`의 몇번째인지 구하기
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(e.currentTarget).index('.radio');
|
||||
|
||||
// Native
|
||||
[].indexOf.call(document.querySelectAll('.radio'), e.currentTarget);
|
||||
```
|
||||
|
||||
- [1.9](#1.9) <a name='1.9'></a> Iframe Contents
|
||||
|
||||
`$('iframe').contents()`는 iframe에 한정해서 `contentDocument`를 반환합니다.
|
||||
|
||||
+ Iframe contents
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$iframe.contents();
|
||||
|
||||
// Native
|
||||
iframe.contentDocument;
|
||||
```
|
||||
|
||||
+ Iframe에서 찾기
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$iframe.contents().find('.css');
|
||||
|
||||
// Native
|
||||
iframe.contentDocument.querySelectorAll('.css');
|
||||
```
|
||||
|
||||
- [1.10](#1.10) <a name='1.10'></a> body 얻기
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('body');
|
||||
|
||||
// Native
|
||||
document.body;
|
||||
```
|
||||
|
||||
- [1.11](#1.11) <a name='1.11'></a> 속성 얻기 및 설정
|
||||
|
||||
+ 속성 얻기
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.attr('foo');
|
||||
|
||||
// Native
|
||||
el.getAttribute('foo');
|
||||
```
|
||||
+ 속성 설정하기
|
||||
|
||||
```js
|
||||
// jQuery, DOM 변형 없이 메모리에서 작동됩니다.
|
||||
$el.attr('foo', 'bar');
|
||||
|
||||
// Native
|
||||
el.setAttribute('foo', 'bar');
|
||||
```
|
||||
|
||||
+ `data-` 속성 얻기
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.data('foo');
|
||||
|
||||
// Native (`getAttribute` 사용)
|
||||
el.getAttribute('data-foo');
|
||||
// Native (IE 11 이상의 지원만 필요하다면 `dataset`을 사용)
|
||||
el.dataset['foo'];
|
||||
```
|
||||
|
||||
**[⬆ 목차로 돌아가기](#목차)**
|
||||
|
||||
## CSS & Style
|
||||
|
||||
- [2.1](#2.1) <a name='2.1'></a> CSS
|
||||
|
||||
+ style값 얻기
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.css("color");
|
||||
|
||||
// Native
|
||||
// NOTE: 알려진 버그로, style값이 'auto'이면 'auto'를 반환합니다.
|
||||
const win = el.ownerDocument.defaultView;
|
||||
// null은 가상 스타일은 반환하지 않음을 의미합니다.
|
||||
win.getComputedStyle(el, null).color;
|
||||
```
|
||||
|
||||
+ style값 설정하기
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.css({ color: "#ff0011" });
|
||||
|
||||
// Native
|
||||
el.style.color = '#ff0011';
|
||||
```
|
||||
|
||||
+ Style값들을 동시에 얻거나 설정하기
|
||||
|
||||
만약 한번에 여러 style값을 바꾸고 싶다면 oui-dom-utils 패키지의 [setStyles](https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L194)를 사용해보세요.
|
||||
|
||||
|
||||
+ class 추가하기
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.addClass(className);
|
||||
|
||||
// Native
|
||||
el.classList.add(className);
|
||||
```
|
||||
|
||||
+ class 제거하기
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.removeClass(className);
|
||||
|
||||
// Native
|
||||
el.classList.remove(className);
|
||||
```
|
||||
|
||||
+ class를 포함하고 있는지 검사하기
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.hasClass(className);
|
||||
|
||||
// Native
|
||||
el.classList.contains(className);
|
||||
```
|
||||
|
||||
+ class 토글하기
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.toggleClass(className);
|
||||
|
||||
// Native
|
||||
el.classList.toggle(className);
|
||||
```
|
||||
|
||||
- [2.2](#2.2) <a name='2.2'></a> 폭과 높이
|
||||
|
||||
폭과 높이는 이론상 동일합니다. 높이로 예를 들겠습니다.
|
||||
|
||||
+ Window의 높이
|
||||
|
||||
```js
|
||||
// window 높이
|
||||
$(window).height();
|
||||
// jQuery처럼 스크롤바를 제외하기
|
||||
window.document.documentElement.clientHeight;
|
||||
// 스크롤바 포함
|
||||
window.innerHeight;
|
||||
```
|
||||
|
||||
+ 문서 높이
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(document).height();
|
||||
|
||||
// Native
|
||||
document.documentElement.scrollHeight;
|
||||
```
|
||||
|
||||
+ Element 높이
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.height();
|
||||
|
||||
// Native
|
||||
function getHeight(el) {
|
||||
const styles = this.getComputedStyles(el);
|
||||
const height = el.offsetHeight;
|
||||
const borderTopWidth = parseFloat(styles.borderTopWidth);
|
||||
const borderBottomWidth = parseFloat(styles.borderBottomWidth);
|
||||
const paddingTop = parseFloat(styles.paddingTop);
|
||||
const paddingBottom = parseFloat(styles.paddingBottom);
|
||||
return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;
|
||||
}
|
||||
// 정수로 정확하게(`border-box`일 때 이 값은 `height`이고, `content-box`일 때, 이 값은 `height + padding + border`)
|
||||
el.clientHeight;
|
||||
// 실수로 정확하게(`border-box`일 때 이 값은 `height`이고, `content-box`일 때, 이 값은 `height + padding + border`)
|
||||
el.getBoundingClientRect().height;
|
||||
```
|
||||
|
||||
- [2.3](#2.3) <a name='2.3'></a> Position & Offset
|
||||
|
||||
+ Position
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.position();
|
||||
|
||||
// Native
|
||||
{ left: el.offsetLeft, top: el.offsetTop }
|
||||
```
|
||||
|
||||
+ Offset
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.offset();
|
||||
|
||||
// Native
|
||||
function getOffset (el) {
|
||||
const box = el.getBoundingClientRect();
|
||||
|
||||
return {
|
||||
top: box.top + window.pageYOffset - document.documentElement.clientTop,
|
||||
left: box.left + window.pageXOffset - document.documentElement.clientLeft
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [2.4](#2.4) <a name='2.4'></a> Scroll Top
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(window).scrollTop();
|
||||
|
||||
// Native
|
||||
(document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
|
||||
```
|
||||
|
||||
**[⬆ 목차로 돌아가기](#목차)**
|
||||
|
||||
## DOM 조작
|
||||
|
||||
- [3.1](#3.1) <a name='3.1'></a> 제거
|
||||
```js
|
||||
// jQuery
|
||||
$el.remove();
|
||||
|
||||
// Native
|
||||
el.parentNode.removeChild(el);
|
||||
```
|
||||
|
||||
- [3.2](#3.2) <a name='3.2'></a> Text
|
||||
|
||||
+ text 가져오기
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.text();
|
||||
|
||||
// Native
|
||||
el.textContent;
|
||||
```
|
||||
|
||||
+ text 설정하기
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.text(string);
|
||||
|
||||
// Native
|
||||
el.textContent = string;
|
||||
```
|
||||
|
||||
- [3.3](#3.3) <a name='3.3'></a> HTML
|
||||
|
||||
+ HTML 가져오기
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.html();
|
||||
|
||||
// Native
|
||||
el.innerHTML;
|
||||
```
|
||||
|
||||
+ HTML 설정하기
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.html(htmlString);
|
||||
|
||||
// Native
|
||||
el.innerHTML = htmlString;
|
||||
```
|
||||
|
||||
- [3.4](#3.4) <a name='3.4'></a> 해당 엘리먼트의 자식들 뒤에 넣기(Append)
|
||||
|
||||
부모 엘리먼트의 마지막 자식으로 엘리먼트를 추가합니다.
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.append("<div id='container'>hello</div>");
|
||||
|
||||
// Native
|
||||
el.insertAdjacentHTML("beforeend","<div id='container'>hello</div>");
|
||||
```
|
||||
|
||||
- [3.5](#3.5) <a name='3.5'></a> 해당 엘리먼트의 자식들 앞에 넣기(Prepend)
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.prepend("<div id='container'>hello</div>");
|
||||
|
||||
// Native
|
||||
el.insertAdjacentHTML("afterbegin","<div id='container'>hello</div>");
|
||||
```
|
||||
|
||||
- [3.6](#3.6) <a name='3.6'></a> 해당 엘리먼트 앞에 넣기(insertBefore)
|
||||
|
||||
새 노드를 선택한 엘리먼트 앞에 넣습니다.
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$newEl.insertBefore(queryString);
|
||||
|
||||
// Native
|
||||
const target = document.querySelector(queryString);
|
||||
target.parentNode.insertBefore(newEl, target);
|
||||
```
|
||||
|
||||
- [3.7](#3.7) <a name='3.7'></a> 해당 엘리먼트 뒤에 넣기(insertAfter)
|
||||
|
||||
새 노드를 선택한 엘리먼트 뒤에 넣습니다.
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$newEl.insertAfter(queryString);
|
||||
|
||||
// Native
|
||||
const target = document.querySelector(queryString);
|
||||
target.parentNode.insertBefore(newEl, target.nextSibling);
|
||||
```
|
||||
- [3.8](#3.8) <a name='3.8'></a> is
|
||||
|
||||
query selector와 일치하면 `true` 를 반환합니다.
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.is(selector);
|
||||
|
||||
// Native
|
||||
el.matches(selector);
|
||||
```
|
||||
|
||||
- [3.9](#3.9) <a name='3.9'></a> clone
|
||||
|
||||
엘리먼트의 복제본을 만듭니다.
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.clone();
|
||||
|
||||
// Native
|
||||
el.cloneNode();
|
||||
|
||||
// Deep clone은 파라미터를 `true` 로 설정하세요.
|
||||
```
|
||||
|
||||
- [3.10](#3.10) <a name='3.10'></a> empty
|
||||
|
||||
모든 자식 노드를 제거합니다.
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.empty();
|
||||
|
||||
// Native
|
||||
el.innerHTML = '';
|
||||
```
|
||||
|
||||
**[⬆ 목차로 돌아가기](#목차)**
|
||||
|
||||
## Ajax
|
||||
|
||||
[Fetch API](https://fetch.spec.whatwg.org/) 는 XMLHttpRequest를 ajax로 대체하는 새로운 표준 입니다. Chrome과 Firefox에서 작동하며, polyfill을 이용해서 구형 브라우저에서 작동되도록 만들 수도 있습니다.
|
||||
|
||||
IE9 이상에서 지원하는 [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)를 이용해보세요.
|
||||
|
||||
**[⬆ 목차로 돌아가기](#목차)**
|
||||
|
||||
## 이벤트
|
||||
|
||||
namespace와 delegation을 포함해서 완전히 갈아 엎길 원하시면 https://github.com/oneuijs/oui-dom-events 를 고려해보세요.
|
||||
|
||||
- [5.1](#5.1) <a name='5.1'></a> 이벤트 Bind 걸기
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.on(eventName, eventHandler);
|
||||
|
||||
// Native
|
||||
el.addEventListener(eventName, eventHandler);
|
||||
```
|
||||
|
||||
- [5.2](#5.2) <a name='5.2'></a> 이벤트 Bind 풀기
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.off(eventName, eventHandler);
|
||||
|
||||
// Native
|
||||
el.removeEventListener(eventName, eventHandler);
|
||||
```
|
||||
|
||||
- [5.3](#5.3) <a name='5.3'></a> 이벤트 발생시키기(Trigger)
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(el).trigger('custom-event', {key1: 'data'});
|
||||
|
||||
// Native
|
||||
if (window.CustomEvent) {
|
||||
const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});
|
||||
} else {
|
||||
const event = document.createEvent('CustomEvent');
|
||||
event.initCustomEvent('custom-event', true, true, {key1: 'data'});
|
||||
}
|
||||
|
||||
el.dispatchEvent(event);
|
||||
```
|
||||
|
||||
**[⬆ 목차로 돌아가기](#목차)**
|
||||
|
||||
## 유틸리티
|
||||
|
||||
- [6.1](#6.1) <a name='6.1'></a> 배열인지 검사(isArray)
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.isArray(range);
|
||||
|
||||
// Native
|
||||
Array.isArray(range);
|
||||
```
|
||||
|
||||
- [6.2](#6.2) <a name='6.2'></a> 앞뒤 공백 지우기(Trim)
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.trim(string);
|
||||
|
||||
// Native
|
||||
string.trim();
|
||||
```
|
||||
|
||||
- [6.3](#6.3) <a name='6.3'></a> Object Assign
|
||||
|
||||
사용하려면 object.assign polyfill을 사용하세요. https://github.com/ljharb/object.assign
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.extend({}, defaultOpts, opts);
|
||||
|
||||
// Native
|
||||
Object.assign({}, defaultOpts, opts);
|
||||
```
|
||||
|
||||
- [6.4](#6.4) <a name='6.4'></a> Contains
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.contains(el, child);
|
||||
|
||||
// Native
|
||||
el !== child && el.contains(child);
|
||||
```
|
||||
|
||||
- [6.5](#6.5) <a name='6.5'></a> inArray
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.inArray(item, array);
|
||||
|
||||
// Native
|
||||
array.indexOf(item);
|
||||
```
|
||||
|
||||
- [6.6](#6.6) <a name='6.6'></a> map
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.map(array, function(value, index) {
|
||||
});
|
||||
|
||||
// Native
|
||||
Array.map(function(value, index) {
|
||||
});
|
||||
```
|
||||
|
||||
**[⬆ 목차로 돌아가기](#목차)**
|
||||
|
||||
## 대안방법
|
||||
|
||||
* [You Might Not Need jQuery](http://youmightnotneedjquery.com/) - 일반 자바스크립트로 공통이벤트, 엘리먼트, ajax 등을 다루는 방법 예제.
|
||||
* [npm-dom](http://github.com/npm-dom) 과 [webmodules](http://github.com/webmodules) - 개별 DOM모듈을 NPM에서 찾을 수 있습니다.
|
||||
|
||||
## 번역
|
||||
|
||||
* [한국어](./README.ko-KR.md)
|
||||
* [简体中文](./README.zh-CN.md)
|
||||
* [Bahasa Melayu](./README-my.md)
|
||||
* [Bahasa Indonesia](./README-id.md)
|
||||
* [Português(PT-BR)](./README.pt-BR.md)
|
||||
* [Tiếng Việt Nam](./README-vi.md)
|
||||
* [Español](./README-es.md)
|
||||
* [Русский](./README-ru.md)
|
||||
* [Türkçe](./README-tr.md)
|
||||
* [Italian](./README-it.md)
|
||||
|
||||
## 브라우저 지원
|
||||
|
||||
![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)
|
||||
--- | --- | --- | --- | --- |
|
||||
Latest ✔ | Latest ✔ | 10+ ✔ | Latest ✔ | 6.1+ ✔ |
|
||||
|
||||
# License
|
||||
|
||||
MIT
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
628
spec/fixtures/repo-with-submodules/You-Dont-Need-jQuery/README.pt-BR.md
поставляемый
Normal file
628
spec/fixtures/repo-with-submodules/You-Dont-Need-jQuery/README.pt-BR.md
поставляемый
Normal file
|
@ -0,0 +1,628 @@
|
|||
> #### You Don't Need jQuery
|
||||
|
||||
Você não precisa de jQuery
|
||||
---
|
||||
|
||||
Ambientes 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+.
|
||||
|
||||
## Tabela de conteúdos
|
||||
|
||||
1. [Query Selector](#query-selector)
|
||||
1. [CSS & Estilo](#css--estilo)
|
||||
1. [Manipulação do DOM](#manipulação-do-dom)
|
||||
1. [Ajax](#ajax)
|
||||
1. [Eventos](#eventos)
|
||||
1. [Utilitários](#utilitários)
|
||||
1. [Suporte dos Navegadores](#suporte-dos-navegadores)
|
||||
|
||||
## Query Selector
|
||||
|
||||
No lugar de seletores comuns como classe, id ou atributo podemos usar `document.querySelector` ou `document.querySelectorAll` para substituição. As diferenças são:
|
||||
* `document.querySelector` retorna o primeiro elemento correspondente
|
||||
* `document.querySelectorAll` retorna todos os elementos correspondentes como NodeList. Pode ser convertido para Array usando `[].slice.call(document.querySelectorAll(selector) || []);`
|
||||
* 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) || []`
|
||||
|
||||
> 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.
|
||||
|
||||
- [1.0](#1.0) <a name='1.0'></a> Query por seletor
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('selector');
|
||||
|
||||
// Nativo
|
||||
document.querySelectorAll('selector');
|
||||
```
|
||||
|
||||
- [1.1](#1.1) <a name='1.1'></a> Query por classe
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('.class');
|
||||
|
||||
// Nativo
|
||||
document.querySelectorAll('.class');
|
||||
|
||||
// ou
|
||||
document.getElementsByClassName('class');
|
||||
```
|
||||
|
||||
- [1.2](#1.2) <a name='1.2'></a> Query por id
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('#id');
|
||||
|
||||
// Nativo
|
||||
document.querySelector('#id');
|
||||
|
||||
// ou
|
||||
document.getElementById('id');
|
||||
```
|
||||
|
||||
- [1.3](#1.3) <a name='1.3'></a> Query por atributo
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('a[target=_blank]');
|
||||
|
||||
// Nativo
|
||||
document.querySelectorAll('a[target=_blank]');
|
||||
```
|
||||
|
||||
- [1.4](#1.4) <a name='1.4'></a> Find sth.
|
||||
|
||||
+ Busca por nós
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.find('li');
|
||||
|
||||
// Nativo
|
||||
el.querySelectorAll('li');
|
||||
```
|
||||
|
||||
+ Buscar `body`
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('body');
|
||||
|
||||
// Nativo
|
||||
document.body;
|
||||
```
|
||||
|
||||
+ Buscar atributos
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.attr('foo');
|
||||
|
||||
// Nativo
|
||||
e.getAttribute('foo');
|
||||
```
|
||||
|
||||
+ Buscar atributos `data-`
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.data('foo');
|
||||
|
||||
// Nativo
|
||||
// usando getAttribute
|
||||
el.getAttribute('data-foo');
|
||||
// você também pode usar `dataset` se você precisar suportar apenas IE 11+
|
||||
el.dataset['foo'];
|
||||
```
|
||||
|
||||
- [1.5](#1.5) <a name='1.5'></a> Sibling/Previous/Next Elements
|
||||
|
||||
+ Sibling elements
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.siblings();
|
||||
|
||||
// Nativo
|
||||
[].filter.call(el.parentNode.children, function(child) {
|
||||
return child !== el;
|
||||
});
|
||||
```
|
||||
|
||||
+ Previous elements
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.prev();
|
||||
|
||||
// Nativo
|
||||
el.previousElementSibling;
|
||||
|
||||
```
|
||||
|
||||
+ Next elements
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.next();
|
||||
|
||||
// Nativo
|
||||
el.nextElementSibling;
|
||||
```
|
||||
|
||||
- [1.6](#1.6) <a name='1.6'></a> Closest
|
||||
|
||||
Retorna o primeiro elemento que corresponda ao seletor, partindo do elemento atual para o document.
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.closest(queryString);
|
||||
|
||||
// Nativo
|
||||
function closest(el, selector) {
|
||||
const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
|
||||
|
||||
while (el) {
|
||||
if (matchesSelector.call(el, selector)) {
|
||||
return el;
|
||||
} else {
|
||||
el = el.parentElement;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
```
|
||||
|
||||
- [1.7](#1.7) <a name='1.7'></a> Parents Until
|
||||
|
||||
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.
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.parentsUntil(selector, filter);
|
||||
|
||||
// Nativo
|
||||
function parentsUntil(el, selector, filter) {
|
||||
const result = [];
|
||||
const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
|
||||
|
||||
// match start from parent
|
||||
el = el.parentElement;
|
||||
while (el && !matchesSelector.call(el, selector)) {
|
||||
if (!filter) {
|
||||
result.push(el);
|
||||
} else {
|
||||
if (matchesSelector.call(el, filter)) {
|
||||
result.push(el);
|
||||
}
|
||||
}
|
||||
el = el.parentElement;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
```
|
||||
|
||||
- [1.8](#1.8) <a name='1.8'></a> Form
|
||||
|
||||
+ Input/Textarea
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('#my-input').val();
|
||||
|
||||
// Nativo
|
||||
document.querySelector('#my-input').value;
|
||||
```
|
||||
|
||||
+ Obter o índice do e.currentTarget entre `.radio`
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(e.currentTarget).index('.radio');
|
||||
|
||||
// Nativo
|
||||
[].indexOf.call(document.querySelectAll('.radio'), e.currentTarget);
|
||||
```
|
||||
|
||||
- [1.9](#1.9) <a name='1.9'></a> Iframe Contents
|
||||
|
||||
`$('iframe').contents()` retorna `contentDocument` para este iframe específico
|
||||
|
||||
+ Iframe contents
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$iframe.contents();
|
||||
|
||||
// Nativo
|
||||
iframe.contentDocument;
|
||||
```
|
||||
|
||||
+ Iframe Query
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$iframe.contents().find('.css');
|
||||
|
||||
// Nativo
|
||||
iframe.contentDocument.querySelectorAll('.css');
|
||||
```
|
||||
|
||||
**[⬆ ir para o topo](#tabela-de-conteúdos)**
|
||||
|
||||
|
||||
## CSS & Estilo
|
||||
|
||||
- [2.1](#2.1) <a name='2.1'></a> CSS
|
||||
|
||||
+ Obter estilo
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.css("color");
|
||||
|
||||
// Nativo
|
||||
// AVISO: Bug conhecido, irá retornar 'auto' se o valor do estilo for 'auto'
|
||||
const win = el.ownerDocument.defaultView;
|
||||
// null significa não retornar estilos
|
||||
win.getComputedStyle(el, null).color;
|
||||
```
|
||||
|
||||
+ Definir Estilo
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.css({ color: "#ff0011" });
|
||||
|
||||
// Nativo
|
||||
el.style.color = '#ff0011';
|
||||
```
|
||||
|
||||
+ Get/Set Styles
|
||||
|
||||
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.
|
||||
|
||||
|
||||
+ Adicionar classe
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.addClass(className);
|
||||
|
||||
// Nativo
|
||||
el.classList.add(className);
|
||||
```
|
||||
|
||||
+ Remover classe
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.removeClass(className);
|
||||
|
||||
// Nativo
|
||||
el.classList.remove(className);
|
||||
```
|
||||
|
||||
+ Verificar classe
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.hasClass(className);
|
||||
|
||||
// Nativo
|
||||
el.classList.contains(className);
|
||||
```
|
||||
|
||||
+ Toggle class
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.toggleClass(className);
|
||||
|
||||
// Nativo
|
||||
el.classList.toggle(className);
|
||||
```
|
||||
|
||||
- [2.2](#2.2) <a name='2.2'></a> Largura e Altura
|
||||
|
||||
`width` e `height` são teoricamente idênticos, vamos pegar `height` como exemplo:
|
||||
|
||||
+ Altura da janela
|
||||
|
||||
```jsc
|
||||
// window height
|
||||
$(window).height();
|
||||
// sem scrollbar, se comporta como jQuery
|
||||
window.document.documentElement.clientHeight;
|
||||
// com scrollbar
|
||||
window.innerHeight;
|
||||
```
|
||||
|
||||
+ Altura do Documento
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(document).height();
|
||||
|
||||
// Nativo
|
||||
document.documentElement.scrollHeight;
|
||||
```
|
||||
|
||||
+ Altura do Elemento
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.height();
|
||||
|
||||
// Nativo
|
||||
function getHeight(el) {
|
||||
const styles = this.getComputedStyles(el);
|
||||
const height = el.offsetHeight;
|
||||
const borderTopWidth = parseFloat(styles.borderTopWidth);
|
||||
const borderBottomWidth = parseFloat(styles.borderBottomWidth);
|
||||
const paddingTop = parseFloat(styles.paddingTop);
|
||||
const paddingBottom = parseFloat(styles.paddingBottom);
|
||||
return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;
|
||||
}
|
||||
// preciso para inteiro(quando `border-box`, é `height`; quando `content-box`, é `height + padding + border`)
|
||||
el.clientHeight;
|
||||
// preciso para decimal(quando `border-box`, é `height`; quando `content-box`, é `height + padding + border`)
|
||||
el.getBoundingClientRect().height;
|
||||
```
|
||||
|
||||
- [2.3](#2.3) <a name='2.3'></a> Position & Offset
|
||||
|
||||
+ Position
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.position();
|
||||
|
||||
// Nativo
|
||||
{ left: el.offsetLeft, top: el.offsetTop }
|
||||
```
|
||||
|
||||
+ Offset
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.offset();
|
||||
|
||||
// Nativo
|
||||
function getOffset (el) {
|
||||
const box = el.getBoundingClientRect();
|
||||
|
||||
return {
|
||||
top: box.top + window.pageYOffset - document.documentElement.clientTop,
|
||||
left: box.left + window.pageXOffset - document.documentElement.clientLeft
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [2.4](#2.4) <a name='2.4'></a> Rolar para o topo
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(window).scrollTop();
|
||||
|
||||
// Nativo
|
||||
(document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
|
||||
```
|
||||
|
||||
**[⬆ ir para o topo](#tabela-de-conteúdos)**
|
||||
|
||||
## Manipulação do Dom
|
||||
|
||||
- [3.1](#3.1) <a name='3.1'></a> Remover
|
||||
```js
|
||||
// jQuery
|
||||
$el.remove();
|
||||
|
||||
// Nativo
|
||||
el.parentNode.removeChild(el);
|
||||
```
|
||||
|
||||
- [3.2](#3.2) <a name='3.2'></a> Texto
|
||||
|
||||
+ Obter texto
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.text();
|
||||
|
||||
// Nativo
|
||||
el.textContent;
|
||||
```
|
||||
|
||||
+ Definir texto
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.text(string);
|
||||
|
||||
// Nativo
|
||||
el.textContent = string;
|
||||
```
|
||||
|
||||
- [3.3](#3.3) <a name='3.3'></a> HTML
|
||||
|
||||
+ Obter HTML
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.html();
|
||||
|
||||
// Nativo
|
||||
el.innerHTML;
|
||||
```
|
||||
|
||||
+ Definir HTML
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.html(htmlString);
|
||||
|
||||
// Nativo
|
||||
el.innerHTML = htmlString;
|
||||
```
|
||||
|
||||
- [3.4](#3.4) <a name='3.4'></a> Append
|
||||
|
||||
Incluir elemento filho após o último filho do elemento pai.
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.append("<div id='container'>hello</div>");
|
||||
|
||||
// Nativo
|
||||
let newEl = document.createElement('div');
|
||||
newEl.setAttribute('id', 'container');
|
||||
newEl.innerHTML = 'hello';
|
||||
el.appendChild(newEl);
|
||||
```
|
||||
|
||||
- [3.5](#3.5) <a name='3.5'></a> Prepend
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.prepend("<div id='container'>hello</div>");
|
||||
|
||||
// Nativo
|
||||
let newEl = document.createElement('div');
|
||||
newEl.setAttribute('id', 'container');
|
||||
newEl.innerHTML = 'hello';
|
||||
el.insertBefore(newEl, el.firstChild);
|
||||
```
|
||||
|
||||
- [3.6](#3.6) <a name='3.6'></a> insertBefore
|
||||
|
||||
Insere um novo nó antes dos elementos selecionados.
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$newEl.insertBefore(queryString);
|
||||
|
||||
// Nativo
|
||||
const target = document.querySelector(queryString);
|
||||
target.parentNode.insertBefore(newEl, target);
|
||||
```
|
||||
|
||||
- [3.7](#3.7) <a name='3.7'></a> insertAfter
|
||||
|
||||
Insere um novo nó após os elementos selecionados.
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$newEl.insertAfter(queryString);
|
||||
|
||||
// Nativo
|
||||
const target = document.querySelector(queryString);
|
||||
target.parentNode.insertBefore(newEl, target.nextSibling);
|
||||
```
|
||||
|
||||
**[⬆ ir para o topo](#tabela-de-conteúdos)**
|
||||
|
||||
## Ajax
|
||||
|
||||
Substitua por [fetch](https://github.com/camsong/fetch-ie8) e [fetch-jsonp](https://github.com/camsong/fetch-jsonp)
|
||||
|
||||
**[⬆ ir para o topo](#tabela-de-conteúdos)**
|
||||
|
||||
## Eventos
|
||||
|
||||
Para uma substituição completa com namespace e delegation, consulte https://github.com/oneuijs/oui-dom-events
|
||||
|
||||
- [5.1](#5.1) <a name='5.1'></a> `Bind` num evento com `on`
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.on(eventName, eventHandler);
|
||||
|
||||
// Nativo
|
||||
el.addEventListener(eventName, eventHandler);
|
||||
```
|
||||
|
||||
- [5.2](#5.2) <a name='5.2'></a> `Unbind` num evento com `off`
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.off(eventName, eventHandler);
|
||||
|
||||
// Nativo
|
||||
el.removeEventListener(eventName, eventHandler);
|
||||
```
|
||||
|
||||
- [5.3](#5.3) <a name='5.3'></a> Trigger
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(el).trigger('custom-event', {key1: 'data'});
|
||||
|
||||
// Nativo
|
||||
if (window.CustomEvent) {
|
||||
const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});
|
||||
} else {
|
||||
const event = document.createEvent('CustomEvent');
|
||||
event.initCustomEvent('custom-event', true, true, {key1: 'data'});
|
||||
}
|
||||
|
||||
el.dispatchEvent(event);
|
||||
```
|
||||
|
||||
**[⬆ ir para o topo](#tabela-de-conteúdos)**
|
||||
|
||||
## Utilitários
|
||||
|
||||
- [6.1](#6.1) <a name='6.1'></a> isArray
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.isArray(range);
|
||||
|
||||
// Nativo
|
||||
Array.isArray(range);
|
||||
```
|
||||
|
||||
- [6.2](#6.2) <a name='6.2'></a> Trim
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.trim(string);
|
||||
|
||||
// Nativo
|
||||
string.trim();
|
||||
```
|
||||
|
||||
- [6.3](#6.3) <a name='6.3'></a> Object Assign
|
||||
|
||||
Use o polyfill `object.assign` para eetender um Object: https://github.com/ljharb/object.assign
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.extend({}, defaultOpts, opts);
|
||||
|
||||
// Nativo
|
||||
Object.assign({}, defaultOpts, opts);
|
||||
```
|
||||
|
||||
- [6.4](#6.4) <a name='6.4'></a> Contains
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.contains(el, child);
|
||||
|
||||
// Nativo
|
||||
el !== child && el.contains(child);
|
||||
```
|
||||
|
||||
**[⬆ ir para o topo](#tabela-de-conteúdos)**
|
||||
|
||||
## Suporte dos Navegadores
|
||||
|
||||
![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)
|
||||
--- | --- | --- | --- | --- |
|
||||
Latest ✔ | Latest ✔ | 10+ ✔ | Latest ✔ | 6.1+ ✔ |
|
||||
|
||||
# Licença
|
||||
|
||||
MIT
|
656
spec/fixtures/repo-with-submodules/You-Dont-Need-jQuery/README.zh-CN.md
поставляемый
Normal file
656
spec/fixtures/repo-with-submodules/You-Dont-Need-jQuery/README.zh-CN.md
поставляемый
Normal file
|
@ -0,0 +1,656 @@
|
|||
## You Don't Need jQuery
|
||||
|
||||
前端发展很快,现代浏览器原生 API 已经足够好用。我们并不需要为了操作 DOM、Event 等再学习一下 jQuery 的 API。同时由于 React、Angular、Vue 等框架的流行,直接操作 DOM 不再是好的模式,jQuery 使用场景大大减少。本项目总结了大部分 jQuery API 替代的方法,暂时只支持 IE10+ 以上浏览器。
|
||||
|
||||
## 目录
|
||||
|
||||
1. [Query Selector](#query-selector)
|
||||
1. [CSS & Style](#css--style)
|
||||
1. [DOM Manipulation](#dom-manipulation)
|
||||
1. [Ajax](#ajax)
|
||||
1. [Events](#events)
|
||||
1. [Utilities](#utilities)
|
||||
1. [Alternatives](#alternatives)
|
||||
1. [Translations](#translations)
|
||||
1. [Browser Support](#browser-support)
|
||||
|
||||
## Query Selector
|
||||
|
||||
常用的 class、id、属性 选择器都可以使用 `document.querySelector` 或 `document.querySelectorAll` 替代。区别是
|
||||
* `document.querySelector` 返回第一个匹配的 Element
|
||||
* `document.querySelectorAll` 返回所有匹配的 Element 组成的 NodeList。它可以通过 `[].slice.call()` 把它转成 Array
|
||||
* 如果匹配不到任何 Element,jQuery 返回空数组 `[]`,但 `document.querySelector` 返回 `null`,注意空指针异常。当找不到时,也可以使用 `||` 设置默认的值,如 `document.querySelectorAll(selector) || []`
|
||||
|
||||
> 注意:`document.querySelector` 和 `document.querySelectorAll` 性能很**差**。如果想提高性能,尽量使用 `document.getElementById`、`document.getElementsByClassName` 或 `document.getElementsByTagName`。
|
||||
|
||||
- [1.0](#1.0) <a name='1.0'></a> Query by selector
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('selector');
|
||||
|
||||
// Native
|
||||
document.querySelectorAll('selector');
|
||||
```
|
||||
|
||||
- [1.1](#1.1) <a name='1.1'></a> Query by class
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('.css');
|
||||
|
||||
// Native
|
||||
document.querySelectorAll('.css');
|
||||
|
||||
// or
|
||||
document.getElementsByClassName('css');
|
||||
```
|
||||
|
||||
- [1.2](#1.2) <a name='1.2'></a> Query by id
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('#id');
|
||||
|
||||
// Native
|
||||
document.querySelector('#id');
|
||||
|
||||
// or
|
||||
document.getElementById('id');
|
||||
```
|
||||
|
||||
- [1.3](#1.3) <a name='1.3'></a> Query by attribute
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('a[target=_blank]');
|
||||
|
||||
// Native
|
||||
document.querySelectorAll('a[target=_blank]');
|
||||
```
|
||||
|
||||
- [1.4](#1.4) <a name='1.4'></a> Find sth.
|
||||
|
||||
+ Find nodes
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.find('li');
|
||||
|
||||
// Native
|
||||
el.querySelectorAll('li');
|
||||
```
|
||||
|
||||
+ Find body
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('body');
|
||||
|
||||
// Native
|
||||
document.body;
|
||||
```
|
||||
|
||||
+ Find Attribute
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.attr('foo');
|
||||
|
||||
// Native
|
||||
e.getAttribute('foo');
|
||||
```
|
||||
|
||||
+ Find data attribute
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.data('foo');
|
||||
|
||||
// Native
|
||||
// using getAttribute
|
||||
el.getAttribute('data-foo');
|
||||
// you can also use `dataset` if only need to support IE 11+
|
||||
el.dataset['foo'];
|
||||
```
|
||||
|
||||
- [1.5](#1.5) <a name='1.5'></a> Sibling/Previous/Next Elements
|
||||
|
||||
+ Sibling elements
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.siblings();
|
||||
|
||||
// Native
|
||||
[].filter.call(el.parentNode.children, function(child) {
|
||||
return child !== el;
|
||||
});
|
||||
```
|
||||
|
||||
+ Previous elements
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.prev();
|
||||
|
||||
// Native
|
||||
el.previousElementSibling;
|
||||
|
||||
```
|
||||
|
||||
+ Next elements
|
||||
|
||||
```js
|
||||
// next
|
||||
$el.next();
|
||||
el.nextElementSibling;
|
||||
```
|
||||
|
||||
- [1.6](#1.6) <a name='1.6'></a> Closest
|
||||
|
||||
Closest 获得匹配选择器的第一个祖先元素,从当前元素开始沿 DOM 树向上。
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.closest(queryString);
|
||||
|
||||
// Native
|
||||
function closest(el, selector) {
|
||||
const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
|
||||
|
||||
while (el) {
|
||||
if (matchesSelector.call(el, selector)) {
|
||||
return el;
|
||||
} else {
|
||||
el = el.parentElement;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
```
|
||||
|
||||
- [1.7](#1.7) <a name='1.7'></a> Parents Until
|
||||
|
||||
获取当前每一个匹配元素集的祖先,不包括匹配元素的本身。
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.parentsUntil(selector, filter);
|
||||
|
||||
// Native
|
||||
function parentsUntil(el, selector, filter) {
|
||||
const result = [];
|
||||
const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
|
||||
|
||||
// match start from parent
|
||||
el = el.parentElement;
|
||||
while (el && !matchesSelector.call(el, selector)) {
|
||||
if (!filter) {
|
||||
result.push(el);
|
||||
} else {
|
||||
if (matchesSelector.call(el, filter)) {
|
||||
result.push(el);
|
||||
}
|
||||
}
|
||||
el = el.parentElement;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
```
|
||||
|
||||
- [1.8](#1.8) <a name='1.8'></a> Form
|
||||
|
||||
+ Input/Textarea
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('#my-input').val();
|
||||
|
||||
// Native
|
||||
document.querySelector('#my-input').value;
|
||||
```
|
||||
|
||||
+ Get index of e.currentTarget between `.radio`
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(e.currentTarget).index('.radio');
|
||||
|
||||
// Native
|
||||
[].indexOf.call(document.querySelectAll('.radio'), e.currentTarget);
|
||||
```
|
||||
|
||||
- [1.9](#1.9) <a name='1.9'></a> Iframe Contents
|
||||
|
||||
jQuery 对象的 iframe `contents()` 返回的是 iframe 内的 `document`
|
||||
|
||||
+ Iframe contents
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$iframe.contents();
|
||||
|
||||
// Native
|
||||
iframe.contentDocument;
|
||||
```
|
||||
|
||||
+ Iframe Query
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$iframe.contents().find('.css');
|
||||
|
||||
// Native
|
||||
iframe.contentDocument.querySelectorAll('.css');
|
||||
```
|
||||
|
||||
**[⬆ 回到顶部](#目录)**
|
||||
|
||||
## CSS & Style
|
||||
|
||||
- [2.1](#2.1) <a name='2.1'></a> CSS
|
||||
|
||||
+ Get style
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.css("color");
|
||||
|
||||
// Native
|
||||
// 注意:此处为了解决当 style 值为 auto 时,返回 auto 的问题
|
||||
const win = el.ownerDocument.defaultView;
|
||||
// null 的意思是不返回伪类元素
|
||||
win.getComputedStyle(el, null).color;
|
||||
```
|
||||
|
||||
+ Set style
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.css({ color: "#ff0011" });
|
||||
|
||||
// Native
|
||||
el.style.color = '#ff0011';
|
||||
```
|
||||
|
||||
+ Get/Set Styles
|
||||
|
||||
注意,如果想一次设置多个 style,可以参考 oui-dom-utils 中 [setStyles](https://github.com/oneuijs/oui-dom-utils/blob/master/src/index.js#L194) 方法
|
||||
|
||||
+ Add class
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.addClass(className);
|
||||
|
||||
// Native
|
||||
el.classList.add(className);
|
||||
```
|
||||
|
||||
+ Remove class
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.removeClass(className);
|
||||
|
||||
// Native
|
||||
el.classList.remove(className);
|
||||
```
|
||||
|
||||
+ has class
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.hasClass(className);
|
||||
|
||||
// Native
|
||||
el.classList.contains(className);
|
||||
```
|
||||
|
||||
+ Toggle class
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.toggleClass(className);
|
||||
|
||||
// Native
|
||||
el.classList.toggle(className);
|
||||
```
|
||||
|
||||
- [2.2](#2.2) <a name='2.2'></a> Width & Height
|
||||
|
||||
Width 与 Height 获取方法相同,下面以 Height 为例:
|
||||
|
||||
+ Window height
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(window).height();
|
||||
|
||||
// Native
|
||||
// 不含 scrollbar,与 jQuery 行为一致
|
||||
window.document.documentElement.clientHeight;
|
||||
// 含 scrollbar
|
||||
window.innerHeight;
|
||||
```
|
||||
|
||||
+ Document height
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(document).height();
|
||||
|
||||
// Native
|
||||
document.documentElement.scrollHeight;
|
||||
```
|
||||
|
||||
+ Element height
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.height();
|
||||
|
||||
// Native
|
||||
// 与 jQuery 一致(一直为 content 区域的高度)
|
||||
function getHeight(el) {
|
||||
const styles = this.getComputedStyles(el);
|
||||
const height = el.offsetHeight;
|
||||
const borderTopWidth = parseFloat(styles.borderTopWidth);
|
||||
const borderBottomWidth = parseFloat(styles.borderBottomWidth);
|
||||
const paddingTop = parseFloat(styles.paddingTop);
|
||||
const paddingBottom = parseFloat(styles.paddingBottom);
|
||||
return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;
|
||||
}
|
||||
// 精确到整数(border-box 时为 height 值,content-box 时为 height + padding + border 值)
|
||||
el.clientHeight;
|
||||
// 精确到小数(border-box 时为 height 值,content-box 时为 height + padding + border 值)
|
||||
el.getBoundingClientRect().height;
|
||||
```
|
||||
|
||||
+ Iframe height
|
||||
|
||||
$iframe .contents() 方法返回 iframe 的 contentDocument
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$('iframe').contents().height();
|
||||
|
||||
// Native
|
||||
iframe.contentDocument.documentElement.scrollHeight;
|
||||
```
|
||||
|
||||
- [2.3](#2.3) <a name='2.3'></a> Position & Offset
|
||||
|
||||
+ Position
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.position();
|
||||
|
||||
// Native
|
||||
{ left: el.offsetLeft, top: el.offsetTop }
|
||||
```
|
||||
|
||||
+ Offset
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.offset();
|
||||
|
||||
// Native
|
||||
function getOffset (el) {
|
||||
const box = el.getBoundingClientRect();
|
||||
|
||||
return {
|
||||
top: box.top + window.pageYOffset - document.documentElement.clientTop,
|
||||
left: box.left + window.pageXOffset - document.documentElement.clientLeft
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [2.4](#2.4) <a name='2.4'></a> Scroll Top
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(window).scrollTop();
|
||||
|
||||
// Native
|
||||
(document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
|
||||
```
|
||||
|
||||
**[⬆ 回到顶部](#目录)**
|
||||
|
||||
## DOM Manipulation
|
||||
|
||||
- [3.1](#3.1) <a name='3.1'></a> Remove
|
||||
```js
|
||||
// jQuery
|
||||
$el.remove();
|
||||
|
||||
// Native
|
||||
el.parentNode.removeChild(el);
|
||||
```
|
||||
|
||||
- [3.2](#3.2) <a name='3.2'></a> Text
|
||||
|
||||
+ Get text
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.text();
|
||||
|
||||
// Native
|
||||
el.textContent;
|
||||
```
|
||||
|
||||
+ Set text
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.text(string);
|
||||
|
||||
// Native
|
||||
el.textContent = string;
|
||||
```
|
||||
|
||||
- [3.3](#3.3) <a name='3.3'></a> HTML
|
||||
|
||||
+ Get HTML
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.html();
|
||||
|
||||
// Native
|
||||
el.innerHTML;
|
||||
```
|
||||
|
||||
+ Set HTML
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.html(htmlString);
|
||||
|
||||
// Native
|
||||
el.innerHTML = htmlString;
|
||||
```
|
||||
|
||||
- [3.4](#3.4) <a name='3.4'></a> Append
|
||||
|
||||
Append 插入到子节点的末尾
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.append("<div id='container'>hello</div>");
|
||||
|
||||
// Native
|
||||
let newEl = document.createElement('div');
|
||||
newEl.setAttribute('id', 'container');
|
||||
newEl.innerHTML = 'hello';
|
||||
el.appendChild(newEl);
|
||||
```
|
||||
|
||||
- [3.5](#3.5) <a name='3.5'></a> Prepend
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.prepend("<div id='container'>hello</div>");
|
||||
|
||||
// Native
|
||||
let newEl = document.createElement('div');
|
||||
newEl.setAttribute('id', 'container');
|
||||
newEl.innerHTML = 'hello';
|
||||
el.insertBefore(newEl, el.firstChild);
|
||||
```
|
||||
|
||||
- [3.6](#3.6) <a name='3.6'></a> insertBefore
|
||||
|
||||
在选中元素前插入新节点
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$newEl.insertBefore(queryString);
|
||||
|
||||
// Native
|
||||
const target = document.querySelector(queryString);
|
||||
target.parentNode.insertBefore(newEl, target);
|
||||
```
|
||||
|
||||
- [3.7](#3.7) <a name='3.7'></a> insertAfter
|
||||
|
||||
在选中元素后插入新节点
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$newEl.insertAfter(queryString);
|
||||
|
||||
// Native
|
||||
const target = document.querySelector(queryString);
|
||||
target.parentNode.insertBefore(newEl, target.nextSibling);
|
||||
```
|
||||
|
||||
**[⬆ 回到顶部](#目录)**
|
||||
|
||||
## Ajax
|
||||
|
||||
用 [fetch](https://github.com/camsong/fetch-ie8) 和 [fetch-jsonp](https://github.com/camsong/fetch-jsonp) 替代
|
||||
|
||||
**[⬆ 回到顶部](#目录)**
|
||||
|
||||
## Events
|
||||
|
||||
完整地替代命名空间和事件代理,链接到 https://github.com/oneuijs/oui-dom-events
|
||||
|
||||
- [5.1](#5.1) <a name='5.1'></a> Bind an event with on
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.on(eventName, eventHandler);
|
||||
|
||||
// Native
|
||||
el.addEventListener(eventName, eventHandler);
|
||||
```
|
||||
|
||||
- [5.2](#5.2) <a name='5.2'></a> Unbind an event with off
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$el.off(eventName, eventHandler);
|
||||
|
||||
// Native
|
||||
el.removeEventListener(eventName, eventHandler);
|
||||
```
|
||||
|
||||
- [5.3](#5.3) <a name='5.3'></a> Trigger
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$(el).trigger('custom-event', {key1: 'data'});
|
||||
|
||||
// Native
|
||||
if (window.CustomEvent) {
|
||||
const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});
|
||||
} else {
|
||||
const event = document.createEvent('CustomEvent');
|
||||
event.initCustomEvent('custom-event', true, true, {key1: 'data'});
|
||||
}
|
||||
|
||||
el.dispatchEvent(event);
|
||||
```
|
||||
|
||||
**[⬆ 回到顶部](#目录)**
|
||||
|
||||
## Utilities
|
||||
|
||||
- [6.1](#6.1) <a name='6.1'></a> isArray
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.isArray(range);
|
||||
|
||||
// Native
|
||||
Array.isArray(range);
|
||||
```
|
||||
|
||||
- [6.2](#6.2) <a name='6.2'></a> Trim
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.trim(string);
|
||||
|
||||
// Native
|
||||
string.trim();
|
||||
```
|
||||
|
||||
- [6.3](#6.3) <a name='6.3'></a> Object Assign
|
||||
|
||||
继承,使用 object.assign polyfill https://github.com/ljharb/object.assign
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.extend({}, defaultOpts, opts);
|
||||
|
||||
// Native
|
||||
Object.assign({}, defaultOpts, opts);
|
||||
```
|
||||
|
||||
- [6.4](#6.4) <a name='6.4'></a> Contains
|
||||
|
||||
```js
|
||||
// jQuery
|
||||
$.contains(el, child);
|
||||
|
||||
// Native
|
||||
el !== child && el.contains(child);
|
||||
```
|
||||
|
||||
**[⬆ 回到顶部](#目录)**
|
||||
|
||||
## Alternatives
|
||||
|
||||
* [你可能不需要 jQuery (You Might Not Need jQuery)](http://youmightnotneedjquery.com/) - 如何使用原生 JavaScript 实现通用事件,元素,ajax 等用法。
|
||||
* [npm-dom](http://github.com/npm-dom) 以及 [webmodules](http://github.com/webmodules) - 在 NPM 上提供独立 DOM 模块的组织
|
||||
|
||||
## Translations
|
||||
|
||||
* [한국어](./README.ko-KR.md)
|
||||
* [简体中文](./README.zh-CN.md)
|
||||
* [Bahasa Melayu](./README-my.md)
|
||||
* [Bahasa Indonesia](./README-id.md)
|
||||
* [Português(PT-BR)](./README.pt-BR.md)
|
||||
* [Tiếng Việt Nam](./README-vi.md)
|
||||
* [Español](./README-es.md)
|
||||
* [Русский](./README-ru.md)
|
||||
* [Türkçe](./README-tr.md)
|
||||
* [Italian](./README-it.md)
|
||||
|
||||
## Browser Support
|
||||
|
||||
![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)
|
||||
--- | --- | --- | --- | --- |
|
||||
Latest ✔ | Latest ✔ | 10+ ✔ | Latest ✔ | 6.1+ ✔ |
|
||||
|
||||
# License
|
||||
|
||||
MIT
|
|
@ -0,0 +1 @@
|
|||
gitdir: ../.git/modules/You-Dont-Need-jQuery
|
|
@ -0,0 +1,92 @@
|
|||
// Karma configuration
|
||||
// Generated on Sun Nov 22 2015 22:10:47 GMT+0800 (CST)
|
||||
require('babel-core/register');
|
||||
|
||||
module.exports = function(config) {
|
||||
config.set({
|
||||
// base path that will be used to resolve all patterns (eg. files, exclude)
|
||||
basePath: '.',
|
||||
|
||||
// frameworks to use
|
||||
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
|
||||
frameworks: ['mocha'],
|
||||
|
||||
// list of files / patterns to load in the browser
|
||||
files: [
|
||||
'./test/**/*.spec.js'
|
||||
],
|
||||
|
||||
// list of files to exclude
|
||||
exclude: [
|
||||
],
|
||||
|
||||
// preprocess matching files before serving them to the browser
|
||||
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
|
||||
preprocessors: {
|
||||
'test/**/*.spec.js': ['webpack', 'sourcemap']
|
||||
},
|
||||
|
||||
// test results reporter to use
|
||||
// possible values: 'dots', 'progress'
|
||||
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
|
||||
reporters: ['progress'],
|
||||
|
||||
coverageReporter: {
|
||||
reporters: [
|
||||
{type: 'text'},
|
||||
{type: 'html', dir: 'coverage'},
|
||||
]
|
||||
},
|
||||
|
||||
webpackMiddleware: {
|
||||
stats: 'minimal'
|
||||
},
|
||||
|
||||
webpack: {
|
||||
cache: true,
|
||||
devtool: 'inline-source-map',
|
||||
module: {
|
||||
loaders: [{
|
||||
test: /\.jsx?$/,
|
||||
loader: 'babel-loader',
|
||||
exclude: /node_modules/
|
||||
}],
|
||||
postLoaders: [{
|
||||
test: /\.js/,
|
||||
exclude: /(test|node_modules)/,
|
||||
loader: 'istanbul-instrumenter'
|
||||
}],
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['', '.js', '.jsx']
|
||||
}
|
||||
},
|
||||
|
||||
// web server port
|
||||
port: 9876,
|
||||
|
||||
// enable / disable colors in the output (reporters and logs)
|
||||
colors: true,
|
||||
|
||||
// level of logging
|
||||
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
|
||||
logLevel: config.LOG_INFO,
|
||||
|
||||
// enable / disable watching file and executing tests whenever any file changes
|
||||
autoWatch: true,
|
||||
|
||||
// start these browsers
|
||||
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
|
||||
browsers: ['Firefox'],
|
||||
|
||||
// Continuous Integration mode
|
||||
// if true, Karma captures browsers, runs the tests and exits
|
||||
// singleRun: false,
|
||||
|
||||
// Concurrency level
|
||||
// how many browser should be started simultanous
|
||||
// concurrency: Infinity,
|
||||
|
||||
// plugins: ['karma-phantomjs-launcher', 'karma-sourcemap-loader', 'karma-webpack']
|
||||
})
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
{
|
||||
"name": "You-Dont-Need-jQuery",
|
||||
"version": "1.0.0",
|
||||
"description": "Examples of how to do query, style, dom, ajax, event etc like jQuery with plain javascript.",
|
||||
"scripts": {
|
||||
"test": "karma start --single-run",
|
||||
"tdd": "karma start --auto-watch --no-single-run",
|
||||
"test-cov": "karma start --auto-watch --single-run --reporters progress,coverage",
|
||||
"lint": "eslint src test"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"babel-cli": "^6.2.0",
|
||||
"babel-core": "^6.1.21",
|
||||
"babel-eslint": "^4.1.5",
|
||||
"babel-loader": "^6.2.0",
|
||||
"babel-preset-es2015": "^6.1.18",
|
||||
"babel-preset-stage-0": "^6.1.18",
|
||||
"chai": "^3.4.1",
|
||||
"eslint": "^1.9.0",
|
||||
"eslint-config-airbnb": "^1.0.0",
|
||||
"eslint-plugin-react": "^3.10.0",
|
||||
"isparta": "^4.0.0",
|
||||
"istanbul-instrumenter-loader": "^0.1.3",
|
||||
"jquery": "^2.1.4",
|
||||
"karma": "^0.13.15",
|
||||
"karma-coverage": "^0.5.3",
|
||||
"karma-firefox-launcher": "^0.1.7",
|
||||
"karma-mocha": "^0.2.1",
|
||||
"karma-sourcemap-loader": "^0.3.6",
|
||||
"karma-webpack": "^1.7.0",
|
||||
"mocha": "^2.3.4",
|
||||
"webpack": "^1.12.9"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/oneuijs/You-Dont-Need-jQuery.git"
|
||||
},
|
||||
"keywords": [
|
||||
"convertion guide",
|
||||
"jQuery",
|
||||
"es6",
|
||||
"es2015",
|
||||
"babel",
|
||||
"OneUI Group"
|
||||
],
|
||||
"author": "OneUI Group",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/oneuijs/You-Dont-Need-jQuery/issues"
|
||||
},
|
||||
"homepage": "https://github.com/oneuijs/You-Dont-Need-jQuery"
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
# Test cases for all the tips
|
||||
|
||||
## Usage
|
||||
|
||||
run all tests once
|
||||
```
|
||||
npm run test
|
||||
```
|
||||
|
||||
run tests on TDD(Test Driven Development) mode
|
||||
```
|
||||
npm run tdd
|
||||
```
|
|
@ -0,0 +1 @@
|
|||
// test for CSS related
|
|
@ -0,0 +1 @@
|
|||
// test for CSS and style related
|
71
spec/fixtures/repo-with-submodules/You-Dont-Need-jQuery/test/query.spec.js
поставляемый
Normal file
71
spec/fixtures/repo-with-submodules/You-Dont-Need-jQuery/test/query.spec.js
поставляемый
Normal file
|
@ -0,0 +1,71 @@
|
|||
// tests for Query Selector related
|
||||
import { expect } from 'chai';
|
||||
import $ from 'jquery';
|
||||
|
||||
describe('query selector', () => {
|
||||
describe('basic', () => {
|
||||
beforeEach(() => {
|
||||
document.body.innerHTML = `
|
||||
<ul id='query-selector-test1' class='list'>
|
||||
<li data-role='red' class='item-i red item'>I</li>
|
||||
<li data-role='blue' class='item-ii blue item'>II</li>
|
||||
<li>III</li>
|
||||
<li>
|
||||
<ul id='nested-ul'>
|
||||
<li data-role='red' class='item-i-i red item'>III.I</li>
|
||||
<li data-role='blue' class='item-i-ii blue item'>III.II</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
`;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
const el = document.querySelector('#query-selector-test1');
|
||||
el.parentNode.removeChild(el);
|
||||
});
|
||||
|
||||
it('1.0 Query by selector', () => {
|
||||
const $els = $('li.item[data-role="red"]');
|
||||
const els = document.querySelectorAll('li.item[data-role="red"]');
|
||||
|
||||
expect($els.length).to.equal(2);
|
||||
[].forEach.call($els, function($el, i) {
|
||||
expect($el).to.equal(els[i]);
|
||||
});
|
||||
});
|
||||
|
||||
it('1.1 Query by class', () => {
|
||||
const $els = $('.item');
|
||||
const els = document.getElementsByClassName('item');
|
||||
|
||||
[].forEach.call($els, function($el, i) {
|
||||
expect($el).to.equal(els[i]);
|
||||
});
|
||||
});
|
||||
|
||||
it('1.2 Query by id', () => {
|
||||
expect($('#nested-ul')[0]).to.equal(document.getElementById('nested-ul'));
|
||||
});
|
||||
|
||||
it('1.3 Query by attribute', () => {
|
||||
const $els = $('[data-role="blue"]');
|
||||
const els = document.querySelectorAll('[data-role="blue"]');
|
||||
|
||||
expect($els.length).to.equal(2);
|
||||
[].forEach.call($els, function($el, i) {
|
||||
expect($el).to.equal(els[i]);
|
||||
});
|
||||
});
|
||||
|
||||
it('1.4 Query in descendents', () => {
|
||||
const $els = $('#query-selector-test1').find('.item');
|
||||
const els = document.getElementById('query-selector-test1').querySelectorAll('.item');
|
||||
|
||||
expect($els.length).to.equal(4);
|
||||
[].forEach.call($els, function($el, i) {
|
||||
expect($el).to.equal(els[i]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
1
spec/fixtures/repo-with-submodules/You-Dont-Need-jQuery/test/utilities.spec.js
поставляемый
Normal file
1
spec/fixtures/repo-with-submodules/You-Dont-Need-jQuery/test/utilities.spec.js
поставляемый
Normal file
|
@ -0,0 +1 @@
|
|||
// test for Utilities related
|
|
@ -0,0 +1,9 @@
|
|||
submodules
|
||||
# Please enter the commit message for your changes. Lines starting
|
||||
# with '#' will be ignored, and an empty message aborts the commit.
|
||||
# On branch master
|
||||
# Changes to be committed:
|
||||
# new file: .gitmodules
|
||||
# new file: You-Dont-Need-jQuery
|
||||
# new file: jstips
|
||||
#
|
|
@ -0,0 +1 @@
|
|||
ref: refs/heads/master
|
|
@ -0,0 +1,11 @@
|
|||
[core]
|
||||
repositoryformatversion = 0
|
||||
filemode = true
|
||||
bare = false
|
||||
logallrefupdates = true
|
||||
ignorecase = true
|
||||
precomposeunicode = true
|
||||
[submodule "jstips"]
|
||||
url = https://github.com/loverajoel/jstips
|
||||
[submodule "You-Dont-Need-jQuery"]
|
||||
url = https://github.com/oneuijs/You-Dont-Need-jQuery
|
|
@ -0,0 +1 @@
|
|||
Unnamed repository; edit this file 'description' to name the repository.
|
15
spec/fixtures/repo-with-submodules/git.git/hooks/applypatch-msg.sample
поставляемый
Executable file
15
spec/fixtures/repo-with-submodules/git.git/hooks/applypatch-msg.sample
поставляемый
Executable file
|
@ -0,0 +1,15 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to check the commit log message taken by
|
||||
# applypatch from an e-mail message.
|
||||
#
|
||||
# The hook should exit with non-zero status after issuing an
|
||||
# appropriate message if it wants to stop the commit. The hook is
|
||||
# allowed to edit the commit message file.
|
||||
#
|
||||
# To enable this hook, rename this file to "applypatch-msg".
|
||||
|
||||
. git-sh-setup
|
||||
commitmsg="$(git rev-parse --git-path hooks/commit-msg)"
|
||||
test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"}
|
||||
:
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to check the commit log message.
|
||||
# Called by "git commit" with one argument, the name of the file
|
||||
# that has the commit message. The hook should exit with non-zero
|
||||
# status after issuing an appropriate message if it wants to stop the
|
||||
# commit. The hook is allowed to edit the commit message file.
|
||||
#
|
||||
# To enable this hook, rename this file to "commit-msg".
|
||||
|
||||
# Uncomment the below to add a Signed-off-by line to the message.
|
||||
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
|
||||
# hook is more suited to it.
|
||||
#
|
||||
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
|
||||
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
|
||||
|
||||
# This example catches duplicate Signed-off-by lines.
|
||||
|
||||
test "" = "$(grep '^Signed-off-by: ' "$1" |
|
||||
sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || {
|
||||
echo >&2 Duplicate Signed-off-by lines.
|
||||
exit 1
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to prepare a packed repository for use over
|
||||
# dumb transports.
|
||||
#
|
||||
# To enable this hook, rename this file to "post-update".
|
||||
|
||||
exec git update-server-info
|
14
spec/fixtures/repo-with-submodules/git.git/hooks/pre-applypatch.sample
поставляемый
Executable file
14
spec/fixtures/repo-with-submodules/git.git/hooks/pre-applypatch.sample
поставляемый
Executable file
|
@ -0,0 +1,14 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to verify what is about to be committed
|
||||
# by applypatch from an e-mail message.
|
||||
#
|
||||
# The hook should exit with non-zero status after issuing an
|
||||
# appropriate message if it wants to stop the commit.
|
||||
#
|
||||
# To enable this hook, rename this file to "pre-applypatch".
|
||||
|
||||
. git-sh-setup
|
||||
precommit="$(git rev-parse --git-path hooks/pre-commit)"
|
||||
test -x "$precommit" && exec "$precommit" ${1+"$@"}
|
||||
:
|
|
@ -0,0 +1,49 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to verify what is about to be committed.
|
||||
# Called by "git commit" with no arguments. The hook should
|
||||
# exit with non-zero status after issuing an appropriate message if
|
||||
# it wants to stop the commit.
|
||||
#
|
||||
# To enable this hook, rename this file to "pre-commit".
|
||||
|
||||
if git rev-parse --verify HEAD >/dev/null 2>&1
|
||||
then
|
||||
against=HEAD
|
||||
else
|
||||
# Initial commit: diff against an empty tree object
|
||||
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
|
||||
fi
|
||||
|
||||
# If you want to allow non-ASCII filenames set this variable to true.
|
||||
allownonascii=$(git config --bool hooks.allownonascii)
|
||||
|
||||
# Redirect output to stderr.
|
||||
exec 1>&2
|
||||
|
||||
# Cross platform projects tend to avoid non-ASCII filenames; prevent
|
||||
# them from being added to the repository. We exploit the fact that the
|
||||
# printable range starts at the space character and ends with tilde.
|
||||
if [ "$allownonascii" != "true" ] &&
|
||||
# Note that the use of brackets around a tr range is ok here, (it's
|
||||
# even required, for portability to Solaris 10's /usr/bin/tr), since
|
||||
# the square bracket bytes happen to fall in the designated range.
|
||||
test $(git diff --cached --name-only --diff-filter=A -z $against |
|
||||
LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
|
||||
then
|
||||
cat <<\EOF
|
||||
Error: Attempt to add a non-ASCII file name.
|
||||
|
||||
This can cause problems if you want to work with people on other platforms.
|
||||
|
||||
To be portable it is advisable to rename the file.
|
||||
|
||||
If you know what you are doing you can disable this check using:
|
||||
|
||||
git config hooks.allownonascii true
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# If there are whitespace errors, print the offending file names and fail.
|
||||
exec git diff-index --check --cached $against --
|
|
@ -0,0 +1,53 @@
|
|||
#!/bin/sh
|
||||
|
||||
# An example hook script to verify what is about to be pushed. Called by "git
|
||||
# push" after it has checked the remote status, but before anything has been
|
||||
# pushed. If this script exits with a non-zero status nothing will be pushed.
|
||||
#
|
||||
# This hook is called with the following parameters:
|
||||
#
|
||||
# $1 -- Name of the remote to which the push is being done
|
||||
# $2 -- URL to which the push is being done
|
||||
#
|
||||
# If pushing without using a named remote those arguments will be equal.
|
||||
#
|
||||
# Information about the commits which are being pushed is supplied as lines to
|
||||
# the standard input in the form:
|
||||
#
|
||||
# <local ref> <local sha1> <remote ref> <remote sha1>
|
||||
#
|
||||
# This sample shows how to prevent push of commits where the log message starts
|
||||
# with "WIP" (work in progress).
|
||||
|
||||
remote="$1"
|
||||
url="$2"
|
||||
|
||||
z40=0000000000000000000000000000000000000000
|
||||
|
||||
while read local_ref local_sha remote_ref remote_sha
|
||||
do
|
||||
if [ "$local_sha" = $z40 ]
|
||||
then
|
||||
# Handle delete
|
||||
:
|
||||
else
|
||||
if [ "$remote_sha" = $z40 ]
|
||||
then
|
||||
# New branch, examine all commits
|
||||
range="$local_sha"
|
||||
else
|
||||
# Update to existing branch, examine new commits
|
||||
range="$remote_sha..$local_sha"
|
||||
fi
|
||||
|
||||
# Check for WIP commit
|
||||
commit=`git rev-list -n 1 --grep '^WIP' "$range"`
|
||||
if [ -n "$commit" ]
|
||||
then
|
||||
echo >&2 "Found WIP commit in $local_ref, not pushing"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
exit 0
|
|
@ -0,0 +1,169 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2006, 2008 Junio C Hamano
|
||||
#
|
||||
# The "pre-rebase" hook is run just before "git rebase" starts doing
|
||||
# its job, and can prevent the command from running by exiting with
|
||||
# non-zero status.
|
||||
#
|
||||
# The hook is called with the following parameters:
|
||||
#
|
||||
# $1 -- the upstream the series was forked from.
|
||||
# $2 -- the branch being rebased (or empty when rebasing the current branch).
|
||||
#
|
||||
# This sample shows how to prevent topic branches that are already
|
||||
# merged to 'next' branch from getting rebased, because allowing it
|
||||
# would result in rebasing already published history.
|
||||
|
||||
publish=next
|
||||
basebranch="$1"
|
||||
if test "$#" = 2
|
||||
then
|
||||
topic="refs/heads/$2"
|
||||
else
|
||||
topic=`git symbolic-ref HEAD` ||
|
||||
exit 0 ;# we do not interrupt rebasing detached HEAD
|
||||
fi
|
||||
|
||||
case "$topic" in
|
||||
refs/heads/??/*)
|
||||
;;
|
||||
*)
|
||||
exit 0 ;# we do not interrupt others.
|
||||
;;
|
||||
esac
|
||||
|
||||
# Now we are dealing with a topic branch being rebased
|
||||
# on top of master. Is it OK to rebase it?
|
||||
|
||||
# Does the topic really exist?
|
||||
git show-ref -q "$topic" || {
|
||||
echo >&2 "No such branch $topic"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Is topic fully merged to master?
|
||||
not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
|
||||
if test -z "$not_in_master"
|
||||
then
|
||||
echo >&2 "$topic is fully merged to master; better remove it."
|
||||
exit 1 ;# we could allow it, but there is no point.
|
||||
fi
|
||||
|
||||
# Is topic ever merged to next? If so you should not be rebasing it.
|
||||
only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
|
||||
only_next_2=`git rev-list ^master ${publish} | sort`
|
||||
if test "$only_next_1" = "$only_next_2"
|
||||
then
|
||||
not_in_topic=`git rev-list "^$topic" master`
|
||||
if test -z "$not_in_topic"
|
||||
then
|
||||
echo >&2 "$topic is already up-to-date with master"
|
||||
exit 1 ;# we could allow it, but there is no point.
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
|
||||
/usr/bin/perl -e '
|
||||
my $topic = $ARGV[0];
|
||||
my $msg = "* $topic has commits already merged to public branch:\n";
|
||||
my (%not_in_next) = map {
|
||||
/^([0-9a-f]+) /;
|
||||
($1 => 1);
|
||||
} split(/\n/, $ARGV[1]);
|
||||
for my $elem (map {
|
||||
/^([0-9a-f]+) (.*)$/;
|
||||
[$1 => $2];
|
||||
} split(/\n/, $ARGV[2])) {
|
||||
if (!exists $not_in_next{$elem->[0]}) {
|
||||
if ($msg) {
|
||||
print STDERR $msg;
|
||||
undef $msg;
|
||||
}
|
||||
print STDERR " $elem->[1]\n";
|
||||
}
|
||||
}
|
||||
' "$topic" "$not_in_next" "$not_in_master"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
################################################################
|
||||
|
||||
This sample hook safeguards topic branches that have been
|
||||
published from being rewound.
|
||||
|
||||
The workflow assumed here is:
|
||||
|
||||
* Once a topic branch forks from "master", "master" is never
|
||||
merged into it again (either directly or indirectly).
|
||||
|
||||
* Once a topic branch is fully cooked and merged into "master",
|
||||
it is deleted. If you need to build on top of it to correct
|
||||
earlier mistakes, a new topic branch is created by forking at
|
||||
the tip of the "master". This is not strictly necessary, but
|
||||
it makes it easier to keep your history simple.
|
||||
|
||||
* Whenever you need to test or publish your changes to topic
|
||||
branches, merge them into "next" branch.
|
||||
|
||||
The script, being an example, hardcodes the publish branch name
|
||||
to be "next", but it is trivial to make it configurable via
|
||||
$GIT_DIR/config mechanism.
|
||||
|
||||
With this workflow, you would want to know:
|
||||
|
||||
(1) ... if a topic branch has ever been merged to "next". Young
|
||||
topic branches can have stupid mistakes you would rather
|
||||
clean up before publishing, and things that have not been
|
||||
merged into other branches can be easily rebased without
|
||||
affecting other people. But once it is published, you would
|
||||
not want to rewind it.
|
||||
|
||||
(2) ... if a topic branch has been fully merged to "master".
|
||||
Then you can delete it. More importantly, you should not
|
||||
build on top of it -- other people may already want to
|
||||
change things related to the topic as patches against your
|
||||
"master", so if you need further changes, it is better to
|
||||
fork the topic (perhaps with the same name) afresh from the
|
||||
tip of "master".
|
||||
|
||||
Let's look at this example:
|
||||
|
||||
o---o---o---o---o---o---o---o---o---o "next"
|
||||
/ / / /
|
||||
/ a---a---b A / /
|
||||
/ / / /
|
||||
/ / c---c---c---c B /
|
||||
/ / / \ /
|
||||
/ / / b---b C \ /
|
||||
/ / / / \ /
|
||||
---o---o---o---o---o---o---o---o---o---o---o "master"
|
||||
|
||||
|
||||
A, B and C are topic branches.
|
||||
|
||||
* A has one fix since it was merged up to "next".
|
||||
|
||||
* B has finished. It has been fully merged up to "master" and "next",
|
||||
and is ready to be deleted.
|
||||
|
||||
* C has not merged to "next" at all.
|
||||
|
||||
We would want to allow C to be rebased, refuse A, and encourage
|
||||
B to be deleted.
|
||||
|
||||
To compute (1):
|
||||
|
||||
git rev-list ^master ^topic next
|
||||
git rev-list ^master next
|
||||
|
||||
if these match, topic has not merged in next at all.
|
||||
|
||||
To compute (2):
|
||||
|
||||
git rev-list master..topic
|
||||
|
||||
if this is empty, it is fully merged to "master".
|
36
spec/fixtures/repo-with-submodules/git.git/hooks/prepare-commit-msg.sample
поставляемый
Executable file
36
spec/fixtures/repo-with-submodules/git.git/hooks/prepare-commit-msg.sample
поставляемый
Executable file
|
@ -0,0 +1,36 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to prepare the commit log message.
|
||||
# Called by "git commit" with the name of the file that has the
|
||||
# commit message, followed by the description of the commit
|
||||
# message's source. The hook's purpose is to edit the commit
|
||||
# message file. If the hook fails with a non-zero status,
|
||||
# the commit is aborted.
|
||||
#
|
||||
# To enable this hook, rename this file to "prepare-commit-msg".
|
||||
|
||||
# This hook includes three examples. The first comments out the
|
||||
# "Conflicts:" part of a merge commit.
|
||||
#
|
||||
# The second includes the output of "git diff --name-status -r"
|
||||
# into the message, just before the "git status" output. It is
|
||||
# commented because it doesn't cope with --amend or with squashed
|
||||
# commits.
|
||||
#
|
||||
# The third example adds a Signed-off-by line to the message, that can
|
||||
# still be edited. This is rarely a good idea.
|
||||
|
||||
case "$2,$3" in
|
||||
merge,)
|
||||
/usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;
|
||||
|
||||
# ,|template,)
|
||||
# /usr/bin/perl -i.bak -pe '
|
||||
# print "\n" . `git diff --cached --name-status -r`
|
||||
# if /^#/ && $first++ == 0' "$1" ;;
|
||||
|
||||
*) ;;
|
||||
esac
|
||||
|
||||
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
|
||||
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
|
|
@ -0,0 +1,128 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to blocks unannotated tags from entering.
|
||||
# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
|
||||
#
|
||||
# To enable this hook, rename this file to "update".
|
||||
#
|
||||
# Config
|
||||
# ------
|
||||
# hooks.allowunannotated
|
||||
# This boolean sets whether unannotated tags will be allowed into the
|
||||
# repository. By default they won't be.
|
||||
# hooks.allowdeletetag
|
||||
# This boolean sets whether deleting tags will be allowed in the
|
||||
# repository. By default they won't be.
|
||||
# hooks.allowmodifytag
|
||||
# This boolean sets whether a tag may be modified after creation. By default
|
||||
# it won't be.
|
||||
# hooks.allowdeletebranch
|
||||
# This boolean sets whether deleting branches will be allowed in the
|
||||
# repository. By default they won't be.
|
||||
# hooks.denycreatebranch
|
||||
# This boolean sets whether remotely creating branches will be denied
|
||||
# in the repository. By default this is allowed.
|
||||
#
|
||||
|
||||
# --- Command line
|
||||
refname="$1"
|
||||
oldrev="$2"
|
||||
newrev="$3"
|
||||
|
||||
# --- Safety check
|
||||
if [ -z "$GIT_DIR" ]; then
|
||||
echo "Don't run this script from the command line." >&2
|
||||
echo " (if you want, you could supply GIT_DIR then run" >&2
|
||||
echo " $0 <ref> <oldrev> <newrev>)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
|
||||
echo "usage: $0 <ref> <oldrev> <newrev>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Config
|
||||
allowunannotated=$(git config --bool hooks.allowunannotated)
|
||||
allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
|
||||
denycreatebranch=$(git config --bool hooks.denycreatebranch)
|
||||
allowdeletetag=$(git config --bool hooks.allowdeletetag)
|
||||
allowmodifytag=$(git config --bool hooks.allowmodifytag)
|
||||
|
||||
# check for no description
|
||||
projectdesc=$(sed -e '1q' "$GIT_DIR/description")
|
||||
case "$projectdesc" in
|
||||
"Unnamed repository"* | "")
|
||||
echo "*** Project description file hasn't been set" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# --- Check types
|
||||
# if $newrev is 0000...0000, it's a commit to delete a ref.
|
||||
zero="0000000000000000000000000000000000000000"
|
||||
if [ "$newrev" = "$zero" ]; then
|
||||
newrev_type=delete
|
||||
else
|
||||
newrev_type=$(git cat-file -t $newrev)
|
||||
fi
|
||||
|
||||
case "$refname","$newrev_type" in
|
||||
refs/tags/*,commit)
|
||||
# un-annotated tag
|
||||
short_refname=${refname##refs/tags/}
|
||||
if [ "$allowunannotated" != "true" ]; then
|
||||
echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
|
||||
echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/tags/*,delete)
|
||||
# delete tag
|
||||
if [ "$allowdeletetag" != "true" ]; then
|
||||
echo "*** Deleting a tag is not allowed in this repository" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/tags/*,tag)
|
||||
# annotated tag
|
||||
if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
|
||||
then
|
||||
echo "*** Tag '$refname' already exists." >&2
|
||||
echo "*** Modifying a tag is not allowed in this repository." >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/heads/*,commit)
|
||||
# branch
|
||||
if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
|
||||
echo "*** Creating a branch is not allowed in this repository" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/heads/*,delete)
|
||||
# delete branch
|
||||
if [ "$allowdeletebranch" != "true" ]; then
|
||||
echo "*** Deleting a branch is not allowed in this repository" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/remotes/*,commit)
|
||||
# tracking branch
|
||||
;;
|
||||
refs/remotes/*,delete)
|
||||
# delete tracking branch
|
||||
if [ "$allowdeletebranch" != "true" ]; then
|
||||
echo "*** Deleting a tracking branch is not allowed in this repository" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
# Anything else (is there anything else?)
|
||||
echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# --- Finished
|
||||
exit 0
|
Двоичный файл не отображается.
|
@ -0,0 +1,6 @@
|
|||
# git ls-files --others --exclude-from=.git/info/exclude
|
||||
# Lines that start with '#' are comments.
|
||||
# For a project mostly in C, the following would be a good set of
|
||||
# exclude patterns (uncomment them if you want to use them):
|
||||
# *.[oa]
|
||||
# *~
|
|
@ -0,0 +1,2 @@
|
|||
0000000000000000000000000000000000000000 d3e073baf592c56614c68ead9e2cd0a3880140cd joshaber <joshaber@gmail.com> 1452185922 -0500 commit (initial): first
|
||||
d3e073baf592c56614c68ead9e2cd0a3880140cd d2b0ad9cbc6f6c4372e8956e5cc5af771b2342e5 joshaber <joshaber@gmail.com> 1452186239 -0500 commit: submodules
|
|
@ -0,0 +1,2 @@
|
|||
0000000000000000000000000000000000000000 d3e073baf592c56614c68ead9e2cd0a3880140cd joshaber <joshaber@gmail.com> 1452185922 -0500 commit (initial): first
|
||||
d3e073baf592c56614c68ead9e2cd0a3880140cd d2b0ad9cbc6f6c4372e8956e5cc5af771b2342e5 joshaber <joshaber@gmail.com> 1452186239 -0500 commit: submodules
|
9
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/COMMIT_EDITMSG
поставляемый
Normal file
9
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/COMMIT_EDITMSG
поставляемый
Normal file
|
@ -0,0 +1,9 @@
|
|||
whitespace is nicespace
|
||||
# Please enter the commit message for your changes. Lines starting
|
||||
# with '#' will be ignored, and an empty message aborts the commit.
|
||||
# On branch master
|
||||
# Your branch is up-to-date with 'origin/master'.
|
||||
#
|
||||
# Changes to be committed:
|
||||
# modified: README.md
|
||||
#
|
1
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/HEAD
поставляемый
Normal file
1
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/HEAD
поставляемый
Normal file
|
@ -0,0 +1 @@
|
|||
ref: refs/heads/master
|
1
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/ORIG_HEAD
поставляемый
Normal file
1
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/ORIG_HEAD
поставляемый
Normal file
|
@ -0,0 +1 @@
|
|||
2e9bbc77d60f20eb462ead5b2ac7405b62b9b90a
|
14
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/config
поставляемый
Normal file
14
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/config
поставляемый
Normal file
|
@ -0,0 +1,14 @@
|
|||
[core]
|
||||
repositoryformatversion = 0
|
||||
filemode = true
|
||||
bare = false
|
||||
logallrefupdates = true
|
||||
worktree = ../../../You-Dont-Need-jQuery
|
||||
ignorecase = true
|
||||
precomposeunicode = true
|
||||
[remote "origin"]
|
||||
url = https://github.com/oneuijs/You-Dont-Need-jQuery
|
||||
fetch = +refs/heads/*:refs/remotes/origin/*
|
||||
[branch "master"]
|
||||
remote = origin
|
||||
merge = refs/heads/master
|
1
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/description
поставляемый
Normal file
1
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/description
поставляемый
Normal file
|
@ -0,0 +1 @@
|
|||
Unnamed repository; edit this file 'description' to name the repository.
|
1
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/gitdir
поставляемый
Normal file
1
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/gitdir
поставляемый
Normal file
|
@ -0,0 +1 @@
|
|||
.git
|
15
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/hooks/applypatch-msg.sample
поставляемый
Executable file
15
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/hooks/applypatch-msg.sample
поставляемый
Executable file
|
@ -0,0 +1,15 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to check the commit log message taken by
|
||||
# applypatch from an e-mail message.
|
||||
#
|
||||
# The hook should exit with non-zero status after issuing an
|
||||
# appropriate message if it wants to stop the commit. The hook is
|
||||
# allowed to edit the commit message file.
|
||||
#
|
||||
# To enable this hook, rename this file to "applypatch-msg".
|
||||
|
||||
. git-sh-setup
|
||||
commitmsg="$(git rev-parse --git-path hooks/commit-msg)"
|
||||
test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"}
|
||||
:
|
24
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/hooks/commit-msg.sample
поставляемый
Executable file
24
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/hooks/commit-msg.sample
поставляемый
Executable file
|
@ -0,0 +1,24 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to check the commit log message.
|
||||
# Called by "git commit" with one argument, the name of the file
|
||||
# that has the commit message. The hook should exit with non-zero
|
||||
# status after issuing an appropriate message if it wants to stop the
|
||||
# commit. The hook is allowed to edit the commit message file.
|
||||
#
|
||||
# To enable this hook, rename this file to "commit-msg".
|
||||
|
||||
# Uncomment the below to add a Signed-off-by line to the message.
|
||||
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
|
||||
# hook is more suited to it.
|
||||
#
|
||||
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
|
||||
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
|
||||
|
||||
# This example catches duplicate Signed-off-by lines.
|
||||
|
||||
test "" = "$(grep '^Signed-off-by: ' "$1" |
|
||||
sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || {
|
||||
echo >&2 Duplicate Signed-off-by lines.
|
||||
exit 1
|
||||
}
|
8
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/hooks/post-update.sample
поставляемый
Executable file
8
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/hooks/post-update.sample
поставляемый
Executable file
|
@ -0,0 +1,8 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to prepare a packed repository for use over
|
||||
# dumb transports.
|
||||
#
|
||||
# To enable this hook, rename this file to "post-update".
|
||||
|
||||
exec git update-server-info
|
14
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/hooks/pre-applypatch.sample
поставляемый
Executable file
14
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/hooks/pre-applypatch.sample
поставляемый
Executable file
|
@ -0,0 +1,14 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to verify what is about to be committed
|
||||
# by applypatch from an e-mail message.
|
||||
#
|
||||
# The hook should exit with non-zero status after issuing an
|
||||
# appropriate message if it wants to stop the commit.
|
||||
#
|
||||
# To enable this hook, rename this file to "pre-applypatch".
|
||||
|
||||
. git-sh-setup
|
||||
precommit="$(git rev-parse --git-path hooks/pre-commit)"
|
||||
test -x "$precommit" && exec "$precommit" ${1+"$@"}
|
||||
:
|
49
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/hooks/pre-commit.sample
поставляемый
Executable file
49
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/hooks/pre-commit.sample
поставляемый
Executable file
|
@ -0,0 +1,49 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to verify what is about to be committed.
|
||||
# Called by "git commit" with no arguments. The hook should
|
||||
# exit with non-zero status after issuing an appropriate message if
|
||||
# it wants to stop the commit.
|
||||
#
|
||||
# To enable this hook, rename this file to "pre-commit".
|
||||
|
||||
if git rev-parse --verify HEAD >/dev/null 2>&1
|
||||
then
|
||||
against=HEAD
|
||||
else
|
||||
# Initial commit: diff against an empty tree object
|
||||
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
|
||||
fi
|
||||
|
||||
# If you want to allow non-ASCII filenames set this variable to true.
|
||||
allownonascii=$(git config --bool hooks.allownonascii)
|
||||
|
||||
# Redirect output to stderr.
|
||||
exec 1>&2
|
||||
|
||||
# Cross platform projects tend to avoid non-ASCII filenames; prevent
|
||||
# them from being added to the repository. We exploit the fact that the
|
||||
# printable range starts at the space character and ends with tilde.
|
||||
if [ "$allownonascii" != "true" ] &&
|
||||
# Note that the use of brackets around a tr range is ok here, (it's
|
||||
# even required, for portability to Solaris 10's /usr/bin/tr), since
|
||||
# the square bracket bytes happen to fall in the designated range.
|
||||
test $(git diff --cached --name-only --diff-filter=A -z $against |
|
||||
LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
|
||||
then
|
||||
cat <<\EOF
|
||||
Error: Attempt to add a non-ASCII file name.
|
||||
|
||||
This can cause problems if you want to work with people on other platforms.
|
||||
|
||||
To be portable it is advisable to rename the file.
|
||||
|
||||
If you know what you are doing you can disable this check using:
|
||||
|
||||
git config hooks.allownonascii true
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# If there are whitespace errors, print the offending file names and fail.
|
||||
exec git diff-index --check --cached $against --
|
53
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/hooks/pre-push.sample
поставляемый
Executable file
53
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/hooks/pre-push.sample
поставляемый
Executable file
|
@ -0,0 +1,53 @@
|
|||
#!/bin/sh
|
||||
|
||||
# An example hook script to verify what is about to be pushed. Called by "git
|
||||
# push" after it has checked the remote status, but before anything has been
|
||||
# pushed. If this script exits with a non-zero status nothing will be pushed.
|
||||
#
|
||||
# This hook is called with the following parameters:
|
||||
#
|
||||
# $1 -- Name of the remote to which the push is being done
|
||||
# $2 -- URL to which the push is being done
|
||||
#
|
||||
# If pushing without using a named remote those arguments will be equal.
|
||||
#
|
||||
# Information about the commits which are being pushed is supplied as lines to
|
||||
# the standard input in the form:
|
||||
#
|
||||
# <local ref> <local sha1> <remote ref> <remote sha1>
|
||||
#
|
||||
# This sample shows how to prevent push of commits where the log message starts
|
||||
# with "WIP" (work in progress).
|
||||
|
||||
remote="$1"
|
||||
url="$2"
|
||||
|
||||
z40=0000000000000000000000000000000000000000
|
||||
|
||||
while read local_ref local_sha remote_ref remote_sha
|
||||
do
|
||||
if [ "$local_sha" = $z40 ]
|
||||
then
|
||||
# Handle delete
|
||||
:
|
||||
else
|
||||
if [ "$remote_sha" = $z40 ]
|
||||
then
|
||||
# New branch, examine all commits
|
||||
range="$local_sha"
|
||||
else
|
||||
# Update to existing branch, examine new commits
|
||||
range="$remote_sha..$local_sha"
|
||||
fi
|
||||
|
||||
# Check for WIP commit
|
||||
commit=`git rev-list -n 1 --grep '^WIP' "$range"`
|
||||
if [ -n "$commit" ]
|
||||
then
|
||||
echo >&2 "Found WIP commit in $local_ref, not pushing"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
exit 0
|
169
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/hooks/pre-rebase.sample
поставляемый
Executable file
169
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/hooks/pre-rebase.sample
поставляемый
Executable file
|
@ -0,0 +1,169 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2006, 2008 Junio C Hamano
|
||||
#
|
||||
# The "pre-rebase" hook is run just before "git rebase" starts doing
|
||||
# its job, and can prevent the command from running by exiting with
|
||||
# non-zero status.
|
||||
#
|
||||
# The hook is called with the following parameters:
|
||||
#
|
||||
# $1 -- the upstream the series was forked from.
|
||||
# $2 -- the branch being rebased (or empty when rebasing the current branch).
|
||||
#
|
||||
# This sample shows how to prevent topic branches that are already
|
||||
# merged to 'next' branch from getting rebased, because allowing it
|
||||
# would result in rebasing already published history.
|
||||
|
||||
publish=next
|
||||
basebranch="$1"
|
||||
if test "$#" = 2
|
||||
then
|
||||
topic="refs/heads/$2"
|
||||
else
|
||||
topic=`git symbolic-ref HEAD` ||
|
||||
exit 0 ;# we do not interrupt rebasing detached HEAD
|
||||
fi
|
||||
|
||||
case "$topic" in
|
||||
refs/heads/??/*)
|
||||
;;
|
||||
*)
|
||||
exit 0 ;# we do not interrupt others.
|
||||
;;
|
||||
esac
|
||||
|
||||
# Now we are dealing with a topic branch being rebased
|
||||
# on top of master. Is it OK to rebase it?
|
||||
|
||||
# Does the topic really exist?
|
||||
git show-ref -q "$topic" || {
|
||||
echo >&2 "No such branch $topic"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Is topic fully merged to master?
|
||||
not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
|
||||
if test -z "$not_in_master"
|
||||
then
|
||||
echo >&2 "$topic is fully merged to master; better remove it."
|
||||
exit 1 ;# we could allow it, but there is no point.
|
||||
fi
|
||||
|
||||
# Is topic ever merged to next? If so you should not be rebasing it.
|
||||
only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
|
||||
only_next_2=`git rev-list ^master ${publish} | sort`
|
||||
if test "$only_next_1" = "$only_next_2"
|
||||
then
|
||||
not_in_topic=`git rev-list "^$topic" master`
|
||||
if test -z "$not_in_topic"
|
||||
then
|
||||
echo >&2 "$topic is already up-to-date with master"
|
||||
exit 1 ;# we could allow it, but there is no point.
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
|
||||
/usr/bin/perl -e '
|
||||
my $topic = $ARGV[0];
|
||||
my $msg = "* $topic has commits already merged to public branch:\n";
|
||||
my (%not_in_next) = map {
|
||||
/^([0-9a-f]+) /;
|
||||
($1 => 1);
|
||||
} split(/\n/, $ARGV[1]);
|
||||
for my $elem (map {
|
||||
/^([0-9a-f]+) (.*)$/;
|
||||
[$1 => $2];
|
||||
} split(/\n/, $ARGV[2])) {
|
||||
if (!exists $not_in_next{$elem->[0]}) {
|
||||
if ($msg) {
|
||||
print STDERR $msg;
|
||||
undef $msg;
|
||||
}
|
||||
print STDERR " $elem->[1]\n";
|
||||
}
|
||||
}
|
||||
' "$topic" "$not_in_next" "$not_in_master"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
################################################################
|
||||
|
||||
This sample hook safeguards topic branches that have been
|
||||
published from being rewound.
|
||||
|
||||
The workflow assumed here is:
|
||||
|
||||
* Once a topic branch forks from "master", "master" is never
|
||||
merged into it again (either directly or indirectly).
|
||||
|
||||
* Once a topic branch is fully cooked and merged into "master",
|
||||
it is deleted. If you need to build on top of it to correct
|
||||
earlier mistakes, a new topic branch is created by forking at
|
||||
the tip of the "master". This is not strictly necessary, but
|
||||
it makes it easier to keep your history simple.
|
||||
|
||||
* Whenever you need to test or publish your changes to topic
|
||||
branches, merge them into "next" branch.
|
||||
|
||||
The script, being an example, hardcodes the publish branch name
|
||||
to be "next", but it is trivial to make it configurable via
|
||||
$GIT_DIR/config mechanism.
|
||||
|
||||
With this workflow, you would want to know:
|
||||
|
||||
(1) ... if a topic branch has ever been merged to "next". Young
|
||||
topic branches can have stupid mistakes you would rather
|
||||
clean up before publishing, and things that have not been
|
||||
merged into other branches can be easily rebased without
|
||||
affecting other people. But once it is published, you would
|
||||
not want to rewind it.
|
||||
|
||||
(2) ... if a topic branch has been fully merged to "master".
|
||||
Then you can delete it. More importantly, you should not
|
||||
build on top of it -- other people may already want to
|
||||
change things related to the topic as patches against your
|
||||
"master", so if you need further changes, it is better to
|
||||
fork the topic (perhaps with the same name) afresh from the
|
||||
tip of "master".
|
||||
|
||||
Let's look at this example:
|
||||
|
||||
o---o---o---o---o---o---o---o---o---o "next"
|
||||
/ / / /
|
||||
/ a---a---b A / /
|
||||
/ / / /
|
||||
/ / c---c---c---c B /
|
||||
/ / / \ /
|
||||
/ / / b---b C \ /
|
||||
/ / / / \ /
|
||||
---o---o---o---o---o---o---o---o---o---o---o "master"
|
||||
|
||||
|
||||
A, B and C are topic branches.
|
||||
|
||||
* A has one fix since it was merged up to "next".
|
||||
|
||||
* B has finished. It has been fully merged up to "master" and "next",
|
||||
and is ready to be deleted.
|
||||
|
||||
* C has not merged to "next" at all.
|
||||
|
||||
We would want to allow C to be rebased, refuse A, and encourage
|
||||
B to be deleted.
|
||||
|
||||
To compute (1):
|
||||
|
||||
git rev-list ^master ^topic next
|
||||
git rev-list ^master next
|
||||
|
||||
if these match, topic has not merged in next at all.
|
||||
|
||||
To compute (2):
|
||||
|
||||
git rev-list master..topic
|
||||
|
||||
if this is empty, it is fully merged to "master".
|
36
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/hooks/prepare-commit-msg.sample
поставляемый
Executable file
36
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/hooks/prepare-commit-msg.sample
поставляемый
Executable file
|
@ -0,0 +1,36 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to prepare the commit log message.
|
||||
# Called by "git commit" with the name of the file that has the
|
||||
# commit message, followed by the description of the commit
|
||||
# message's source. The hook's purpose is to edit the commit
|
||||
# message file. If the hook fails with a non-zero status,
|
||||
# the commit is aborted.
|
||||
#
|
||||
# To enable this hook, rename this file to "prepare-commit-msg".
|
||||
|
||||
# This hook includes three examples. The first comments out the
|
||||
# "Conflicts:" part of a merge commit.
|
||||
#
|
||||
# The second includes the output of "git diff --name-status -r"
|
||||
# into the message, just before the "git status" output. It is
|
||||
# commented because it doesn't cope with --amend or with squashed
|
||||
# commits.
|
||||
#
|
||||
# The third example adds a Signed-off-by line to the message, that can
|
||||
# still be edited. This is rarely a good idea.
|
||||
|
||||
case "$2,$3" in
|
||||
merge,)
|
||||
/usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;
|
||||
|
||||
# ,|template,)
|
||||
# /usr/bin/perl -i.bak -pe '
|
||||
# print "\n" . `git diff --cached --name-status -r`
|
||||
# if /^#/ && $first++ == 0' "$1" ;;
|
||||
|
||||
*) ;;
|
||||
esac
|
||||
|
||||
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
|
||||
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
|
128
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/hooks/update.sample
поставляемый
Executable file
128
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/hooks/update.sample
поставляемый
Executable file
|
@ -0,0 +1,128 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to blocks unannotated tags from entering.
|
||||
# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
|
||||
#
|
||||
# To enable this hook, rename this file to "update".
|
||||
#
|
||||
# Config
|
||||
# ------
|
||||
# hooks.allowunannotated
|
||||
# This boolean sets whether unannotated tags will be allowed into the
|
||||
# repository. By default they won't be.
|
||||
# hooks.allowdeletetag
|
||||
# This boolean sets whether deleting tags will be allowed in the
|
||||
# repository. By default they won't be.
|
||||
# hooks.allowmodifytag
|
||||
# This boolean sets whether a tag may be modified after creation. By default
|
||||
# it won't be.
|
||||
# hooks.allowdeletebranch
|
||||
# This boolean sets whether deleting branches will be allowed in the
|
||||
# repository. By default they won't be.
|
||||
# hooks.denycreatebranch
|
||||
# This boolean sets whether remotely creating branches will be denied
|
||||
# in the repository. By default this is allowed.
|
||||
#
|
||||
|
||||
# --- Command line
|
||||
refname="$1"
|
||||
oldrev="$2"
|
||||
newrev="$3"
|
||||
|
||||
# --- Safety check
|
||||
if [ -z "$GIT_DIR" ]; then
|
||||
echo "Don't run this script from the command line." >&2
|
||||
echo " (if you want, you could supply GIT_DIR then run" >&2
|
||||
echo " $0 <ref> <oldrev> <newrev>)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
|
||||
echo "usage: $0 <ref> <oldrev> <newrev>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Config
|
||||
allowunannotated=$(git config --bool hooks.allowunannotated)
|
||||
allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
|
||||
denycreatebranch=$(git config --bool hooks.denycreatebranch)
|
||||
allowdeletetag=$(git config --bool hooks.allowdeletetag)
|
||||
allowmodifytag=$(git config --bool hooks.allowmodifytag)
|
||||
|
||||
# check for no description
|
||||
projectdesc=$(sed -e '1q' "$GIT_DIR/description")
|
||||
case "$projectdesc" in
|
||||
"Unnamed repository"* | "")
|
||||
echo "*** Project description file hasn't been set" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# --- Check types
|
||||
# if $newrev is 0000...0000, it's a commit to delete a ref.
|
||||
zero="0000000000000000000000000000000000000000"
|
||||
if [ "$newrev" = "$zero" ]; then
|
||||
newrev_type=delete
|
||||
else
|
||||
newrev_type=$(git cat-file -t $newrev)
|
||||
fi
|
||||
|
||||
case "$refname","$newrev_type" in
|
||||
refs/tags/*,commit)
|
||||
# un-annotated tag
|
||||
short_refname=${refname##refs/tags/}
|
||||
if [ "$allowunannotated" != "true" ]; then
|
||||
echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
|
||||
echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/tags/*,delete)
|
||||
# delete tag
|
||||
if [ "$allowdeletetag" != "true" ]; then
|
||||
echo "*** Deleting a tag is not allowed in this repository" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/tags/*,tag)
|
||||
# annotated tag
|
||||
if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
|
||||
then
|
||||
echo "*** Tag '$refname' already exists." >&2
|
||||
echo "*** Modifying a tag is not allowed in this repository." >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/heads/*,commit)
|
||||
# branch
|
||||
if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
|
||||
echo "*** Creating a branch is not allowed in this repository" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/heads/*,delete)
|
||||
# delete branch
|
||||
if [ "$allowdeletebranch" != "true" ]; then
|
||||
echo "*** Deleting a branch is not allowed in this repository" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/remotes/*,commit)
|
||||
# tracking branch
|
||||
;;
|
||||
refs/remotes/*,delete)
|
||||
# delete tracking branch
|
||||
if [ "$allowdeletebranch" != "true" ]; then
|
||||
echo "*** Deleting a tracking branch is not allowed in this repository" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
# Anything else (is there anything else?)
|
||||
echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# --- Finished
|
||||
exit 0
|
Двоичные данные
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/index
поставляемый
Normal file
Двоичные данные
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/index
поставляемый
Normal file
Двоичный файл не отображается.
6
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/info/exclude
поставляемый
Normal file
6
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/info/exclude
поставляемый
Normal file
|
@ -0,0 +1,6 @@
|
|||
# git ls-files --others --exclude-from=.git/info/exclude
|
||||
# Lines that start with '#' are comments.
|
||||
# For a project mostly in C, the following would be a good set of
|
||||
# exclude patterns (uncomment them if you want to use them):
|
||||
# *.[oa]
|
||||
# *~
|
2
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/logs/HEAD
поставляемый
Normal file
2
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/logs/HEAD
поставляемый
Normal file
|
@ -0,0 +1,2 @@
|
|||
0000000000000000000000000000000000000000 2e9bbc77d60f20eb462ead5b2ac7405b62b9b90a joshaber <joshaber@gmail.com> 1452186236 -0500 clone: from https://github.com/oneuijs/You-Dont-Need-jQuery
|
||||
2e9bbc77d60f20eb462ead5b2ac7405b62b9b90a a78b35a896b890f0a2a4f1f924c5739776415250 joshaber <joshaber@gmail.com> 1452202510 -0500 commit: whitespace is nicespace
|
2
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/logs/refs/heads/master
поставляемый
Normal file
2
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/logs/refs/heads/master
поставляемый
Normal file
|
@ -0,0 +1,2 @@
|
|||
0000000000000000000000000000000000000000 2e9bbc77d60f20eb462ead5b2ac7405b62b9b90a joshaber <joshaber@gmail.com> 1452186236 -0500 clone: from https://github.com/oneuijs/You-Dont-Need-jQuery
|
||||
2e9bbc77d60f20eb462ead5b2ac7405b62b9b90a a78b35a896b890f0a2a4f1f924c5739776415250 joshaber <joshaber@gmail.com> 1452202510 -0500 commit: whitespace is nicespace
|
1
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/logs/refs/remotes/origin/HEAD
поставляемый
Normal file
1
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/logs/refs/remotes/origin/HEAD
поставляемый
Normal file
|
@ -0,0 +1 @@
|
|||
0000000000000000000000000000000000000000 2e9bbc77d60f20eb462ead5b2ac7405b62b9b90a joshaber <joshaber@gmail.com> 1452186236 -0500 clone: from https://github.com/oneuijs/You-Dont-Need-jQuery
|
|
@ -0,0 +1,2 @@
|
|||
x<01>ŽQ
|
||||
Â0DýÎ)re»m’D¼Êîfk#¶)mÄë<1B>þû73¼aFò<§b±…SÙT-k¯± è¡é\ÄxtäÆ®B¤žÚq0+mºÔ¢ÌBô0"(w•¢c$ 8öÈ@†ÞeÊ›}æ}"ÖÍ^uÌ”^ÉóÍÖ=D@×€=ƒ05÷JåüÏ¢ùL©è¾’¨M»]’üŒùÁÞJ|
|
Двоичные данные
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/objects/ae/897dce6e0590f08dddfe9a5152e237e955ca57
поставляемый
Normal file
Двоичные данные
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/objects/ae/897dce6e0590f08dddfe9a5152e237e955ca57
поставляемый
Normal file
Двоичный файл не отображается.
Двоичные данные
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/objects/be/8ed228c0a080145d28ed625a5f487caae6a3f9
поставляемый
Normal file
Двоичные данные
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/objects/be/8ed228c0a080145d28ed625a5f487caae6a3f9
поставляемый
Normal file
Двоичный файл не отображается.
Двоичные данные
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/objects/pack/pack-d38b3bc339acd655e8dae9c0dcea8bb2ec174d16.idx
поставляемый
Normal file
Двоичные данные
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/objects/pack/pack-d38b3bc339acd655e8dae9c0dcea8bb2ec174d16.idx
поставляемый
Normal file
Двоичный файл не отображается.
Двоичные данные
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/objects/pack/pack-d38b3bc339acd655e8dae9c0dcea8bb2ec174d16.pack
поставляемый
Normal file
Двоичные данные
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/objects/pack/pack-d38b3bc339acd655e8dae9c0dcea8bb2ec174d16.pack
поставляемый
Normal file
Двоичный файл не отображается.
2
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/packed-refs
поставляемый
Normal file
2
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/packed-refs
поставляемый
Normal file
|
@ -0,0 +1,2 @@
|
|||
# pack-refs with: peeled fully-peeled
|
||||
2e9bbc77d60f20eb462ead5b2ac7405b62b9b90a refs/remotes/origin/master
|
1
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/refs/heads/master
поставляемый
Normal file
1
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/refs/heads/master
поставляемый
Normal file
|
@ -0,0 +1 @@
|
|||
a78b35a896b890f0a2a4f1f924c5739776415250
|
1
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/refs/remotes/origin/HEAD
поставляемый
Normal file
1
spec/fixtures/repo-with-submodules/git.git/modules/You-Dont-Need-jQuery/refs/remotes/origin/HEAD
поставляемый
Normal file
|
@ -0,0 +1 @@
|
|||
ref: refs/remotes/origin/master
|
|
@ -0,0 +1,7 @@
|
|||
whitespace is nicespace
|
||||
# Please enter the commit message for your changes. Lines starting
|
||||
# with '#' will be ignored, and an empty message aborts the commit.
|
||||
# On branch test
|
||||
# Changes to be committed:
|
||||
# modified: README.md
|
||||
#
|
|
@ -0,0 +1 @@
|
|||
ref: refs/heads/test
|
|
@ -0,0 +1 @@
|
|||
9f0218b7652b622afea799a4723490c43e1af1fe
|
|
@ -0,0 +1,14 @@
|
|||
[core]
|
||||
repositoryformatversion = 0
|
||||
filemode = true
|
||||
bare = false
|
||||
logallrefupdates = true
|
||||
worktree = ../../../jstips
|
||||
ignorecase = true
|
||||
precomposeunicode = true
|
||||
[remote "origin"]
|
||||
url = https://github.com/loverajoel/jstips
|
||||
fetch = +refs/heads/*:refs/remotes/origin/*
|
||||
[branch "master"]
|
||||
remote = origin
|
||||
merge = refs/heads/master
|
|
@ -0,0 +1 @@
|
|||
Unnamed repository; edit this file 'description' to name the repository.
|
|
@ -0,0 +1 @@
|
|||
.git
|
15
spec/fixtures/repo-with-submodules/git.git/modules/jstips/hooks/applypatch-msg.sample
поставляемый
Executable file
15
spec/fixtures/repo-with-submodules/git.git/modules/jstips/hooks/applypatch-msg.sample
поставляемый
Executable file
|
@ -0,0 +1,15 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to check the commit log message taken by
|
||||
# applypatch from an e-mail message.
|
||||
#
|
||||
# The hook should exit with non-zero status after issuing an
|
||||
# appropriate message if it wants to stop the commit. The hook is
|
||||
# allowed to edit the commit message file.
|
||||
#
|
||||
# To enable this hook, rename this file to "applypatch-msg".
|
||||
|
||||
. git-sh-setup
|
||||
commitmsg="$(git rev-parse --git-path hooks/commit-msg)"
|
||||
test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"}
|
||||
:
|
24
spec/fixtures/repo-with-submodules/git.git/modules/jstips/hooks/commit-msg.sample
поставляемый
Executable file
24
spec/fixtures/repo-with-submodules/git.git/modules/jstips/hooks/commit-msg.sample
поставляемый
Executable file
|
@ -0,0 +1,24 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to check the commit log message.
|
||||
# Called by "git commit" with one argument, the name of the file
|
||||
# that has the commit message. The hook should exit with non-zero
|
||||
# status after issuing an appropriate message if it wants to stop the
|
||||
# commit. The hook is allowed to edit the commit message file.
|
||||
#
|
||||
# To enable this hook, rename this file to "commit-msg".
|
||||
|
||||
# Uncomment the below to add a Signed-off-by line to the message.
|
||||
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
|
||||
# hook is more suited to it.
|
||||
#
|
||||
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
|
||||
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
|
||||
|
||||
# This example catches duplicate Signed-off-by lines.
|
||||
|
||||
test "" = "$(grep '^Signed-off-by: ' "$1" |
|
||||
sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || {
|
||||
echo >&2 Duplicate Signed-off-by lines.
|
||||
exit 1
|
||||
}
|
8
spec/fixtures/repo-with-submodules/git.git/modules/jstips/hooks/post-update.sample
поставляемый
Executable file
8
spec/fixtures/repo-with-submodules/git.git/modules/jstips/hooks/post-update.sample
поставляемый
Executable file
|
@ -0,0 +1,8 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to prepare a packed repository for use over
|
||||
# dumb transports.
|
||||
#
|
||||
# To enable this hook, rename this file to "post-update".
|
||||
|
||||
exec git update-server-info
|
14
spec/fixtures/repo-with-submodules/git.git/modules/jstips/hooks/pre-applypatch.sample
поставляемый
Executable file
14
spec/fixtures/repo-with-submodules/git.git/modules/jstips/hooks/pre-applypatch.sample
поставляемый
Executable file
|
@ -0,0 +1,14 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to verify what is about to be committed
|
||||
# by applypatch from an e-mail message.
|
||||
#
|
||||
# The hook should exit with non-zero status after issuing an
|
||||
# appropriate message if it wants to stop the commit.
|
||||
#
|
||||
# To enable this hook, rename this file to "pre-applypatch".
|
||||
|
||||
. git-sh-setup
|
||||
precommit="$(git rev-parse --git-path hooks/pre-commit)"
|
||||
test -x "$precommit" && exec "$precommit" ${1+"$@"}
|
||||
:
|
49
spec/fixtures/repo-with-submodules/git.git/modules/jstips/hooks/pre-commit.sample
поставляемый
Executable file
49
spec/fixtures/repo-with-submodules/git.git/modules/jstips/hooks/pre-commit.sample
поставляемый
Executable file
|
@ -0,0 +1,49 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to verify what is about to be committed.
|
||||
# Called by "git commit" with no arguments. The hook should
|
||||
# exit with non-zero status after issuing an appropriate message if
|
||||
# it wants to stop the commit.
|
||||
#
|
||||
# To enable this hook, rename this file to "pre-commit".
|
||||
|
||||
if git rev-parse --verify HEAD >/dev/null 2>&1
|
||||
then
|
||||
against=HEAD
|
||||
else
|
||||
# Initial commit: diff against an empty tree object
|
||||
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
|
||||
fi
|
||||
|
||||
# If you want to allow non-ASCII filenames set this variable to true.
|
||||
allownonascii=$(git config --bool hooks.allownonascii)
|
||||
|
||||
# Redirect output to stderr.
|
||||
exec 1>&2
|
||||
|
||||
# Cross platform projects tend to avoid non-ASCII filenames; prevent
|
||||
# them from being added to the repository. We exploit the fact that the
|
||||
# printable range starts at the space character and ends with tilde.
|
||||
if [ "$allownonascii" != "true" ] &&
|
||||
# Note that the use of brackets around a tr range is ok here, (it's
|
||||
# even required, for portability to Solaris 10's /usr/bin/tr), since
|
||||
# the square bracket bytes happen to fall in the designated range.
|
||||
test $(git diff --cached --name-only --diff-filter=A -z $against |
|
||||
LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
|
||||
then
|
||||
cat <<\EOF
|
||||
Error: Attempt to add a non-ASCII file name.
|
||||
|
||||
This can cause problems if you want to work with people on other platforms.
|
||||
|
||||
To be portable it is advisable to rename the file.
|
||||
|
||||
If you know what you are doing you can disable this check using:
|
||||
|
||||
git config hooks.allownonascii true
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# If there are whitespace errors, print the offending file names and fail.
|
||||
exec git diff-index --check --cached $against --
|
53
spec/fixtures/repo-with-submodules/git.git/modules/jstips/hooks/pre-push.sample
поставляемый
Executable file
53
spec/fixtures/repo-with-submodules/git.git/modules/jstips/hooks/pre-push.sample
поставляемый
Executable file
|
@ -0,0 +1,53 @@
|
|||
#!/bin/sh
|
||||
|
||||
# An example hook script to verify what is about to be pushed. Called by "git
|
||||
# push" after it has checked the remote status, but before anything has been
|
||||
# pushed. If this script exits with a non-zero status nothing will be pushed.
|
||||
#
|
||||
# This hook is called with the following parameters:
|
||||
#
|
||||
# $1 -- Name of the remote to which the push is being done
|
||||
# $2 -- URL to which the push is being done
|
||||
#
|
||||
# If pushing without using a named remote those arguments will be equal.
|
||||
#
|
||||
# Information about the commits which are being pushed is supplied as lines to
|
||||
# the standard input in the form:
|
||||
#
|
||||
# <local ref> <local sha1> <remote ref> <remote sha1>
|
||||
#
|
||||
# This sample shows how to prevent push of commits where the log message starts
|
||||
# with "WIP" (work in progress).
|
||||
|
||||
remote="$1"
|
||||
url="$2"
|
||||
|
||||
z40=0000000000000000000000000000000000000000
|
||||
|
||||
while read local_ref local_sha remote_ref remote_sha
|
||||
do
|
||||
if [ "$local_sha" = $z40 ]
|
||||
then
|
||||
# Handle delete
|
||||
:
|
||||
else
|
||||
if [ "$remote_sha" = $z40 ]
|
||||
then
|
||||
# New branch, examine all commits
|
||||
range="$local_sha"
|
||||
else
|
||||
# Update to existing branch, examine new commits
|
||||
range="$remote_sha..$local_sha"
|
||||
fi
|
||||
|
||||
# Check for WIP commit
|
||||
commit=`git rev-list -n 1 --grep '^WIP' "$range"`
|
||||
if [ -n "$commit" ]
|
||||
then
|
||||
echo >&2 "Found WIP commit in $local_ref, not pushing"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
exit 0
|
169
spec/fixtures/repo-with-submodules/git.git/modules/jstips/hooks/pre-rebase.sample
поставляемый
Executable file
169
spec/fixtures/repo-with-submodules/git.git/modules/jstips/hooks/pre-rebase.sample
поставляемый
Executable file
|
@ -0,0 +1,169 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2006, 2008 Junio C Hamano
|
||||
#
|
||||
# The "pre-rebase" hook is run just before "git rebase" starts doing
|
||||
# its job, and can prevent the command from running by exiting with
|
||||
# non-zero status.
|
||||
#
|
||||
# The hook is called with the following parameters:
|
||||
#
|
||||
# $1 -- the upstream the series was forked from.
|
||||
# $2 -- the branch being rebased (or empty when rebasing the current branch).
|
||||
#
|
||||
# This sample shows how to prevent topic branches that are already
|
||||
# merged to 'next' branch from getting rebased, because allowing it
|
||||
# would result in rebasing already published history.
|
||||
|
||||
publish=next
|
||||
basebranch="$1"
|
||||
if test "$#" = 2
|
||||
then
|
||||
topic="refs/heads/$2"
|
||||
else
|
||||
topic=`git symbolic-ref HEAD` ||
|
||||
exit 0 ;# we do not interrupt rebasing detached HEAD
|
||||
fi
|
||||
|
||||
case "$topic" in
|
||||
refs/heads/??/*)
|
||||
;;
|
||||
*)
|
||||
exit 0 ;# we do not interrupt others.
|
||||
;;
|
||||
esac
|
||||
|
||||
# Now we are dealing with a topic branch being rebased
|
||||
# on top of master. Is it OK to rebase it?
|
||||
|
||||
# Does the topic really exist?
|
||||
git show-ref -q "$topic" || {
|
||||
echo >&2 "No such branch $topic"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Is topic fully merged to master?
|
||||
not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
|
||||
if test -z "$not_in_master"
|
||||
then
|
||||
echo >&2 "$topic is fully merged to master; better remove it."
|
||||
exit 1 ;# we could allow it, but there is no point.
|
||||
fi
|
||||
|
||||
# Is topic ever merged to next? If so you should not be rebasing it.
|
||||
only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
|
||||
only_next_2=`git rev-list ^master ${publish} | sort`
|
||||
if test "$only_next_1" = "$only_next_2"
|
||||
then
|
||||
not_in_topic=`git rev-list "^$topic" master`
|
||||
if test -z "$not_in_topic"
|
||||
then
|
||||
echo >&2 "$topic is already up-to-date with master"
|
||||
exit 1 ;# we could allow it, but there is no point.
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
|
||||
/usr/bin/perl -e '
|
||||
my $topic = $ARGV[0];
|
||||
my $msg = "* $topic has commits already merged to public branch:\n";
|
||||
my (%not_in_next) = map {
|
||||
/^([0-9a-f]+) /;
|
||||
($1 => 1);
|
||||
} split(/\n/, $ARGV[1]);
|
||||
for my $elem (map {
|
||||
/^([0-9a-f]+) (.*)$/;
|
||||
[$1 => $2];
|
||||
} split(/\n/, $ARGV[2])) {
|
||||
if (!exists $not_in_next{$elem->[0]}) {
|
||||
if ($msg) {
|
||||
print STDERR $msg;
|
||||
undef $msg;
|
||||
}
|
||||
print STDERR " $elem->[1]\n";
|
||||
}
|
||||
}
|
||||
' "$topic" "$not_in_next" "$not_in_master"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
################################################################
|
||||
|
||||
This sample hook safeguards topic branches that have been
|
||||
published from being rewound.
|
||||
|
||||
The workflow assumed here is:
|
||||
|
||||
* Once a topic branch forks from "master", "master" is never
|
||||
merged into it again (either directly or indirectly).
|
||||
|
||||
* Once a topic branch is fully cooked and merged into "master",
|
||||
it is deleted. If you need to build on top of it to correct
|
||||
earlier mistakes, a new topic branch is created by forking at
|
||||
the tip of the "master". This is not strictly necessary, but
|
||||
it makes it easier to keep your history simple.
|
||||
|
||||
* Whenever you need to test or publish your changes to topic
|
||||
branches, merge them into "next" branch.
|
||||
|
||||
The script, being an example, hardcodes the publish branch name
|
||||
to be "next", but it is trivial to make it configurable via
|
||||
$GIT_DIR/config mechanism.
|
||||
|
||||
With this workflow, you would want to know:
|
||||
|
||||
(1) ... if a topic branch has ever been merged to "next". Young
|
||||
topic branches can have stupid mistakes you would rather
|
||||
clean up before publishing, and things that have not been
|
||||
merged into other branches can be easily rebased without
|
||||
affecting other people. But once it is published, you would
|
||||
not want to rewind it.
|
||||
|
||||
(2) ... if a topic branch has been fully merged to "master".
|
||||
Then you can delete it. More importantly, you should not
|
||||
build on top of it -- other people may already want to
|
||||
change things related to the topic as patches against your
|
||||
"master", so if you need further changes, it is better to
|
||||
fork the topic (perhaps with the same name) afresh from the
|
||||
tip of "master".
|
||||
|
||||
Let's look at this example:
|
||||
|
||||
o---o---o---o---o---o---o---o---o---o "next"
|
||||
/ / / /
|
||||
/ a---a---b A / /
|
||||
/ / / /
|
||||
/ / c---c---c---c B /
|
||||
/ / / \ /
|
||||
/ / / b---b C \ /
|
||||
/ / / / \ /
|
||||
---o---o---o---o---o---o---o---o---o---o---o "master"
|
||||
|
||||
|
||||
A, B and C are topic branches.
|
||||
|
||||
* A has one fix since it was merged up to "next".
|
||||
|
||||
* B has finished. It has been fully merged up to "master" and "next",
|
||||
and is ready to be deleted.
|
||||
|
||||
* C has not merged to "next" at all.
|
||||
|
||||
We would want to allow C to be rebased, refuse A, and encourage
|
||||
B to be deleted.
|
||||
|
||||
To compute (1):
|
||||
|
||||
git rev-list ^master ^topic next
|
||||
git rev-list ^master next
|
||||
|
||||
if these match, topic has not merged in next at all.
|
||||
|
||||
To compute (2):
|
||||
|
||||
git rev-list master..topic
|
||||
|
||||
if this is empty, it is fully merged to "master".
|
36
spec/fixtures/repo-with-submodules/git.git/modules/jstips/hooks/prepare-commit-msg.sample
поставляемый
Executable file
36
spec/fixtures/repo-with-submodules/git.git/modules/jstips/hooks/prepare-commit-msg.sample
поставляемый
Executable file
|
@ -0,0 +1,36 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to prepare the commit log message.
|
||||
# Called by "git commit" with the name of the file that has the
|
||||
# commit message, followed by the description of the commit
|
||||
# message's source. The hook's purpose is to edit the commit
|
||||
# message file. If the hook fails with a non-zero status,
|
||||
# the commit is aborted.
|
||||
#
|
||||
# To enable this hook, rename this file to "prepare-commit-msg".
|
||||
|
||||
# This hook includes three examples. The first comments out the
|
||||
# "Conflicts:" part of a merge commit.
|
||||
#
|
||||
# The second includes the output of "git diff --name-status -r"
|
||||
# into the message, just before the "git status" output. It is
|
||||
# commented because it doesn't cope with --amend or with squashed
|
||||
# commits.
|
||||
#
|
||||
# The third example adds a Signed-off-by line to the message, that can
|
||||
# still be edited. This is rarely a good idea.
|
||||
|
||||
case "$2,$3" in
|
||||
merge,)
|
||||
/usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;
|
||||
|
||||
# ,|template,)
|
||||
# /usr/bin/perl -i.bak -pe '
|
||||
# print "\n" . `git diff --cached --name-status -r`
|
||||
# if /^#/ && $first++ == 0' "$1" ;;
|
||||
|
||||
*) ;;
|
||||
esac
|
||||
|
||||
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
|
||||
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче