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.
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);
$ ('# 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.
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.
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.
$ ('# 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
.
var lis = document.querySelectorAll ('# container li');
querySelectorAll
volverá todos Elementos que coinciden con el selector CSS especificado..
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.
var lis = document.getElementById ('container'). getElementsByTagName ('li');
$ ('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.
[] .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
.
var anchors = document.getElementsbyTagName ('a'); addEvent (anclas, 'clic', fn);
$ ('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.
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
.
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
.
$ ('# box'). addClass ('wrap');
jQuery proporciona una API útil para modificar nombres de clases en un conjunto de elementos.
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');
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?
$ ('# list'). next ();
jQuery siguiente
El método devolverá el elemento que sigue inmediatamente al elemento actual en el conjunto envuelto.
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.
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.
PS') .appendTo (' cuerpo ');
Además de consultar el DOM, jQuery también ofrece la posibilidad de crear e inyectar elementos..
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';
$ (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.
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..
// 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.
$ ('. 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.
[] .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.
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.
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.
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!
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!
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..