El otro día estaba trabajando en un generador de esquemas JSON y quería mostrar números de línea en un
Investigué un poco y encontré múltiples enfoques:
¡No me gustó ninguno! El primero no se veía nítido y no coincidía con los estilos que ya tenía implementados para mis elementos
El segundo requirió un montón de JavaScript para mantener esa lista ordenada: agregar/eliminar elementos
Así que terminé creando un híbrido.
Es un SVG generado dinámicamente, almacenado como una Propiedad personalizada de CSS y utilizado como imagen de fondo, heredando los estilos de su elemento principal
Vamos a sumergirnos.
Primero, el método principal:
lineNumbers(element, numLines = 50, inline = false)
elemento es el elemento
A continuación, definimos un prefijo para la propiedad personalizada:
const prefix = '--linenum-';
Antes de continuar, verificamos si reutilizamos alguna propiedad existente:
if (!inline) { const styleString = document.body.getAttribute('style') || ''; const regex = new RegExp(`${prefix}[^:]*`, 'g'); const match = styleString.match(regex); if (match) { element.style.backgroundImage = `var(${match[0]})`; return; } }
A continuación, extraemos estilos del elemento, representando el SVG con la misma familia de fuentes, tamaño de fuente, altura de línea, etc. :
const bgColor = getComputedStyle(element).borderColor; const fillColor = getComputedStyle(element).color; const fontFamily = getComputedStyle(element).fontFamily; const fontSize = parseFloat(getComputedStyle(element).fontSize); const lineHeight = parseFloat(getComputedStyle(element).lineHeight) / fontSize; const paddingTop = parseFloat(getComputedStyle(element).paddingTop) / 2; const translateY = (fontSize * lineHeight).toFixed(2);
También necesitamos una identificación aleatoria para nuestra propiedad:
const id = `${prefix}${Math.random().toString(36).substr(2, 6)}`;
Y ahora es el momento de renderizar el SVG:
const svg = ``;
Vamos a desglosarlo:
En la sección
La última parte itera una matriz creada a partir de numLines y agrega los elementos
¡Ya casi llegamos!
Para usar el SVG generado como una propiedad url(), necesitamos codificarlo:
const encodedURI = `url("data:image/svg xml,${encodeURIComponent(svg)}")`;
Y finalmente, configuramos esa propiedad en cualquier elemento o cuerpo del documento:
const target = inline ? element : document.body; target.style.setProperty(id, encodedURI); element.style.backgroundImage = `var(${id})`;
¡Y listo!
¡No está mal, y solo 610 bytes, minimizados y comprimidos!
Puedes ver una demostración aquí y descargar el script completo aquí.
A continuación se muestra un Codepen simplificado, que no utiliza la lógica de propiedades en línea:
¿Hay pros y contras? ¡Por supuesto que las hay!
Personalmente, para mi proyecto actual, necesitaba una forma simple y nítida de agregar números de línea a una vista previa JSON dentro de un
Este método no se basa en la manipulación del DOM. Los números de línea se generan como un único SVG, almacenado dentro de una propiedad personalizada de CSS.
Dado que los números de línea son parte de la imagen de fondo, se desplazan automáticamente con el contenido del texto, eliminando la necesidad de una lógica de sincronización manual.
Al almacenar el SVG generado en una propiedad personalizada de CSS, se puede reutilizar en varios elementos. Esto significa que si varios elementos requieren los mismos números de línea, todos pueden hacer referencia a la misma propiedad personalizada, evitando la generación de SVG redundante.
Las listas ordenadas son más accesibles para lectores de pantalla y tecnologías de asistencia, mientras que los números de línea basados en SVG pueden ignorarse o malinterpretarse.
Diseñar e interactuar con números de línea individuales en una lista ordenada es sencillo. Por el contrario, el enfoque SVG hace que sea más difícil personalizar o agregar interactividad a números de línea específicos.
Es posible que las propiedades personalizadas de SVG y CSS no se muestren de manera consistente en todos los navegadores; la implementación actual tiene problemas con Safari, donde debemos deducir (paddingTop / 10) de TranslateY.
Las listas ordenadas pueden ser más flexibles para manejar actualizaciones de contenido dinámico, como agregar o eliminar líneas, mientras que el enfoque SVG puede requerir regenerar y volver a aplicar toda la imagen de fondo.
Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.
Copyright© 2022 湘ICP备2022001581号-3