soy Kseso y esto EsCSS

Javascript con Furoya: agregar etiquetas a cada letra de un texto para aplicarles estilos CSS

Cómo separar un texto letra a letra y añadir marcado html a cada una de ellas con las funciones de javaScript split( ) y join( ) y a partir de ello poder aplicar estilos a cada carácter independientemente. Autor: Furoya.

Javascript con Furoya: agregar etiquetas a cada letra de un texto para aplicarles estilos CSS

✎ 0
COLABORACIÓN AUTOR INVITADO
Javascript con Furoya: agregar etiquetas a cada letra de un texto para aplicar estilos CSS

Seguimos arruinando complementando un blog de CSS con apuntes de javascript.

Y ahora tampoco vamos a ver un ejemplo donde el JS modifica el CSS o lo complementa; pero aún así creo que a más de uno le va a gustar la propuesta.

Pongámonos en situación : tenemos un texto en un título, y queremos destacar la primera letra con un formato distinto al resto, ¿cómo hacemos?. Sí, con el pseudoelemento CSS ::first-letter tenemos muchos estilos disponibles. Y lo mismo si queremos modificar la primera línea (habiendo más de una), porque existe ::first-line.

Pero volvamos al primer caso. ¿Qué ocurre si queremos modificar la segunda y quinta letras?. Tenemos a los selectores :nth-algo, pero son para elementos HTML reales, y conseguir el efecto con ellos nos obliga a meter cada caracter en un span (por ejemplo) y así apuntarle no a la letra sino a la caja que la contiene.

El método en realidad no está mal, salvo por un pequeño detalle : provocaríamos suicidios en masa entre expertos en SEO y puristas de la semántica. Porque hay que destrozar las palabras en el código fuente.

<head> <style> span:nth-child(2) , span:nth-child(5) { color: red; background-color: lime; } </style> </head> <body> <h1> <span>Q</span><span>W</span><span>E</span><span>R</span><span>T</span><span>Y</span><span>U</span><span>I</span><span>O</span><span>P</span><span>.</span> </h1> </body>

Hay algo que es obvio, pero no se tiene muy en cuenta. Y es lo que nos va a ayudar a resolver dignamente este problema.

Estamos hablando de código fuente, pero lo que vemos en el navegador no es el source code original de la página, sino una versión que hace el mismo navegador interpretando (a su manera) esas instrucciones. Y resulta que javascript modifica ese código. A diferencia de los lenguajes de programación en el servidor (que sí pueden reescribir un código fuente) con JS nada más accedemos a esa copia virtual del source que está en la memoria de la máquina.

Entonces cualquier modificación que hagamos va a ser local, y ni el código original ni los índices de buscadores se van a enterar. (Bueno, a la araña de Google de un tiempo a esta parte le gusta curiosear el Css y Js que aplican a la página).

Ya estuvimos hablando de la manipulación de cadenas de texto, y en algún comentario hasta de funciones prehechas para eso (como .substr(,) ), también mencionamos a los Array y a textContent para "capturar de" o "meter en" un elemento el texto limpio sin etiquetas.

Ahora vamos a ver como juntarlos de nuevo, agregando más funciones y un método muy útil para convertir cadenas de texto en elementos de Array, y viceversa.

Supongamos que hay un texto que nos muestra una fecha en formato 01/12/2999, y nosotros queremos manejar por separado cada valor de dd/mm/aaaa. Un método simple es usar una de las funciones que ya vienen en JS y que se llama split(). Dentro de los paréntesis se pone como argumento o parámetro la parte del texto por donde queremos cortar esa cadena, y el método split nos va a devolver una lista o Array con los demás caracteres en orden de aparición.

Si ponemos: var misFechas = "01/12/2999".split("/"); nos queda igual que misFechas = ["01","12","2999"];, un Array con 3 elementos que resultan de cortar por el carácter /, y a los que podemos acceder por su índice; como var miAnio = misFechas[2];.

Ahora bien, ¿qué pasa si dejamos que corte por un argumento de texto vacío como split("")? Pues que va a cortar donde no haya texto ... que es entre carácter y carácter.
<script> var miTexto = "QWERTYUIOP"; var misLetras = miTexto.split(""); alert(misLetras); /*devuelve Q,W,E,R,T,Y,U,I,O,P */ </script>

Que es lo mismo que si escribiésemos misLetras = ["Q","W","E","R","T","Y","U","I","O","P"];.

La forma en que lo muestra el mensaje modal no es muy exacta, porque al final no estamos seguros de si esas comas separan elementos o son parte de alguno, ya que no muestra las comillas. Pero es lo que hay y tenemos que acostumbrarnos a verlo así si no queremos tener que abrir consolas de javascript.

Ya tenemos la mitad del trabajo hecho ¿Ven que se puede cortar un título letra a letra? Pero ya no es un texto, en el ejemplo son 10, uno por cada caracter.

Ahora tenemos que juntarlo de nuevo, pero incluyendo las etiquetas de <span>.

¡Ajá. Ya se dieron cuenta!. Si hay un metodo para cortar un texto por alguno/s de sus caracteres, entonces debe haber otro para volver a juntarlo encadenando con otro/s caracter/es.

Se llama join() y se maneja igual. Si usamos como argumento otra cadena vacía, junta los elementos del Array en un solo texto tal como estaba, pero si usamos join("</span><span>") nos va a quedar así:

<script type="text/javascript"> var miTexto = "QWERTYUIOP"; var misLetras = miTexto.split(""); alert(misLetras); /*devuelve Q,W,E,R,T,Y,U,I,O,P */ var misEspanes = misLetras.join("</span><span>"); prompt("Así reconstruye",misEspanes); </script>

Nota: Usé un prompt en vez de un alert porque es más fácil copiar y pegar el resultado en cualquier editor para verlo mejor.

Modal resultante del prompt
Modal resultante del prompt

Ver Pen del código anterior

Habrán notado un detalle al probar el ejemplo, faltan la primer etiqueta de apertura y la última de cierre. Por el mecanismo que estamos usando, es evidente; pero como ya es una cadena de texto, sabemos cómo agregar lo que falte.

<script type="text/javascript"> var miTexto = "QWERTYUIOP"; var misLetras = miTexto.split(""); alert(misLetras); var misEspanes = misLetras.join("</span><span>"); misEspanes = "<span>" + misEspanes + "</span>"; prompt("Así reconstruye",misEspanes); </script>

La parte más difícil ya está hecha. Ya tenemos el contenido de nuestro título separado letra a letra con "espanes". Ahora vamos a ver el paso final, y el inicial que no mencionamos. En el ejemplo, la variable miTexto es una cadena que escribimos en el escript, pero en realidad nosotros la tenemos ya escrita en el HTML, porque era nuestro título.

Vimos la última vez que con textContent se puede "escribir" dentro de un elemento que esté en el cuerpo de la página, pero resulta que si no le ponemos un valor lo que hace es "leer" y capturar el contenido de texto de ese elemento. Así que con el siguiente código ya tenemos resuelto el problema.

<!DOCTYPE html> <html lang="es-ar"> <head> <meta charset="utf-8" /> </head> <body> <h1>QWERTYUIOP.</h1> <script type="text/javascript"> /*CAPTURA EL CONTENIDO*/ var miTexto = document.querySelector("h1").textContent; /*SEPARA LOS CARACTERES*/ var misLetras = miTexto.split(""); /*JUNTA LOS CARACTERES CON CIERRE Y APERTURA DE SPAN EN MEDIO*/ var misEspanes = misLetras.join("</span><span>"); /*AGREGA LAS ETIQUETAS PRIMERA Y ÚLTIMA*/ misEspanes = "<span>" + misEspanes + "</span>"; prompt("",misEspanes); /*REEMPLAZA EL CONTENIDO ORIGINAL DE H1 POR EL MODIFICADO*/ document.querySelector("h1").innerHTML = misEspanes; </script> </body> </html>

Un detalle final : la última línea del escript no es document.querySelector("h1").textContent = misEspanes; porque de esa forma sólo se maneja la cadena como texto plano. Y nosotros tenemos que meter en el título elementos HTML.

Con innerHTML le decimos al navegador que a esa cadena la tiene que tratar como si fuese HTML, y no parsearla.

No se pueden quejar, hoy aprendieron varios métodos. Ahora un ejemplo práctico.

See the Pen Zebra in title. by solipsistaCP (@solipsistacp) on CodePen.

Y a partir de acá, crean los formatos y animaciones de texto que les permita esta estructura, y sin arruinar el código fuente. Más adelante veremos cómo trabajar formatos que necesiten saber la cantidad de elementos y cómo ponerles clases numeradas a cada uno.

Autoría

Furoya: Autor del artículo

Artículo original de Furoya.
La intención del autor con sus colaboraciones no es que los artículos sirvan para hacer un copy&paste de códigos sino que comprendas y aprendas la lógica y el cómo trabaja javaScript.
Y a partir de lo expuesto experimentes tú.
El autor del post y el editor del blog te animamos a que plantees tus dudas o reflexiones y que compartas tus realizaciones en base a lo expuesto en los comentarios. Recuerda que puedes incluir pens (ejemplos en Codepen.io) en ellos.