Как я могу вставить новую строку / возврат каретки в element.textContent? - PullRequest
49 голосов
/ 02 апреля 2012

Как бы глупо это не звучало, я до сих пор не нашел подходящего ответа.

Допустим, я хочу динамически создать новый элемент DOM и заполнить его textContent / innerText со строковым литералом JS.
Строка такая длинная, что хотелось бы разбить ее на три части:

var h1 = document.createElement("h1");

h1.textContent = "This is a very long string and I would like to insert a carriage return HERE...
moreover, I would like to insert another carriage return HERE... 
so this text will display in a new line";

Проблема в том, если я напишу

h1.textContent = "...I would like to insert a carriage return here... \n";

это не работает, вероятно, потому что браузер считает '\ n' чистым текстом и отображает его как таковой (\ r тоже не работает).

С другой стороны, я мог бы изменить h1.innerHTML вместо textContent и написать:

h1.innerHTML = "...I would like to insert a carriage return here...<br />";

Здесь
выполнит эту работу, но это заменит не только текстовое содержимое, но и все содержимое HTML моего h1, что не совсем то, что я хочу.

Есть ли простой способ решить мою проблему?
Я бы не стал создавать несколько элементов блока, чтобы текст располагался на разных строках.
Любая идея будет принята с благодарностью.
Заранее спасибо.

Ответы [ 9 ]

80 голосов
/ 10 октября 2015

Я знаю этот вопрос, заданный давно.

У меня была похожая проблема несколько дней назад, я передавал значение из веб-сервиса в формате json и поместил его в table cell contentText.

Поскольку значение передается в формате, например, "text row1\r\ntext row2" и т. Д.

Для новой строки в textContent Необходимо использовать \r\n инаконец, мне пришлось использовать css white-space: pre-line; (текст будет перенесен, когда необходимо, и на разрывы строк), и все идет хорошо.

Или, Вы можете использовать только white-space: pre;, и тогда текст будет перенесен только на разрывы строк (в данном случае \r\n).

Итак, есть пример, как решить это с переносомтекст только на разрывы строк:

var h1 = document.createElement("h1");

//setting this css style solving problem with new line in textContent
h1.setAttribute('style', 'white-space: pre;');

//add \r\n in text everywhere You want for line-break (new line)
h1.textContent = "This is a very long string and I would like to insert a carriage return \r\n...";
h1.textContent += "moreover, I would like to insert another carriage return \r\n...";
h1.textContent += "so this text will display in a new line";

document.body.appendChild(h1);
31 голосов
/ 04 августа 2012

Я столкнулся с этим некоторое время назад. Я обнаружил, что хорошим решением было использование ASCII-представления возвратов каретки (КОД 13). В JavaScript есть удобная функция под названием String.fromCharCode(), которая генерирует строковую версию кода ASCII или несколько кодов, разделенных запятой. В моем случае мне нужно было создать CSV-файл из длинной строки и записать его в текстовую область. Мне нужно было иметь возможность вырезать текст из текстовой области и сохранить его в блокноте. Когда я пытался использовать метод <br />, он не сохранял бы возврат каретки, однако, используя метод fromCharCode, он сохранял возвраты. Смотрите мой код ниже:

h1.innerHTML += "...I would like to insert a carriage return here..." + String.fromCharCode(13);
h1.innerHTML += "Ant the other line here..." + String.fromCharCode(13);
h1.innerHTML += "And so on..." + String.fromCharCode(13);
h1.innerHTML += "This prints hello: " + String.fromCharCode(72,69,76,76,79);

Подробнее об этом методе см. Здесь: w3Schools-fromCharCode ()

См. Здесь для кодов ASCII: Коды ASCII

5 голосов
/ 02 апреля 2012

Вы можете использовать регулярные выражения для замены символов '\ n' или '\ n \ r' на ''.

у вас есть это:

var h1 = document.createElement("h1");

h1.textContent = "This is a very long string and I would like to insert a carriage return HERE...
moreover, I would like to insert another carriage return HERE... 
so this text will display in a new line";

вы можете заменить свои символы следующим образом:

h1.innerHTML = h1.innerHTML.replace(/\n\r?/g, '<br />');

проверить ссылку на JavaScript для объектов String и Regex:

http://www.w3schools.com/jsref/jsref_replace.asp

http://www.w3schools.com/jsref/jsref_obj_regexp.asp

4 голосов
/ 02 апреля 2012

Вы можете объединить строки ...

h1.innerHTML += "...I would like to insert a carriage return here...<br />";
h1.innerHTML += "Ant the other line here... <br />";
h1.innerHTML += "And so on...<br />";

jsFiddle.

3 голосов
/ 14 июня 2012

Использование element.innerHTML="some \\\\n some";.

2 голосов
/ 29 июля 2016

Я обнаружил, что вставка \\n работает.Т.е. вы избежали экранированного символа новой строки

2 голосов
/ 24 июня 2015

Ни одно из вышеперечисленных решений не помогло мне. Я пытался добавить перевод строки и дополнительный текст к элементу <p>. Я обычно использую Firefox, но мне нужна совместимость с браузером. Я читал, что только Firefox поддерживает свойство textContent, только Internet Explorer поддерживает свойство innerText, но оба поддерживают свойство innerHTML. Однако ни добавление <br />, ни \n, ни \r\n ни к одному из этих свойств не привело к появлению новой строки. Следующее, однако, сработало:

<html>
<body>
<script type="text/javascript">
  function modifyParagraph() {

  var p;
  p=document.getElementById("paragraphID");
  p.appendChild(document.createElement("br"));
  p.appendChild(document.createTextNode("Additional text."));
}    
</script>

<p id="paragraphID">Original text.</p>

<input type="button" id="pbutton" value="Modify Paragraph" onClick="modifyParagraph()" />
</body>
</html>
0 голосов
/ 31 мая 2018

Ответ Нелека - лучший, опубликованный до сих пор, но он основан на установке значения css: white-space: pre, что может быть нежелательно.

Я хотел бы предложить другое решение, котороепытается решить реальный вопрос, который должен был быть задан здесь:

«Как вставить ненадежный текст в элемент DOM?»

Если вы доверяете тексту, почему бы просто не использовать innerHTML?

domElement.innerHTML = trustedText.replace(/\r/g, '').replace(/\n/g, '<br>');

должно быть достаточно для всех разумных случаев.

Если вы решили, что следует использовать .textContent вместо .innerHTML, это означает, что вы не доверяете тексту, которому высобирается вставить, верно?Это разумная проблема.

Например, у вас есть форма, в которой пользователь может создать сообщение, и после публикации текст сообщения сохраняется в вашей базе данных, а затем добавляется на страницы всякий раз, когда другие пользователипосетите соответствующую страницу.

Если вы используете здесь innerHTML, вы получите брешь в безопасности.то есть пользователь может публиковать что-то вроде

[script]alert(1);[/script]

(попробуйте представить, что [] являются <>, очевидно, переполнение стека добавляет текст небезопасным способом!)

, который не сработаетпредупреждение, если вы используете innerHTML, но оно должно дать вам представление о том, почему использование innerHTML может иметь проблемы.более умный пользователь будет публиковать

[img src="invalid_src" onerror="alert(1)"]

, что вызовет оповещение для каждого другого пользователя, который посещает страницу.Теперь у нас есть проблема.Даже более умный пользователь установит отображение: ни один в этом стиле img и заставит публиковать файлы cookie текущего пользователя на междоменном сайте.Поздравляем, все ваши данные для входа в систему теперь доступны в Интернете.

Итак, важно понять, что использование innerHTML не является неправильным, оно идеально, если вы просто используете его для создания шаблонов, используя толькоВаш собственный доверенный код разработчика.Реальный вопрос должен был звучать так: «Как добавить ненадежный пользовательский текст с новыми строками в мой HTML-документ».

Возникает вопрос: какую стратегию мы используем для новых строк?мы используем элементы [br]?[p] s или [div] s?

Вот короткая функция, которая решает проблему:

function insertUntrustedText(domElement, untrustedText, newlineStrategy) {
    domElement.innerHTML = '';
    var lines = untrustedText.replace(/\r/g, '').split('\n');
    var linesLength = lines.length;
    if(newlineStrategy === 'br') {
        for(var i = 0; i < linesLength; i++) {
            domElement.appendChild(document.createTextNode(lines[i]));
            domElement.appendChild(document.createElement('br'));
        }
    }
    else {
        for(var i = 0; i < linesLength; i++) {
            var lineElement = document.createElement(newlineStrategy);
            lineElement.textContent = lines[i];
            domElement.appendChild(lineElement);
        }
    }
}

Вы можете просто бросить это где-нибудь в вашем файле common_functions.js, а затем простозапускать и забывать всякий раз, когда вам нужно добавить какой-либо пользователь / api / etc -> ненадежный текст (т.е. не написанный вашей собственной командой разработчиков) на ваши html-страницы.

пример использования:

insertUntrustedText(document.querySelector('.myTextParent'), 'line1\nline2\r\nline3', 'br');

параметр newlineStrategy принимает только допустимые теги элементов dom, поэтому, если вы хотите [br] новые строки, передайте 'br', если вы хотите каждую строку в элементе [p], передайте 'p' и т. Д.

0 голосов
/ 01 марта 2016

Следующий код работает хорошо (в FireFox, IE и Chrome):

var display_out = "This is line 1" + "<br>" + "This is line 2";

document.getElementById("demo").innerHTML = display_out;
...