L'autre jour, je travaillais sur un générateur de schéma JSON et je voulais afficher les numéros de ligne dans un
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à mis 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)
element 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 convient de 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 = ``;
Décomposons :
Dans la section
La dernière partie parcourt un tableau créé à partir de numLines et ajoute les éléments
Nous y sommes presque !
Pour utiliser le SVG généré comme propriété url(), nous devons encoder :
const encodedURI = `url("data:image/svg xml,${encodeURIComponent(svg)}")`;
Et enfin, nous définissons cette propriété sur l'élément ou sur le corps du document :
const target = inline ? element : document.body; target.style.setProperty(id, encodedURI); element.style.backgroundImage = `var(${id})`;
Et c'est tout !
Pas trop mal, et seulement 610 octets, minifiés et compressés !
Vous pouvez voir une démo ici et télécharger le script complet ici.
Vous trouverez ci-dessous un Codepen simplifié, n'utilisant pas la logique de propriété en ligne :
Y a-t-il des avantages et des inconvénients ? Bien sûr qu'il y en a !
Personnellement, pour mon projet actuel, j'avais besoin d'un moyen simple et clair d'ajouter des numéros de ligne à un aperçu JSON dans un
Cette méthode ne repose pas sur la manipulation du DOM. Les numéros de ligne sont générés sous la forme d'un seul SVG, stocké dans une propriété personnalisée CSS.
Étant donné que les numéros de ligne font partie de l'image d'arrière-plan, ils défilent automatiquement avec le contenu du texte, éliminant ainsi le besoin d'une logique de synchronisation manuelle.
En stockant le SVG généré dans une propriété personnalisée CSS, il peut être réutilisé sur plusieurs éléments. Cela signifie que si plusieurs éléments nécessitent les mêmes numéros de ligne, ils peuvent tous référencer la même propriété personnalisée, évitant ainsi une génération SVG redondante.
Les listes ordonnées sont plus accessibles aux lecteurs d'écran et aux technologies d'assistance, tandis que les numéros de ligne basés sur SVG peuvent être ignorés ou mal interprétés.
Styliser et interagir avec des numéros de ligne individuels dans une liste ordonnée est simple. En revanche, l'approche SVG rend plus difficile la personnalisation ou l'ajout d'interactivité à des numéros de ligne spécifiques.
Les propriétés personnalisées SVG et CSS peuvent ne pas s'afficher de manière cohérente dans tous les navigateurs : l'implémentation actuelle présente des problèmes avec Safari, où nous devons déduire (paddingTop / 10) de TranslateY.
Les listes ordonnées peuvent être plus flexibles pour gérer les mises à jour de contenu dynamique, telles que l'ajout ou la suppression de lignes, alors que l'approche SVG peut nécessiter la régénération et la réapplication de l'intégralité de l'image d'arrière-plan.
Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.
Copyright© 2022 湘ICP备2022001581号-3