Рендеринг 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.