J'ai besoin de créer l'éditeur wysiwyg comme tel:
De cette façon, nous pouvons rendre le texte en surbrillance de syntaxe, tout en conservant la fonctionnalité d'édition d'une zone de texte.
Mon problème est mon manque d'expertise en CSS. Donc, peu importe le nombre de variantes que j'essaie, il y a toujours un problème avec le retour à la ligne, le défilement ou les alignements qui ne sont pas synchronisés.
Voici une variante. Le composant éditeur a un texte gris transparent tandis que le div sous-jacent est du texte orange, afin que nous puissions voir quand ils s'alignent.
Le défi est de les faire toujours aligner, quel que soit le contenu, le défilement ou la taille .
<div class="scrollable"> <div id="view" class="content"> <textarea id="editor" class="content" onInput="update();" class="content"></textarea> <div id="richtext" class="content"></div> </div> </div>
.scrollable {
width: 300px;
height: 100px;
overflow: scroll;
border : 1px solid grey;
}
.content {
font-family: monospace;
font-size: 18px;
position: absolute;
top: 0;
left: 0;
border: none;
overflow: hidden;
min-width: 100%;
min-height: 100%;
outline: none;
resize: none;
margin: none;
padding: 0;
box-shadow: none;
box-sizing: border-box;
white-space: pre;
display: block;
overflow: none;
}
#richtext {
z-index: -10;
color: orange;
}
#view {
height: 100%;
position: relative;
display: inline-block;
}
#editor {
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: transparent;
color: #00000055;
caret-color: black;
}
function update(){
document.getElementById("richtext").innerHTML =
document.getElementById("editor").value;
}
4 Réponses :
Changez la classe .content min-height: 100%; en min-height: 100vh; et changez également white- space: pre; to white-space: pre-wrap;
Voici le violon mis à jour:
<div class="scrollable">
<div id="view" class="content">
<textarea id="editor" class="content" onInput="update();" class="content"></textarea>
<div id="richtext" class="content"></div>
</div>
</div>
.scrollable {
width: 300px;
height: 100px;
overflow: scroll;
border: 1px solid grey;
}
.content {
font-family: monospace;
font-size: 18px;
position: absolute;
top: 0;
left: 0;
border: none;
overflow: hidden;
min-width: 100%;
min-height: 100vh;
outline: none;
resize: none;
margin: none;
padding: 0;
box-shadow: none;
box-sizing: border-box;
white-space: pre-wrap;
display: block;
overflow: none;
}
#richtext {
z-index: -10;
color: orange;
}
#view {
height: 100%;
position: relative;
display: inline-block;
}
#editor {
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: transparent;
color: #00000055;
caret-color: black;
}
function update() {
document.getElementById("richtext").innerHTML =
document.getElementById("editor").value;
}
Au fur et à mesure que le contenu s'allonge, il se désynchronise.
Avez-vous BESOIN de la zone de texte et du div sous-jacent? J'essayais de trouver un bon éditeur de texte riche récemment et j'ai remarqué que beaucoup de ceux modernes utilisent, juste un div avec contenteditable = "true" comme attribut HTML5. Voici quelques bons exemples de ceci dans le monde réel.
Si vous avez vraiment besoin de vous en tenir aux deux éléments, je les réduirais tous les deux en métal nu en réinitialisant TOUS les attributs:
textarea,
.preview {
all: initial;
}
Ensuite, construisez le style du texte donc c'est complètement le même sur les deux. font-family , font-size , font-weight , line-height , etc. assurez-vous qu'il y a une bonne réinitialisation ou normalisation CSS en place.
Le problème est que les navigateurs traitent le rendu du texte différemment dans une zone de texte qu'ailleurs, le but serait donc de les forcer à être les mêmes en étant un peu lourds à main levée.
J'utilise Elm et il existe de nombreux problèmes connus avec contenteditable. Je l'évite exprès.
C'est tout à fait compréhensible. Je vous ai également donné quelques éléments CSS à essayer. Le problème est que les navigateurs traitent le rendu du texte différemment dans une zone de texte qu'ailleurs, le but serait donc de les forcer à être les mêmes en étant un peu lourd.
L'alignement se désynchronise car vous finirez par dépasser la hauteur définie de la zone de texte et son défilement interne entre en action.
Pour éviter cela, mettez à jour la hauteur de la zone de texte afin qu'elle s'étende automatiquement.
<div class="scrollable"> <div id="view" class="content"> <textarea id="editor" class="content" onInput="update();" class="content"></textarea> <div id="richtext" class="content"></div> </div> </div>
.scrollable {
width: 300px;
height: 100px;
overflow: scroll;
border : 1px solid grey;
}
.content {
font-family: monospace;
font-size: 18px;
position: absolute;
top: 0;
left: 0;
border: none;
overflow: hidden;
min-width: 100%;
min-height: 100%;
outline: none;
resize: none;
margin: none;
padding: 0;
box-shadow: none;
box-sizing: border-box;
white-space: pre;
display: block;
overflow: none;
}
#richtext {
z-index: -10;
color: orange;
}
#view {
height: 100%;
position: relative;
display: inline-block;
}
#editor {
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: transparent;
color: #00000055;
caret-color: black;
}
var richtext = document.getElementById("richtext")
var editor = document.getElementById("editor")
function update(){
richtext.innerHTML = editor.value;
editor.style.width = 'auto';
editor.style.width = editor.scrollWidth+'px';
editor.style.height = 'auto';
editor.style.height = editor.scrollHeight+'px';
}
function update(){
richtext.innerHTML = editor.value;
editor.style.width = 'auto';
editor.style.width = editor.scrollWidth+'px';
editor.style.height = 'auto';
editor.style.height = editor.scrollHeight+'px';
}
Edit: il en va de même pour la largeur, évidemment.
Vous avez utilisé la position absolue. Ainsi div et textarea sont placés l'un sur l'autre. supprimer la position, la largeur min et la largeur max pour div et textarea. et utilisez display: flex-inline pour div # view; vous pouvez changer la valeur de l'espace blanc pour un meilleur résultat.
Ce que vous décrivez n'est pas clair (d'un point de vue technique). Veuillez créer un exécutable exemple minimal reproductible . Pensez également à ajouter les résultats de votre recherche à la question. Sinon, il apparaîtra comme si vous n'en avez effectué aucune.
Je vais travailler pour rendre cela plus clair. Il n'y a aucune obligation de SO pour montrer le travail effectué. Et en fait, mon travail se fait en elm-ui, en elm. La solution à mon problème commence par comprendre les mécanismes d'une solution CSS, mais mon code existant n'aidera personne ici car ce n'est pas un problème spécifique à elm / elm-ui. Si vous êtes curieux, voici le code gist.github.com/z5h /…
Quels que soient les outils, la technologie backend ou le framework frontend utilisés, cela se résume à la façon dont les navigateurs interprètent votre sortie CSS et vous semblez avoir besoin d'aide pour cela. Ne fournissez pas le code source, fournissez un exemple de travail (basé sur la quantité minimale de code de sortie (traité = ce qui frappe le navigateur) nécessaire pour le reproduire). Personne n'a dit qu'il y avait une exigence SO pour montrer votre recherche ou votre code existant, mais cela augmenterait considérablement vos chances d'obtenir une réponse utile, ce qui semble, à son tour, être votre exigence / attente.
@ z5h On dirait que vous avez répondu à votre propre question. Mettez les 2 divs dans un wrapper et donnez au wrapper une
hauteuret unoverflow: autoOk, j'ai ajouté ce que j'ai. Ça ne marche pas. Toute aide est appréciée.
Le moyen le plus simple de résoudre votre problème consiste à supprimer textarea et à utiliser
divaveccontenteditable = "true". Vous voudrez peut-être voir comment CKEditor le fait.@Duannx J'utilise Elm et il existe de nombreux problèmes connus avec contenteditable. Je l'évite exprès.