"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > Números de línea para usar SVG

Números de línea para usar SVG

Publicado el 2024-08-23
Navegar:517

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:

  1. Usando una imagen de fondo (TinyMCE hace eso, usando un PNG)
  2. Usando una lista ordenada
      .

¡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

  • dinámicamente, sincronizar eventos de desplazamiento y mucho más.

    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

    Line Numbers for <textarea> usando SVG

    Vamos a sumergirnos.


    javascript

    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 = `
      
      ${Array.from({ length: numLines }, (_, i) => `${i   1}`).join("")}
    `;
    

    Vamos a desglosarlo:

    En la sección simplemente configuramos los estilos que extrajimos del

    La última parte itera una matriz creada a partir de numLines y agrega los elementos al SVG principal.

    ¡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!


    Manifestación

    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:


    Pros y contras

    ¿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

    Ventajas

    Manipulación DOM reducida

    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.

    Sincronización automática

    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.

    Reutilizabilidad entre elementos

    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.

    Escalabilidad

    La naturaleza vectorial de SVG garantiza que los números de línea permanezcan nítidos y claros en cualquier nivel de zoom.

    Contras

    Accesibilidad

    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.

    Complejidad de personalización

    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.

    Compatibilidad del navegador

    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.

    Manejo de contenido dinámico

    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.

  • Declaración de liberación Este artículo se reproduce en: https://dev.to/madsstoumann/line-numbers-for-using-svg-1216?1 Si hay alguna infracción, comuníquese con [email protected] para eliminarla.
    Último tutorial Más>

    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