De jQuery a JavaScript una referencia

Nos guste o no, primero se introducen más y más desarrolladores en el mundo de JavaScript a través de jQuery. En muchos sentidos, estos recién llegados son los afortunados. Tienen acceso a una gran cantidad de nuevas API de JavaScript, que hacen que el proceso de cruce de DOM (algo para lo que muchas personas dependen de jQuery) sea mucho más fácil. Desafortunadamente, ellos no conocen estas APIs.!

En este artículo, tomaremos una variedad de tareas comunes de jQuery y las convertiremos a JavaScript moderno y heredado..

Moderno vs. Legado - Para cada elemento de la lista a continuación, encontrará la forma moderna, "niños geniales" para realizar la tarea, y el legado, "hacer felices a los navegadores antiguos". La elección que elija para sus propios proyectos dependerá en gran medida de sus visitantes.


Antes de que comencemos

Tenga en cuenta que algunos de los legado Los ejemplos en este artículo harán uso de un navegador cruzado simple., Añadir evento función. Esta función simplemente garantizará que tanto el modelo de evento recomendado por W3C, addEventListener, y el legado de Internet Explorer adjuntar están normalizados.

Entonces, cuando me refiero a addEvent (els, event, handler) en los fragmentos de código heredados a continuación, se hace referencia a la siguiente función.

var addEvent = (function () var filter = function (el, type, fn) for (var i = 0, len = el.length; i < len; i++ )  addEvent(el[i], type, fn);  ; if ( document.addEventListener )  return function (el, type, fn)  if ( el && el.nodeName || el === window )  el.addEventListener(type, fn, false);  else if (el && el.length)  filter(el, type, fn);  ;  return function (el, type, fn)  if ( el && el.nodeName || el === window )  el.attachEvent('on' + type, function ()  return fn.call(el, window.event); );  else if ( el && el.length )  filter(el, type, fn);  ; )(); // usage addEvent( document.getElementsByTagName('a'), 'click', fn);

1 - $ ('# contenedor');

Esta llamada de función consultará el DOM para el elemento con un carné de identidad de envase, y crea un nuevo jQuery objeto.

JavaScript moderno

var container = document.querySelector ('# container');

querySelector forma parte de la API de selectores, que nos brinda la capacidad de consultar el DOM mediante los selectores de CSS con los que ya estamos familiarizados.

Este método en particular devolverá el primer elemento que coincida con el selector pasado.

Legado

var container = document.getElementById ('container');

Preste especial atención a cómo hace referencia al elemento. Cuando usas getElementById, se pasa el valor solo, mientras que, con querySelector, se espera un selector de CSS.


2 - $ ('# container'). find ('li');

Esta vez, no estamos buscando un solo elemento; en su lugar, estamos capturando cualquier número de elementos de la lista que sean descendientes de #envase.

JavaScript moderno

var lis = document.querySelectorAll ('# container li');

querySelectorAll volverá todos Elementos que coinciden con el selector CSS especificado..

Limitaciones del Selector

Si bien casi todos los navegadores relevantes son compatibles con la API de selectores, los selectores de CSS específicos que usted pasa están limitados a la capacidad del navegador. Traducción: Internet Explorer 8 solo admitirá selectores CSS 2.1.

Legado

var lis = document.getElementById ('container'). getElementsByTagName ('li');

3 - $ ('a'). en ('clic', fn);

En este ejemplo, estamos adjuntando una hacer clic escucha de eventos a todas las etiquetas de anclaje en la página.

JavaScript moderno

[] .forEach.call (document.querySelectorAll ('a'), function (el) el.addEventListener ('click', function () // anchor se hizo clic, false););

El fragmento anterior parece aterrador, pero no está tan mal. Porque querySelectorAll devuelve una estática NodeList en lugar de un Formación, No podemos acceder directamente a métodos, como para cada. Esto es remediado llamando para cada sobre el Formación objeto, y pasando los resultados de querySelectorAll como esta.

Legado

var anchors = document.getElementsbyTagName ('a'); addEvent (anclas, 'clic', fn);

4 - $ ('ul'). en ('clic', 'a', fn);

Ahh - este ejemplo es ligeramente diferente. Esta vez, el fragmento de jQuery está utilizando la delegación de eventos. los hacer clic el oyente se aplica a todas las listas desordenadas, sin embargo, la función de devolución de llamada solo se activará si el objetivo (en lo que el usuario hizo clic específicamente) es una etiqueta de ancla.

JavaScript moderno

document.addEventListener ('clic', función (e) if (e.target.matchesSelector ('ul a')) // proceder, false);

Técnicamente, este método de JavaScript de vainilla no es el mismo que el ejemplo de jQuery. En su lugar, está adjuntando el detector de eventos directamente a la documento. A continuación, utiliza el nuevo partidosSelector método para determinar si el objetivo - el nodo en el que se hizo clic - coincide con el selector proporcionado. De esta manera, estamos adjuntando un único detector de eventos, en lugar de muchos.

Tenga en cuenta que, en el momento de escribir este documento, todos los navegadores implementan partidosSelector a través de sus propios prefijos respectivos: mozMatchesSelector, webkitMatchesSelector, Para normalizar el método, uno podría escribir:

coincidencias var (function (doc) matches = doc.matchesSelector || doc.webkitMatchesSelector || doc.mozMatchesSelector || doc.oMatchesSelector || doc.msMatchesSelector;) (document.documentElement); document.addEventListener ('clic', función (e) if (matches.call (e.target, 'ul a')) // proceder, false);

Con esta técnica, en Webkit, los partidos se referirán a webkitMatchesSelector, y, en mozilla, mozMatchesSelector.

Legado

var uls = document.getElementsByTagName ('ul'); addEvent (uls, 'click', function () var target = e.target || e.srcElement; if (target && target.nodeName === 'A') // proceder);

Como alternativa, determinamos si el nombre del nodo La propiedad (el nombre del elemento de destino) es igual a nuestra consulta deseada. Preste especial atención al hecho de que las versiones más antiguas de Internet Explorer a veces cumplen con sus propias reglas, algo así como el niño que come play-doh durante la hora del almuerzo. No podrás acceder objetivo directamente desde el evento objeto. En su lugar, querrá buscar event.srcElement.


5 - $ ('# box'). addClass ('wrap');

jQuery proporciona una API útil para modificar nombres de clases en un conjunto de elementos.

JavaScript moderno

document.querySelector ('# box'). classList.add ('wrap');

Esta nueva técnica utiliza la nueva Lista de clase API para añadir, retirar, y palanca nombres de clase.

var container = document.querySelector ('# box'); container.classList.add ('wrap'); container.classList.remove ('wrap'); container.classList.toggle ('wrap');

Legado

var box = document.getElementById ('box'), hasClass = function (el, cl) var regex = new RegExp ('(?: \\ s | ^)' + cl + '(?: \\ s | $ ) '); return !! el.className.match (regex); , addClass = function (el, cl) el.className + = "+ cl;, removeClass = function (el, cl) var regex = new RegExp ('(?: \\ s | ^)' + cl + '(?: \\ s | $)'); el.className = el.className.replace (regex, "); , toggleClass = function (el, cl) hasClass (el, cl)? removeClass (el, cl): addClass (el, cl); ; addClass (caja, 'drago'); removeClass (caja, 'drago'); toggleClass (caja, 'drago'); // si el elemento no tiene una clase de 'drago', agrega uno.

La técnica de retroceso requiere un poco más de trabajo, ay?


6 - $ ('# list'). next ();

jQuery siguiente El método devolverá el elemento que sigue inmediatamente al elemento actual en el conjunto envuelto.

JavaScript moderno

var next = document.querySelector ('# list'). nextElementSibling; // IE9

nextElementSibling se referirá específicamente a la siguiente elemento nodo, en lugar de cualquier nodo (texto, comentario, elemento). Desafortunadamente, Internet Explorer 8 y anteriores no lo admiten.

Legado

var list = document.getElementById ('list'), next = list.nextSibling; // queremos el siguiente elemento nodo ... no texto. while (next.nodeType> 1) next = next.nextSibling;

Hay un par de maneras de escribir esto. En este ejemplo, estamos detectando la tipo de nodo del nodo que sigue al elemento especificado. Podría ser texto, elemento, o incluso un comentario. Como necesitamos específicamente el siguiente elemento, deseamos una tipo de nodo de 1. Si next.nodeType devuelve un número mayor que 1, debemos omitirlo y seguir adelante, ya que probablemente sea un nodo de texto.


7 - PS
') .appendTo (' cuerpo ');

Además de consultar el DOM, jQuery también ofrece la posibilidad de crear e inyectar elementos..

JavaScript moderno

var div = document.createElement ('div'); div.id = 'caja'; document.body.appendChild (div);

No hay nada moderno en este ejemplo; así es como hemos logrado el proceso de crear e inyectar elementos en el DOM durante mucho, mucho tiempo.

Es probable que deba agregar contenido al elemento, en cuyo caso puede usar internalHTML, o createTextNode.

div.appendChild (document.createTextNode ('wacka wacka')); // o div.innerHTML = 'wacka wacka';

8 - $ (documento) .ready (fn)

jQuery document.ready El método es increíblemente conveniente. Nos permite comenzar a ejecutar el código tan pronto como sea posible después de que se haya cargado el DOM.

JavaScript moderno

document.addEventListener ('DOMContentLoaded', function () // divertirse);

Estandarizado como parte de HTML5, el DOMContentLoaded El evento se activará tan pronto como el documento haya sido completado, analizado..

Legado

// http://dustindiaz.com/smallest-domready-ever function ready (cb) /in/.test(document.readyState) // in = loadINg? setTimeout ('ready (' + cb + ')', 9): cb ();  ready (function () // toma algo del DOM);

La solución alternativa, cada nueve milisegundos, detectará el valor de document.readyState. Si se devuelve "cargando", el documento aún no se ha analizado completamente (/in/.test (). Pero una vez que haya, document.readyState será igual a "completo", momento en el que se ejecuta la función de devolución de llamada del usuario.


9 - $ ('. box'). css ('color', 'red');

Si es posible, siempre agregue un clase a un elemento, cuando necesita proporcionar un estilo especial. Sin embargo, a veces, el estilo se determinará dinámicamente, en cuyo caso debe insertarse como un atributo.

JavaScript moderno

[] .forEach.call (document.querySelectorAll ('. box'), function (el) el.style.color = 'red'; // o agregue una clase);

Una vez más, estamos usando el [] .forEach.call () Técnica para filtrar a través de todos los elementos con una clase de caja, y hacerlos rojos, a través de la estilo objeto.

Legado

var box = document.getElementsByClassName ('box'), // consulte el ejemplo # 10 a continuación para obtener una solución de navegador cruzado i = box.length; while (i--> 0 && (cuadro [i] .style.color = 'rojo'));

Esta vez, nos estamos poniendo un poco complicados con el mientras lazo. Sí, es un poco sarcástico, ¿no? Esencialmente, estamos imitando:

var i = 0, len; para (len = box.length; i < len; i++ )  box[i].style.color = 'red'; 

Sin embargo, como solo necesitamos realizar una sola acción, podemos guardar un par de líneas. Tenga en cuenta que la legibilidad es mucho más importante que guardar dos líneas, de ahí mi referencia "sarcástica". No obstante, siempre es divertido ver cuán condensado puede hacer sus bucles. Somos desarrolladores; ¡Hacemos este tipo de cosas por diversión! De todos modos, siéntete libre de seguir con el para versión de declaración.


10 - PS

Claramente, nuestra intención no es replicar la API jQuery completa. Típicamente, para proyectos que no son de jQuery, el PS o $$ La función se utiliza como abreviatura para recuperar uno o más elementos del DOM.

JavaScript moderno

var $ = function (el) return document.querySelectorAll (el); ; // Uso = $ ('. Box');

Darse cuenta de PS es simplemente un puntero de un carácter para document.querySelector. Ahorra tiempo!

Legado

if (! document.getElementsByClassName) document.getElementsByClassName = function (cl, tag) var els, matches = [], i = 0, len, regex = new RegExp ('(?: \\ s | ^)' + cl + '(?: \\ s | $)'); // Si no se especifica ningún nombre de etiqueta, // tenemos que tomar CADA elemento del DOM els = document.getElementsByTagName (etiqueta || "*"); if (! els [0]) devuelve false; para (len = els.length; i < len; i++ )        if ( els[i].className.match(regex) )           matches.push( els[i]);               return matches; // an array of elements that have the desired classname ;    // Very simple implementation. We're only checking for an id, class, or tag name. // Does not accept CSS selectors in pre-querySelector browsers. var $ = function(el, tag)     var firstChar = el.charAt(0);      if ( document.querySelectorAll ) return document.querySelectorAll(el);      switch ( firstChar )        case "#":          return document.getElementById( el.slice(1) );       case ".":          return document.getElementsByClassName( el.slice(1), tag );       default:          return document.getElementsByTagName(el);     ; // Usage $('#container'); $('.box'); // any element with a class of box $('.box', 'div'); // look for divs with a class of box $('p'); // get all p elements

Desafortunadamente, el método heredado no es tan mínimo. Honestamente, en este punto, debes usar una biblioteca. jQuery está altamente optimizado para trabajar con el DOM, ¡por eso es tan popular! El ejemplo anterior ciertamente funcionará, sin embargo, no es compatible con selectores de CSS complejos en navegadores antiguos; Esa tarea es solo un poquito más complicada!


Resumen

Es importante para mí tener en cuenta que no te estoy animando a que abandones jQuery. Lo uso en casi todos mis proyectos. Dicho esto, no siempre esté dispuesto a aceptar abstracciones sin tomar un poco de tiempo para investigar el código subyacente.

Me gustaría que esta publicación sirva como un documento vivo, de algún tipo. Si tiene alguno de sus propios (o mejoras / aclaraciones para mis ejemplos), deje un comentario a continuación, y actualizaré esporádicamente esta publicación con nuevos elementos. Marca esta página ahora! Por último, me gustaría enviar un consejo sobre este conjunto de ejemplos, que sirvió como impulso para esta publicación..