Rendering HTML di dalam textarea

146

Saya harus dapat merender beberapa tag HTML di dalam textarea (yaitu <strong>, <i>, <u>, <a>) tetapi textareas hanya menafsirkan kontennya sebagai teks. Apakah ada cara mudah untuk melakukannya tanpa mengandalkan perpustakaan / plugin eksternal (saya menggunakan jQuery)? Jika tidak, apakah Anda tahu ada plugin jQuery yang bisa saya gunakan untuk melakukan ini?

Biarawan Pengkodean
sumber
Satu-satunya cara untuk melakukannya adalah dengan overlay markup HTML Anda di atas konten tag teks melalui trik penentuan posisi CSS. Tidak ada yang akan membantu Anda meyakinkan browser untuk merender konten teks secara berbeda. (Mengapa tepatnya Anda "perlu" melakukan ini?)
Runcing
Saya hanya perlu pengguna untuk dapat menambahkan beberapa gaya format ke teks yang dia masukkan (seperti ketika Anda menulis artikel di Wordpress). Saya hanya tidak membutuhkan semua fitur seperti perataan teks dan sebagainya, tetapi hanya tag-tag dasar itu.
The Coding Monk

Jawaban:

234

Ini tidak mungkin dilakukan dengan a textarea. Apa yang Anda cari adalah div konten yang dapat diedit , yang sangat mudah dilakukan:

<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
sumber
8
sungguh memalukan bahwa Anda tidak bisa menggunakan ini tanpa menggunakan javascript untuk mengirim perubahan menggunakan ajax atau menyalinnya ke input formulir. Jika ada yang menemukan cara untuk melakukannya saya akan sangat tertarik!
Ben
3
@yckart: Ya, saya pikir itu tidak benar, meskipun itu berfungsi di semua browser yang saya coba. contenteditableadalah atribut enumerasi daripada atribut Boolean (ada inheritkeadaan juga dan truedan false), dan saya pikir itu berarti bahwa menentukan nilai adalah wajib, meskipun saya tidak dapat menemukan sedikit spesifikasi untuk mengkonfirmasi ini. MDN tampaknya setuju .
Tim Down
2
@yckart: Saya mengasumsikan browser mengartikan contenteditabletanpa nilai sama dengan contenteditable="", yang pada gilirannya sama dengan contenteditable="true".
Tim Down
7
Ini tidak berfungsi lebih baik daripada a textarea. Mengetikkan <strong>someting</strong>biola membuat Anda dengan teks yang tepat. HTML tidak diterapkan.
Matt Ellen
2
@MarcusEkwall tetapi bukankah pertanyaannya menanyakan rendering html?
phil294
31

Dengan div yang dapat diedit, Anda dapat menggunakan metode document.execCommand( detail lebih lanjut ) untuk dengan mudah memberikan dukungan untuk tag yang Anda tentukan dan untuk beberapa fungsi lainnya ..

#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
sumber
Ini tidak berfungsi di beberapa browser hanya menambahkan ini sebagai catatan AS dari '16
jeffrey crowder
5

Karena Anda hanya mengatakan render, ya Anda bisa. Anda dapat melakukan sesuatu seperti ini:

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>
Ini membuatnya agar textareakehendak membuat html! Selain flashing ketika mengubah ukuran, ketidakmampuan untuk langsung menggunakan kelas dan harus memastikan bahwa div dalam svgformat yang sama dengan textareaagar tanda sisipan untuk menyelaraskan dengan benar, itu berfungsi!

merlin
sumber
2

Tambahan untuk ini. Anda dapat menggunakan entitas karakter (seperti mengubah <div>ke &lt;div&gt;) dan itu akan ditampilkan di textarea. Tetapi ketika disimpan, nilai dari textarea adalah teks seperti yang diberikan . Jadi Anda tidak perlu melakukan de-encode. Saya baru saja menguji ini di browser (yaitu kembali ke 11).

kapak
sumber
Saya benar-benar ingin ini bekerja untuk saya tetapi tidak. Misalnya <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>tidak ditampilkan sebagai HTML. Saya menggunakan Chrome 46.
sirdank
Hm Saya menyalin-menempelkan string itu langsung ke dokumen html dan menjadikan markup dengan benar untuk saya di Versi Chrome 48.0.2552.0 dev (64-bit) OS X 10.11.1. Jadi mungkin ini masalah versi.
axlotl
Saya terus mendapatkan suara untuk ini jadi inilah pena: codepen.io/axlotl/pen/YGZOEq
axlotl
0

Saya memiliki masalah yang sama tetapi secara terbalik, dan solusi berikut. Saya ingin meletakkan html dari div di sebuah textarea (jadi saya dapat mengedit beberapa reaksi di situs web saya; Saya ingin memiliki textarea di lokasi yang sama.)

Untuk memasukkan konten div ini ke dalam textarea, saya menggunakan:

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

coba contoh ini

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

Ini dimungkinkan dengan <textarea> satu-satunya hal yang perlu Anda lakukan adalah menggunakan editor Summernote WYSIWYG

menafsirkan tag HTML dalam textarea (yaitu <strong>, <i>, <u>, <a>)

Fenil Shah
sumber
Itu tidak menggunakan textarea. Ini menggunakan div, yang tidak bisa dikirimkan dengan formulir.
Usman Ahmed
Itu bekerja dengan textarea, coba saja berikan id ke textarea bukan div. Saya membuat seluruh proyek menggunakan textarea dan summernote. Ini bekerja dengan baik!
Fenil Shah
Apa gunanya? Berperilaku sama dengan ckeditor jika textarea digunakan. Tidak dapat membuat tag HTML seperti yang diminta.
Usman Ahmed
Mengapa saya harus menggunakan editor WYSIWYG? Ini benar-benar bukan jawaban, maaf.
Luca De Nardi