Mon incursion récente dans la construction de rédacteurs et de popovers Wysiwyg a donné des informations fascinantes sur les API du navigateur. Le congé de maternité a fourni l'occasion idéale pour les plongées profondes dans les défis techniques sans la pression des délais.
Mon objectif actuel consiste à «Codename Goose», un agent d'IA open source avec un backend rouille et une interface de chat à base d'électrons. J'ai soumis une demande de traction pour intégrer un éditeur WYSIWYG, optant pour une solution personnalisée sur les packages existants pour minimiser la taille du bundle. Cependant, les mainteneurs ont suggéré une barre d'outils à popover pour répondre aux préoccupations de l'espace.
La création de cette barre d'outils flottante s'est avérée difficile de façon inattendue. Mes objectifs étaient simples:
Les zones de texte présentaient des complexités uniques. Contrairement aux éléments HTML standard, où la manipulation du contenu et le positionnement précis sont facilement disponibles, les zones de texte exposent uniquement le texte brut et les API de sélection de base. Le navigateur gère le rendu en interne.
pour illustrer, considérez cette analogie:
Les navigateurs modernes offrent une API popover intégrée pour créer des éléments pop-up. Voici un exemple:
Malgré sa compatibilité et sa facilité d'utilisation de son arrosage, l'API Popover a des limites:
popovertarget
. Merci à Mark Techson, qui m'a présenté l'API Popover via la conférence de l'UNA Kravets, "moins Cruft, plus de puissance: tirer parti de la puissance de la plate-forme Web."
Pour positionner le popover en fonction de la sélection du texte de l'utilisateur, j'avais besoin:
Article de blog de Colby Fayock, "Comment partager le texte sélectionné dans React with the Sélection API", m'a présenté le Selection API
(accessible via window.getSelection()
). Cette API renvoie un objet Selection
détaillant le texte sélectionné.
getRangeAt(0)
La méthode getRangeAt(0)
dans l'objet Selection
fournit les décalages de démarrage et de fin de la sélection:
startOffset
: L'indice débutant de la sélection. endOffset
: l'indice de fin de la sélection (après le dernier caractère sélectionné). Par exemple, dans "Hello, World! Bienvenue.", La sélection "Monde" donne startOffset
= 7 et endOffset
= 12.
Remarque: getRangeAt(0)
accède à la première sélection. Les navigateurs comme Firefox permettent plusieurs sélections (CTRL-CLICK), mais l'accès aux index au-delà de 0 dans les navigateurs à sélection unique entraîne des erreurs.
getBoundingClientRect()
getRangeAt(0)
donne accès à getBoundingClientRect()
, qui renvoie une boîte de délimitation avec les coordonnées, la largeur et la hauteur du haut sélectionné, de la droite, du bas, de la largeur gauche. Cela permet un placement de popover précis au-dessus de la sélection, comme démontré:
Cependant, cette approche est limitée dans les zones de texte.
La technique "DIV miroir", découverte à travers des discussions avec Claude, propose une solution de contournement. Une div invisible superpose la zone de texte, reflétant son contenu et son style. Les interactions utilisateur se produisent dans cette div, offrant un accès complet Selection API
tout en maintenant une apparence de zone de texte standard.
Article de blog de Jhey Thompkins, "Comment: Où est le curseur de texte?", Et la méthode getComputedStyle()
(qui renvoie les styles CSS calculés d'un élément) a contribué à correspondre précisément à l'apparition de la zone de texte dans la superposition Div.
Cependant, cette miroir n'est pas parfaite:
De nombreux packages fonctionnent bien avec les éléments DOM standard, mais luttent avec les zones de texte en raison des mêmes limitations fondamentales: accès restreint au rendu interne et au positionnement.
Malgré les progrès de l'interaction riche en texte, travailler avec des zones de texte reste étonnamment complexe. Explorer ces API de navigateur a été une expérience enrichissante. Les futurs API peuvent simplifier les tâches comme les popovers basées sur la sélection. Si vous avez rencontré des solutions alternatives, j'apprécierais d'en entendre parler.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!