Cada dos semanas, vamos a echar un vistazo ultra centrado a un efecto interesante y útil, plugin, hack, biblioteca o incluso una tecnología ingeniosa. Luego intentaremos deconstruir el código o crear un pequeño proyecto divertido con él.
Hoy, vamos a echar un vistazo al excelente plugin replaceText jQuery. ¿Interesado? Empecemos después del salto..
Como desarrolladores web, tenemos acceso a una asombrosa cantidad de código preconstruido, ya sea un pequeño fragmento de código o un marco completo. A menos que esté haciendo algo increíblemente específico, lo más probable es que ya haya algo creado previamente para que lo aproveche. Desafortunadamente, muchas de estas ofertas estelares languidecen en el anonimato, especialmente para la multitud no hardcore..
Esta serie busca corregir este problema mediante la introducción de un código útil y bien escrito, ya sea un complemento, un efecto o una tecnología para el lector. Además, si es lo suficientemente pequeño, intentaremos deconstruir el código y entender cómo lo hace vudú. Si es mucho más grande, intentaremos crear un mini proyecto con él para aprender las cuerdas y, con suerte, entender cómo usarlo en el mundo real..
Comenzamos las cosas centrándonos en el excelente complemento de reemplazo de texto de Ben Alman. Aquí hay alguna información rápida:
Reemplazar el contenido en su página suena extremadamente simple. Después de todo, el método de JavaScript nativo reemplazar
Parece hacer lo mismo. Si te sientes particularmente vago, jQuery hace que la sustitución de todo el contenido del contenedor sea demasiado sencilla también.
// Usando simplemente reemplaza $ ("# container"). Text (). Replace (/ text / g, 'reemplazo de texto') // Reemplazando el contenido * completo * del contenedor var lazyFool = "contenido completo con texto reemplazado externamente "; $ ("# container"). html (lazyFool);
Como dice el dicho, solo porque puedas hacerlo no significa que debas hacerlo. Ambos métodos generalmente se rechazan [fuera de los casos extremos] porque rompen un montón de cosas mientras hacen lo que hacen.
El principal problema con estos enfoques es que aplanan la estructura de DOM al juntar efectivamente cada nodo no de texto que contiene el contenedor. Si logras reemplazar el propio html, usando internalHTML
o de jQuery html
, Aún así, desenganchará cada controlador de eventos adjunto a cualquiera de sus hijos, lo que es un factor decisivo. Este es el problema principal que este plugin busca resolver..
La mejor manera de lidiar con la situación, y la forma en que el complemento la maneja, es trabajar y modificar los nodos de texto exclusivamente.
Los nodos de texto aparecen en el DOM al igual que los nodos normales, excepto que no pueden contener nodos secundarios. El texto que contienen puede obtenerse usando el
nodeValue
odatos
propiedad.
Al trabajar con nodos de texto, podemos hacer muchas de las complejidades involucradas con el proceso. Básicamente necesitaremos recorrer los nodos, probar si es un nodo de texto y, en caso afirmativo, proceder a manipularlo de manera inteligente para evitar problemas..
Revisaremos el código fuente del complemento para que pueda comprender cómo el complemento implementa este concepto en detalle..
Como la mayoría de los complementos de jQuery bien escritos, es extremadamente fácil de usar. Utiliza la siguiente sintaxis:
$ (contenedor) .replaceText (texto, reemplazo);
Por ejemplo, si necesita reemplazar todas las apariciones de la palabra 'val' con 'valor', por ejemplo, deberá crear una instancia del complemento de la siguiente manera:
$ ("# container"). replaceText ("val", "value");
Sí, es realmente tan simple. El plugin se encarga de todo por ti..
Si eres del tipo que se vuelve loco con expresiones regulares, también puedes hacerlo.!
$ ("# container"). replaceText (/ (val) / gi, "value");
No debe preocuparse por reemplazar el contenido en los atributos de un elemento, el complemento es bastante inteligente.
Dado que el complemento está compuesto de solo 25 líneas de código, cuando se eliminen los comentarios y demás, haremos un análisis rápido de la fuente explicando qué fragmento hace qué y con qué propósito..
Aquí está la fuente, para su referencia. Repasaremos cada parte en detalle a continuación..
$ .fn.replaceText = function (search, replace, text_only) return this.each (function () var node = this.firstChild, val, new_val, remove = []; if (node) do if (node .nodeType === 3) val = node.nodeValue; new_val = val.replace (buscar, reemplazar); if (new_val! == val) if (! text_only && /Correcto, hagamos una ejecución moderadamente alta del código..
$ .fn.replaceText = function (search, replace, text_only) ;Paso 1 - El contenedor genérico para un plugin jQuery. El autor, con razón, se ha abstenido de agregar opciones vapidas ya que la funcionalidad proporcionada es lo suficientemente simple como para garantizar una. Los parámetros deben ser autoexplicativos. --
solo texto
será manejado un poco más tarde.devuelve this.each (function () );Paso 2 -
esto.cada
se asegura de que el complemento se comporte cuando se pasa en una colección de elementos.var node = this.firstChild, val, new_val, remove = [];Paso 3 - Declaración de requisitos de las variables que vamos a utilizar..
nodo
contiene el primer elemento hijo del nodo.val
mantiene el valor actual del nodo.new_val
mantiene el valor actualizado del nodo.retirar
es una matriz que contendrá un nodo que deberá eliminarse del DOM. Voy a entrar en detalles sobre esto en un momento.if (nodo)
Etapa 4 - Verificamos si el nodo existe realmente, es decir, el contenedor que se pasó tiene elementos secundarios. Recuérdalo nodo
contiene el primer elemento hijo del elemento pasado.
do while (node = node.nextSibling);
Paso 5 - El bucle esencialmente, bueno, recorre los nodos secundarios que terminan cuando el bucle está en el nodo final.
if (node.nodeType === 3)
Paso 6 - Esta es la parte interesante. Accedemos al tipo de nodo
propiedad [solo lectura] del nodo para deducir qué tipo de nodo es. Un valor de 3 implica que es un nodo de texto, por lo que podemos continuar. Si te facilita la vida, puedes reescribirla así: if (node.nodeType == Node.TEXT_NODE)
.
val = node.nodeValue; new_val = val.replace (buscar, reemplazar);
Paso 7 - Almacenamos el valor actual del nodo de texto, primero arriba. A continuación, reemplazamos rápidamente las instancias de la palabra clave con el reemplazo con el nativo reemplazar
Método de JavaScript Los resultados están siendo almacenados en la variable. new_val
.
if (new_val! == val)
Paso 8 - Proceder solo si el valor ha cambiado!
si (! text_only && /Paso 9a - Recuerda el
solo texto
parámetro. Esto entra en juego aquí. Esto se utiliza para especificar si el contenedor debe tratarse como uno que contiene nodos de elementos en su interior. El código también realiza una verificación interna rápida para ver si contiene contenido HTML. Lo hace buscando una etiqueta de apertura en el contenido denew_val
.En caso afirmativo, se inserta un nodo de texto antes del nodo actual y el nodo actual se agrega a la
retirar
matriz para ser manejada más tarde.else node.nodeValue = new_val;Paso 9b - Si es solo texto, inyecte directamente el nuevo texto en el nodo sin pasar por el alboroto de malabares de DOM.
remove.length && $ (remove) .remove ();Paso 10 - Finalmente, una vez que el bucle ha terminado de ejecutarse, eliminamos rápidamente los nodos acumulados del DOM. La razón por la que lo hacemos después de que el bucle haya terminado de ejecutarse es que la eliminación de un nodo a mitad de la ejecución lo arruinará.
Proyecto
El pequeño proyecto que vamos a construir hoy es bastante básico. Aquí está la lista de nuestros requisitos:
Nota: Esto es más una prueba de concepto que algo que simplemente puede desplegar sin tocar. Obviamente, con el fin de evitar que el artículo se convierta en algo inverosímil, me he saltado varias secciones que son de suma importancia para el código listo para producción, por ejemplo, la validación.
El enfoque real aquí debería estar en el propio complemento y las técnicas de desarrollo que contiene. Recuerde, esto es más una demostración beta para mostrar algo interesante que se puede hacer con este complemento. Siempre desinfecte y valide sus entradas!
Deconstrucción: jQuery replaceText Deconstrucción: jQuery replaceText
por Siddharth para la gente encantadora en Nettuts+Esta página utiliza el popular plugin replaceText de Ben Alman. En esta demostración, lo estamos utilizando para resaltar fragmentos arbitrarios de texto en esta página. Completa la palabra, estás buscando y pulsa ir..
<-- Assorted text here -->
El HTML debe ser bastante explicativo. Todo lo que he hecho es crear una entrada de texto, dos enlaces para aplicar y eliminar el resaltado, así como un párrafo que contiene un texto variado.
body font-family: "Myriad Pro", "Lucida Grande", "Verdana", sans-serif; tamaño de fuente: 16px; p margen: 20px 0 40px 0; h1 font-size: 36px; relleno: 0; margen: 7px 0; h2 font-size: 24px; #container width: 900px; margen izquierdo: auto; margen derecho: auto; relleno: 50px 0 0 0; posición: relativa; #haiz padding: 20px; fondo: #EFEFEF; -moz-border-radius: 15px; -webkit-border-radius: 15px; borde: 1px sólido # C9C9C9; #search width: 600px; margen: 40px auto; text-align: center; #keyword width: 150px; altura: 30px; relleno: 0 10px; borde: 1px sólido # C9C9C9; -moz-border-radius: 5px; -webkit-border-radius: 5px; fondo: # F0F0F0; tamaño de fuente: 18px; # apply-highlight, # remove-highlight padding-left: 40px; .highlight background-color: yellow;
De nuevo, bastante auto explicativo y bastante básico. Lo único a tener en cuenta es la clase llamada realce
que estoy definiendo Esto se aplicará al texto que tendremos que resaltar..
En esta etapa, su página debería verse así:
La primera orden del día es conectar rápidamente nuestro enlace con sus manejadores para que el texto se resalte y se resalte adecuadamente..
var searchInput = $ ("# keyword"), searchTerm, searchRegex; $ ("# apply-highlight"). click (highLight); $ ("# remove-highlight"). bind ("click", function () $ ("# haiz"). removeHighlight (););
Debería ser bastante simple. Declaro algunas variables para uso posterior y adjunto los enlaces a sus manejadores. realce
y quitar resaltar
Son funciones extremadamente simples que veremos a continuación..
función highLight () searchTerm = searchInput.val (); searchRegex = new RegExp (searchTerm, 'g'); $ ("# haiz *"). replaceText (searchRegex, ''+ searchTerm +'');
reemplazarTexto
plugin pasando los valores apropiados. Estoy eligiendo incluir directamente término de búsqueda
en el marcado por brevedad.jQuery.fn.removeHighlight = function () return this.find ("span.highlight"). each (function () with (this.parentNode) replaceChild (this.firstChild, this););
Un método rápido y sucio para hacer el trabajo. Y sí, este es un complemento de jQuery ya que quería canjearme. La clase todavía está codificada.
Simplemente estoy buscando cada etiqueta de span con una clase de realce
y reemplazando todo el nodo con el valor que contiene.
Antes de preparar sus horcas, recuerde que esto es solo para fines de demostración. Para su propia aplicación, necesitará un método de iluminación mucho más sofisticado.
Y hemos terminado. Echamos un vistazo a un complemento increíblemente útil, recorrimos el código fuente y finalmente terminamos creando un mini proyecto con él..