Рендеринг HTML внутри текстового поля


150

Мне нужно иметь возможность отображать некоторые HTML-теги внутри текстового поля (а именно <strong>, <i>, <u>, <a>), но текстовые поля интерпретируют их содержимое только как текст. Есть ли простой способ сделать это, не полагаясь на внешние библиотеки / плагины (я использую jQuery)? Если нет, знаете ли вы какой-нибудь плагин jQuery, который я мог бы использовать для этого?


Единственный способ сделать это - наложить HTML-разметку на содержимое тега textarea с помощью уловок позиционирования CSS. Ничто не поможет вам убедить браузер отображать содержимое текстового поля иначе. (Почему именно вам «нужно» это делать?)
— Pointy

Мне просто нужно, чтобы пользователь мог добавить некоторые стили форматирования к тексту, который он вводит (как при написании статьи в Wordpress). Мне просто нужны не все функции, такие как выравнивание текста и т. Д., А только эти базовые теги.
— The Coding Monk

Ответы:


243

Это невозможно сделать с файлом textarea. То, что вы ищете, - это div с возможностью редактирования содержимого , что очень легко сделать:

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


9
очень жаль, что вы не можете практически использовать это без использования javascript, чтобы либо отправить свои изменения с помощью ajax, либо скопировать их во ввод формы. Если бы кто-нибудь нашел способ сделать это, мне было бы очень интересно!
— Бен

3
@yckart: Ну, я не думаю, что это действительно так, хотя это работает во всех браузерах, которые я пробовал. contenteditableявляется перечислимым атрибутом, а не логическим атрибутом (есть inheritсостояние, а также trueи false), и я думаю, что это означает, что указание значения является обязательным, хотя я не могу найти окончательный бит спецификации, чтобы подтвердить это. Однако MDN, похоже, согласен .
— Tim Down

2
@yckart: я предполагал, что браузер contenteditableбез значения интерпретирует как то же самое contenteditable="", что и contenteditable="true".
— Tim Down

7
Это не работает лучше, чем textarea. Ввод <strong>someting</strong>на скрипке оставляет вам точный текст. HTML не применяется.
— Мэтт Эллен

2
@MarcusEkwall, но разве вопрос не касался рендеринга html?
— phil294

32

С редактируемым div вы можете использовать метод document.execCommand( подробнее ), чтобы легко обеспечить поддержку указанных вами тегов и некоторых других функций.

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


Это не работает в некоторых браузерах, просто добавляя это как примечание AS от '16
— Джеффри Краудер


6

Поскольку вы сказали только «Рендеринг», да, вы можете. Вы можете сделать что-то вроде этого:

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>
Это делает так, что a textareaбудет отображать html! Помимо мигания при изменении размера, невозможности напрямую использовать классы и необходимости убедиться, что div в элементе svgимеет тот же формат, что и textareaдля правильного выравнивания каретки, это работает!


2

Дополнение к этому. Вы можете использовать символьные сущности (например, изменить <div>на &lt;div&gt;), и они будут отображаться в текстовом поле. Но когда он сохраняется, значение textarea - это текст в том виде, в котором он отображается . Так что вам не нужно декодировать. Я только что протестировал это в браузерах (то есть до 11).


Я бы очень хотел, чтобы это сработало для меня, но этого не произошло. Например <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>, не отображается как HTML. Я использую Chrome 46.
— sirdank

Хм. Я скопировал эту строку прямо в html-документ, и он правильно отображает разметку для меня в Chrome версии 48.0.2552.0 dev (64-разрядная версия) OS X 10.11.1. Так что, возможно, проблема в версии.
— axlotl

Я продолжаю голосовать за это, так что вот ручка: codepen.io/axlotl/pen/YGZOEq
— axlotl 07

2

попробуйте этот пример

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>


как насчет применения стиля только к части текста?
— ogostos

0

У меня такая же проблема, но наоборот, и следующее решение. Я хочу поместить html из div в текстовое поле (чтобы я мог редактировать некоторые реакции на моем веб-сайте; я хочу, чтобы текстовое поле находилось в том же месте.)

Чтобы поместить содержимое этого div в текстовое поле, я использую:

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>


-3

Это возможно, <textarea> единственное, что вам нужно сделать, это использовать редактор Summernote WYSIWYG.

он интерпретирует HTML - теги внутри текстового поля (а именно <strong>, <i>, <u>, <a>)


Текстовое поле не используется. Он использует div, который нельзя отправить с формой.
— Усман Ахмед

Он действительно работает с текстовым полем, просто попробуйте указать id в textarea вместо div. Я создал целый проект, используя textarea и summernote. Работает нормально!
— Fenil Shah 08

В чем смысл? Он ведет себя так же, как ckeditor, если используется textarea. Невозможно отобразить теги HTML, как было предложено.
— Усман Ахмед

Почему мне следует использовать редактор WYSIWYG? Это действительно не ответ, извините.
— Лука Де Нарди

Он не использует текстовое поле. Не ответ.
— Рахул Ганди,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.