Maison > Article > interface Web > Numéros de ligne pour
L'autre jour, je travaillais sur un générateur de schéma JSON et je voulais afficher les numéros de ligne dans une
J'ai fait quelques recherches et trouvé plusieurs approches :
Je n’ai aimé aucun d’entre eux ! Le premier n'avait pas l'air net et ne correspondait pas aux styles que j'avais déjà en place pour mes éléments
Le second nécessitait beaucoup de JavaScript pour maintenir cette liste ordonnée : ajout/suppression d'éléments
J'ai donc fini par créer un hybride.
Il s'agit d'un SVG généré dynamiquement, stocké en tant que Propriété personnalisée CSS - et utilisé comme image d'arrière-plan, héritant des styles de son élément
Plongeons-nous.
Tout d'abord, la méthode principale :
lineNumbers(element, numLines = 50, inline = false)
l'élément est l'élément
Ensuite, nous définissons un préfixe pour la propriété personnalisée :
const prefix = '--linenum-';
Avant de continuer, nous vérifions s'il faut réutiliser une propriété existante :
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; } }
Ensuite, nous extrayons les styles de l'élément, rendant le SVG avec la même famille de polices, la même taille de police, la même hauteur de ligne, 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);
Nous avons également besoin d'un identifiant aléatoire pour notre propriété :
const id = `${prefix}${Math.random().toString(36).substr(2, 6)}`;
Et maintenant il est temps de rendre le SVG :
const svg = `<svg xmlns="http://www.w3.org/2000/svg"> <style> svg { background: ${bgColor}; } text { fill: hsl(from ${fillColor} h s l / 50%); font-family: ${fontFamily}; font-size: ${fontSize}px; line-height: ${lineHeight}; text-anchor: end; translate: 0 calc((var(--n) * ${translateY}px) + ${paddingTop}px); } </style> ${Array.from({ length: numLines }, (_, i) => `<text x="90%" style="--n:${i + 1};">${i + 1}</text>`).join("")} </svg>`;
Décomposons-le :
Dans la section