Rendering HTML all'interno di textarea


146

Devo essere in grado di eseguire il rendering di alcuni tag HTML all'interno di un'area di testo (ovvero <strong>, <i>, <u>, <a>), ma le textareas interpretano il loro contenuto solo come testo. C'è un modo semplice per farlo senza fare affidamento su librerie / plugin esterni (sto usando jQuery)? In caso contrario, conosci qualche plugin jQuery che potrei usare per fare questo?


L'unico modo per farlo sarà sovrapporre il markup HTML al contenuto del tag textarea tramite trucchi di posizionamento CSS. Nulla ti aiuterà a convincere il browser a rendere i contenuti della textarea in modo diverso. (Perché esattamente "hai bisogno" di farlo?)
Pointy,

Ho solo bisogno che l'utente sia in grado di aggiungere alcuni stili di formattazione al testo che inserisce (proprio come quando scrivi un articolo su Wordpress). Non ho solo bisogno di tutte le funzionalità come l'allineamento del testo e così via, ma solo quei tag di base.
The Coding Monk,

Risposte:


234

Questo non è possibile fare con a textarea. Quello che stai cercando è un div modificabile del contenuto , che è fatto molto facilmente:

<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>


8
è un vero peccato che non sia possibile utilizzarlo praticamente senza l'uso di javascript per inviare le modifiche utilizzando ajax o copiarle in un modulo di input. Se qualcuno ha trovato il modo di farlo, sarei davvero interessato!
Ben

3
@yckart: Beh, non penso che sia effettivamente valido, anche se funziona in tutti i browser che ho provato. contenteditableè un attributo enumerato piuttosto che un attributo booleano (c'è uno inheritstato oltre a truee false) e penso che ciò significhi che specificare un valore è obbligatorio, anche se non riesco a trovare un bit definitivo della specifica per confermarlo. MDN sembra essere d'accordo però.
Tim Down,

2
@yckart: avevo supposto che il browser interpretasse contenteditablesenza valore lo stesso di contenteditable="", che a sua volta è lo stesso di contenteditable="true".
Tim Down

7
Questo non funziona meglio di a textarea. Digitare <strong>someting</strong>nel violino ti lascia con quel testo esatto. L'HTML non è applicato.
Matt Ellen,

2
@MarcusEkwall ma la domanda non era per il rendering html?
phil294,

31

Con una div modificabile è possibile utilizzare il metodo document.execCommand( maggiori dettagli ) per fornire facilmente il supporto per i tag specificati e per qualche altra funzionalità ..

#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>


Questo non funziona in alcuni browser aggiungendo questo come una nota AS del '16
jeffrey crowder

5

Dal momento che hai detto solo rendering, sì, puoi. Potresti fare qualcosa del genere:

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>
Questo lo rende in modo che un textarearendering render HTML! Oltre al lampeggiamento durante il ridimensionamento, l'impossibilità di utilizzare direttamente le classi e la necessità di assicurarsi che il div svgabbia lo stesso formato textareadi allineamento corretto del cursore, funziona!


2

Un addendum a questo. È possibile utilizzare entità carattere (come passare <div>a &lt;div&gt;) e verrà visualizzato nell'area di testo. Ma quando viene salvato, il valore dell'area di testo è il testo come renderizzato . Quindi non è necessario decodificare. Ho appena testato questo su tutti i browser (cioè indietro a 11).


Mi piacerebbe davvero che funzionasse per me, ma non è così. Ad esempio, <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>non viene visualizzato come HTML. Sono su Chrome 46.
sirdank

Hm. Ho copiato e incollato quella stringa direttamente in un documento HTML e questo mi rende il markup corretto per me in Chrome Versione 48.0.2552.0 dev (64-bit) OS X 10.11.1. Quindi forse è un problema di versione.
axlotl,

Continuo a essere votato per questo, quindi ecco una penna: codepen.io/axlotl/pen/YGZOEq
axlotl

0

Ho lo stesso problema ma al contrario e la seguente soluzione. Voglio mettere HTML da un div in un'area di testo (così posso modificare alcune reazioni sul mio sito Web; voglio avere l'area di testo nella stessa posizione.)

Per mettere il contenuto di questo div in un'area di testo che uso:

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>


0

prova questo esempio

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>


-2

Questo è possibile con <textarea> l'unica cosa che devi fare è utilizzare l' editor WYSIWYG di Summernote

interpreta i tag HTML all'interno di una textarea (vale a dire <strong>, <i>, <u>, <a>)


Non utilizza textarea. Utilizza div, che non può essere inviato con un modulo.
Usman Ahmed,

Funziona con textarea, prova a dare id a textarea invece di div. Ho creato un intero progetto usando textarea e summernote. Funziona benissimo!
Fenil Shah,

Qual e il punto? Si comporta come ckeditor se si utilizza textarea. Impossibile eseguire il rendering dei tag HTML come richiesto.
Usman Ahmed,

Perché dovrei usare un editor WYSIWYG? Questa non è davvero una risposta, scusa.
Luca De Nardi,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.