HTML in Textbereich rendern

145

Ich muss in der Lage sein, einige HTML-Tags in einem Textbereich zu rendern (nämlich <strong>, <i>, <u>, <a>), aber Textbereiche interpretieren ihren Inhalt nur als Text. Gibt es eine einfache Möglichkeit, dies zu tun, ohne sich auf externe Bibliotheken / Plugins zu verlassen (ich verwende jQuery)? Wenn nicht, kennen Sie ein jQuery-Plugin, mit dem ich dies tun könnte?

Der codierende Mönch
quelle
Die einzige Möglichkeit, dies zu tun, besteht darin, Ihr HTML-Markup über CSS-Positionierungstricks über den Inhalt des Textbereichs-Tags zu legen. Nichts hilft Ihnen, den Browser davon zu überzeugen, den Inhalt des Textbereichs anders zu rendern. (Warum genau "brauchen" Sie das?)
Pointy
Ich brauche nur den Benutzer, um dem eingegebenen Text einige Formatierungsstile hinzufügen zu können (ähnlich wie beim Schreiben eines Artikels in Wordpress). Ich brauche einfach nicht alle Funktionen wie Textausrichtung usw., sondern nur diese grundlegenden Tags.
Der codierende Mönch

Antworten:

233

Dies ist mit a nicht möglich textarea. Was Sie suchen, ist ein inhaltsbearbeitbares Div, das sehr einfach zu erstellen ist:

<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
quelle
8
Es ist wirklich schade, dass Sie dies ohne die Verwendung von Javascript praktisch nicht verwenden können, um Ihre Änderungen entweder mit Ajax einzureichen oder in eine Formulareingabe zu kopieren. Wenn jemand einen Weg gefunden hat, wäre ich wirklich interessiert!
Ben
3
@yckart: Nun, ich glaube nicht, dass das tatsächlich gültig ist, obwohl es in allen Browsern funktioniert, die ich ausprobiert habe. contenteditableist eher ein Aufzählungsattribut als ein Boolesches Attribut (es gibt einen inheritStatus sowie trueund false), und ich denke , das bedeutet, dass die Angabe eines Werts obligatorisch ist, obwohl ich kein definitives Bit der Spezifikation finden kann, um dies zu bestätigen. MDN scheint jedoch zuzustimmen .
Tim Down
2
@yckart: Ich hatte angenommen, dass der Browser contenteditableohne Wert den gleichen Wert wie interpretiert contenteditable="", was wiederum der gleiche ist wie contenteditable="true".
Tim Down
7
Das funktioniert nicht besser als a textarea. Wenn Sie <strong>someting</strong>in die Geige tippen, erhalten Sie genau diesen Text. Der HTML-Code wird nicht angewendet.
Matt Ellen
2
@MarcusEkwall, aber war die Frage nicht nach HTML-Rendering?
Phil294
31

Mit einem bearbeitbaren div können Sie die Methode document.execCommand( weitere Details ) verwenden, um auf einfache Weise die Unterstützung für die von Ihnen angegebenen Tags und einige andere Funktionen bereitzustellen.

#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
quelle
Dies funktioniert in einigen Browsern nicht, wenn Sie dies nur als Notiz AS von '16
jeffrey crowder
5

Da du nur Rendern gesagt hast, kannst du das ja. Sie könnten etwas in dieser Richtung tun:

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>
Dies macht es so, dass a textareaHTML rendern wird! Abgesehen vom Blinken beim Ändern der Größe, der Unfähigkeit, Klassen direkt zu verwenden und sicherstellen zu müssen, dass das Div im svgFormat das gleiche Format hat wie das, textareadamit das Caret korrekt ausgerichtet wird, funktioniert es!

Merlin
quelle
2

Ein Nachtrag dazu. Sie können Zeichenentitäten verwenden (z. B. Ändern <div>in &lt;div&gt;), die im Textbereich gerendert werden. Wenn es jedoch gespeichert wird, ist der Wert des Textbereichs der gerenderte Text . Sie müssen also nicht entschlüsseln. Ich habe dies gerade über alle Browser hinweg getestet (dh zurück zu 11).

Axlotl
quelle
Ich würde wirklich gerne, dass dies für mich funktioniert, aber das tat es nicht. Wird beispielsweise <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>nicht als HTML angezeigt. Ich bin auf Chrome 46.
Sirdank
Hm. Ich habe diese Zeichenfolge direkt in ein HTML-Dokument kopiert und das Markup wird in Chrome Version 48.0.2552.0 dev (64-Bit) OS X 10.11.1 ordnungsgemäß für mich gerendert. Vielleicht ist es ein Versionsproblem.
Axlotl
Ich werde immer wieder dafür herabgestimmt, also hier ein Stift: codepen.io/axlotl/pen/YGZOEq
axlotl
0

Ich habe das gleiche Problem, aber umgekehrt, und die folgende Lösung. Ich möchte HTML von einem Div in einen Textbereich einfügen (damit ich einige Reaktionen auf meiner Website bearbeiten kann; ich möchte den Textbereich am selben Ort haben.)

Um den Inhalt dieses Div in einen Textbereich zu setzen, benutze ich:

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

Versuchen Sie dieses Beispiel

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

Dies ist möglich, <textarea> wenn Sie nur den Summernote WYSIWYG-Editor verwenden müssen

es interpretiert HTML - Tags in einem Textfeld (nämlich <strong>, <i>, <u>, <a>)

Fenil Shah
quelle
Es wird kein Textbereich verwendet. Es wird div verwendet, das nicht mit einem Formular eingereicht werden kann.
Usman Ahmed
Es funktioniert mit Textarea. Versuchen Sie einfach, Textarea anstelle von div eine ID zu geben. Ich habe ein ganzes Projekt mit Textarea und Summernote erstellt. Es funktioniert gut!
Fenil Shah
Was ist der Punkt? Es verhält sich wie ckeditor, wenn Textbereich verwendet wird. HTML-Tags können nicht wie gewünscht gerendert werden.
Usman Ahmed
Warum sollte ich einen WYSIWYG-Editor verwenden? Dies ist wirklich keine Antwort, sorry.
Luca De Nardi