Rendu HTML dans la zone de texte

146

Je dois être capable de rendre certaines balises HTML à l'intérieur d'une zone de texte (à savoir <strong>, <i>, <u>, <a>) mais les zones de texte n'interprètent leur contenu que comme du texte. Existe-t-il un moyen simple de le faire sans compter sur des bibliothèques / plugins externes (j'utilise jQuery)? Sinon, connaissez-vous un plugin jQuery que je pourrais utiliser pour faire cela?

Le moine codant
la source
La seule façon de le faire sera de superposer votre balisage HTML sur le contenu de la balise textarea via des astuces de positionnement CSS. Rien ne vous aidera à convaincre le navigateur de rendre le contenu de la zone de texte différemment. (Pourquoi exactement avez-vous "besoin" de faire cela?)
Pointy
J'ai juste besoin que l'utilisateur puisse ajouter des styles de mise en forme au texte qu'il entre (un peu comme lorsque vous écrivez un article sur Wordpress). Je n'ai tout simplement pas besoin de toutes les fonctionnalités telles que l'alignement du texte, etc., mais uniquement de ces balises de base.
The Coding Monk

Réponses:

234

Cela n'est pas possible avec un fichier textarea. Ce que vous recherchez, c'est une div modifiable de contenu , ce qui se fait très facilement:

<div contenteditable="true"></div>

jsFiddle

div.editable {
    width: 300px;
    height: 200px;
    border: 1px solid #ccc;
    padding: 5px;
}

strong {
  font-weight: bold;
}
<div contenteditable="true">This is the first line.<br>
See, how the text fits here, also if<br>there is a <strong>linebreak</strong> at the end?
<br>It works nicely.
<br>
<br><span style="color: lightgreen">Great</span>.
</div>

mekwall
la source
9
C'est vraiment dommage que vous ne puissiez pratiquement pas utiliser cela sans utiliser javascript pour soumettre vos modifications en utilisant ajax ou les copier dans une entrée de formulaire. Si quelqu'un a trouvé un moyen de le faire, je serais vraiment intéressé!
Ben
3
@yckart: Eh bien, je ne pense pas que ce soit réellement valable, même si cela fonctionne dans tous les navigateurs que j'ai essayés. contenteditableest un attribut énuméré plutôt qu'un attribut booléen (il y a un inheritétat ainsi que trueet false), et je pense que cela signifie que la spécification d'une valeur est obligatoire, bien que je ne puisse pas trouver un bit définitif de la spécification pour le confirmer. MDN semble cependant être d'accord .
Tim Down
2
@yckart: J'avais supposé que le navigateur interprétait contenteditablesans valeur comme étant le même que contenteditable="", ce qui à son tour est le même que contenteditable="true".
Tim Down
7
Cela ne fonctionne pas mieux qu'un fichier textarea. Taper <strong>someting</strong>dans le violon vous laisse avec ce texte exact. Le HTML n'est pas appliqué.
Matt Ellen
2
@MarcusEkwall mais la question n'était-elle pas de demander un rendu html?
phil294
31

Avec un div modifiable, vous pouvez utiliser la méthode document.execCommand( plus de détails ) pour fournir facilement la prise en charge des balises que vous avez spécifiées et pour certaines autres fonctionnalités.

#text {
    width : 500px;
	min-height : 100px;
	border : 2px solid;
}
<div id="text" contenteditable="true"></div>
<button onclick="document.execCommand('bold');">toggle bold</button>
<button onclick="document.execCommand('italic');">toggle italic</button>
<button onclick="document.execCommand('underline');">toggle underline</button>

Sampath Liyanage
la source
Cela ne fonctionne pas dans certains navigateurs simplement en ajoutant ceci comme une note à partir de '16
jeffrey crowder
5

Puisque vous avez seulement dit rendre, oui vous pouvez. Vous pouvez faire quelque chose du genre:

function render(){
	var inp     = document.getElementById("box");
	var data = `
<svg xmlns="http://www.w3.org/2000/svg" width="${inp.offsetWidth}" height="${inp.offsetHeight}">
<foreignObject width="100%" height="100%">
<div xmlns="http://www.w3.org/1999/xhtml" 
style="font-family:monospace;font-style: normal; font-variant: normal; font-size:13.3px;padding:2px;;">
${inp.value} <i style="color:red">cant touch this</i>
</div>
</foreignObject>
</svg>`;
	var blob = new Blob( [data], {type:'image/svg+xml'} );
	var url=URL.createObjectURL(blob);
	inp.style.backgroundImage="url("+URL.createObjectURL(blob)+")";
 }
 onload=function(){
  render();
  ro = new ResizeObserver(render);
	ro.observe(document.getElementById("box"));
 }
#box{
  color:transparent;
  caret-color: black;
  font-style: normal;/*must be same as in the svg for caret to align*/
  font-variant: normal; 
  font-size:13.3px;
  padding:2px;
  font-family:monospace;
}
<textarea id="box" oninput="render()">you can edit me!</textarea>
Cela fait en sorte qu'un textarearendu html! Outre le clignotement lors du redimensionnement, l'impossibilité d'utiliser directement les classes et le fait de devoir s'assurer que le div dans le svga le même format que celui textareadu curseur pour s'aligner correctement, ça marche!

Merlin
la source
2

Un addendum à cela. Vous pouvez utiliser des entités de caractère (comme changer <div>en &lt;div&gt;) et elles seront rendues dans la zone de texte. Mais lorsqu'il est enregistré, la valeur de la zone de texte est le texte tel qu'il est rendu . Vous n'avez donc pas besoin de désencoder. Je viens de tester cela sur les navigateurs (c'est-à-dire retour à 11).

axlotl
la source
J'aimerais vraiment que cela fonctionne pour moi, mais ce n'est pas le cas. Par exemple, <textarea> check for url &lt;B&gt;http://localhost/Dashboard.aspx&lt;/B&gt; &lt;BR&gt; Tool Started at &lt;B&gt;11/10/2015 3:56:58 AM&lt;/B&gt; &lt;BR&gt; .... </textarea>ne s'affiche pas au format HTML. Je suis sur Chrome 46.
sirdank
Hm. J'ai copié-collé cette chaîne directement dans un document html et cela rend le balisage correctement pour moi dans Chrome Version 48.0.2552.0 dev (64 bits) OS X 10.11.1. Alors peut-être que c'est un problème de version.
axlotl
Je continue de recevoir des votes négatifs
axlotl
0

J'ai le même problème mais à l'envers, et la solution suivante. Je veux mettre le html d'un div dans une zone de texte (pour pouvoir modifier certaines réactions sur mon site Web; je veux avoir la zone de texte au même endroit.)

Pour mettre le contenu de ce div dans une zone de texte, j'utilise:

var content = $('#msg500').text();
$('#msg500').wrapInner('<textarea>' + content + '</textarea>');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="msg500">here some <strong>html</strong> <i>tags</i>.</div>

Houdini
la source
0

essayez cet exemple

function toggleRed() {
  var text = $('.editable').text();
  $('.editable').html('<p style="color:red">' + text + '</p>');
}

function toggleItalic() {
  var text = $('.editable').text();
  $('.editable').html("<i>" + text + "</i>");
}

$('.bold').click(function() {
  toggleRed();
});

$('.italic').click(function() {
  toggleItalic();
});
.editable {
  width: 300px;
  height: 200px;
  border: 1px solid #ccc;
  padding: 5px;
  resize: both;
  overflow: auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="editable" contenteditable="true"></div>
<button class="bold">toggle red</button>
<button class="italic">toggle italic</button>

David Grinstein
la source
-2

Ceci est possible avec <textarea> la seule chose que vous devez faire est d'utiliser l' éditeur Summernote WYSIWYG

il interprète les balises HTML dans une zone de texte ( à savoir <strong>, <i>, <u>, <a>)

Fenil Shah
la source
Il n'utilise pas textarea. Il utilise div, qui ne peut pas être soumis avec un formulaire.
Usman Ahmed
Cela fonctionne avec textarea, essayez simplement de donner id à textarea au lieu de div. J'ai créé tout un projet en utilisant textarea et summernote. Ça fonctionne bien!
Fenil Shah
À quoi ça sert? Il se comporte de la même manière que ckeditor si textarea est utilisé. Impossible d'afficher les balises HTML comme demandé.
Usman Ahmed
Pourquoi utiliser un éditeur WYSIWYG? Ce n'est vraiment pas une réponse, désolé.
Luca De Nardi