jQuery конвертирует разрывы строк в br (эквивалент nl2br)


110

У меня jQuery берет содержимое текстового поля и вставляет его в li.

Я хочу, чтобы он визуально сохранял разрывы строк.

Должен быть действительно простой способ сделать это ...


Примечание XSS: если вы это делаете, похоже, что вы напрямую смешиваете ввод пользователя и <br/>, что означает, что вы либо отображаете символы новой строки, либо <br/s>, и, следовательно, можете быть уязвимы для атаки XSS , то есть если ваш ввод поступает от любого другого пользователя на сайте.
user420667

Ответы:


165

демонстрация: http://so.devilmaycode.it/jquery-convert-line-breaks-to-br-nl2br-equivalent

function nl2br (str, is_xhtml) {   
    var breakTag = (is_xhtml || typeof is_xhtml === 'undefined') ? '<br />' : '<br>';    
    return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1'+ breakTag +'$2');
}

5
Спасибо, это отлично работает. Странно, что это не официальная функция jQuery.
gbhall

4
Потому что jQuery не предназначен для замены встроенной функции javascript, такой как replace, он ориентирован на цепочку селекторов CSS и легкий доступ! возможно, в будущей версии ;-)
Лука Философи

Потрясающие. Помогли мне решить проблему с IE7, не поддерживающим пробелы: предварительная упаковка
Кевин Паули

Разве это регулярное выражение не означало бы, что если строка заканчивается на ">", то BR не добавляется? Я знаю, что в своем HTML я использую & gt; но пользовательский контент не так хорошо работает с этим ...
Дэйв Стейн

@DaveStein нет, я пробовал это с '>' и '& gt;' и оба раза добавляются разрывы строк. Я думаю, что этот код функции в основном идеален :)
Джейк

91

вы можете просто сделать:

textAreaContent=textAreaContent.replace(/\n/g,"<br>");

Ура, это сработало, за исключением того, что несколько разрывов строки будут рассматриваться как разрывы одной строки.
gbhall

4
Я обновил его, и теперь он использует регулярное выражение, поэтому, если вы хотите обрабатывать несколько разрывов строк как один br, измените регулярное выражение с помощью: / \ n + / g
mck89

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

если вы получаете сообщение об ошибке «x.replace не является функцией», используйте x.toString (). replace
Vörös

29

Поместите это в свой код (желательно в общую библиотеку функций js):

String.prototype.nl2br = function()
{
    return this.replace(/\n/g, "<br />");
}

Использование:

var myString = "test\ntest2";

myString.nl2br();

создание функции прототипа строки позволяет использовать ее в любой строке.


29

В духе изменения рендеринга вместо изменения содержимого следующий CSS заставляет каждую новую строку вести себя как<br> :

white-space: pre;
white-space: pre-line;

Почему два правила: pre-lineвлияет только на символы новой строки (спасибо за подсказку, @KevinPauli). IE6-7 и другие старые браузеры возвращаются к более экстремальным, preкоторые также включают nowrapи отображают несколько пробелов. Подробности об этих и других настройках ( pre-wrap) см. В mozilla и css-tricks (спасибо @Sablefoste).

Хотя я, как правило, не склонен угадывать вопрос, а не отвечать на него, в этом случае замена новой строки <br>разметкой может повысить уязвимость к атакам путем инъекции с немытым вводом пользователя. Вы пересекаете ярко-красную линию всякий раз, когда обнаруживаете, что меняете .text()вызовы, .html()которые, как следует из буквального вопроса, должны быть выполнены. (Спасибо @AlexS за то, что подчеркнули этот момент.) Даже если вы исключаете угрозу безопасности в то время, будущие изменения могут непреднамеренно ввести ее. Вместо этого этот CSS позволяет получить жесткие разрывы строк без разметки, используя более безопасный .text().


1
В зависимости от случая, это самое простое решение, которое действительно лучше всего отвечает на вопрос. Вы также можете рассмотреть любые другие white-space:варианты, например pre-wrap. См. Css-tricks.com/almanac/properties/w/whitespace
Sablefoste,

Это действительно лучший ответ - решения для замены строк означают необходимость использования .html()для установки содержимого, что, в свою очередь, позволит пользователю вставлять произвольный HTML-код, если вы не отфильтруете его заранее.
Alex S

Хороший момент об .html()опасности @AlexS, попытался включить.
Bob Stein


1

Эта функция JavaScript определяет, использовать ли вставку или замену для обработки свопа.

(Вставьте или замените разрывы строк HTML)

/**
 * This function is same as PHP's nl2br() with default parameters.
 *
 * @param {string} str Input text
 * @param {boolean} replaceMode Use replace instead of insert
 * @param {boolean} isXhtml Use XHTML 
 * @return {string} Filtered text
 */
function nl2br (str, replaceMode, isXhtml) {

  var breakTag = (isXhtml) ? '<br />' : '<br>';
  var replaceStr = (replaceMode) ? '$1'+ breakTag : '$1'+ breakTag +'$2';
  return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, replaceStr);
}

Демо - JSFiddle

Функции JavaScript nl2br и br2nl


1

Я написал для этого небольшое расширение jQuery:

$.fn.nl2brText = function (sText) {
    var bReturnValue = 'undefined' == typeof sText;
    if(bReturnValue) {
        sText = $('<pre>').html(this.html().replace(/<br[^>]*>/i, '\n')).text();
    }
    var aElms = [];
    sText.split(/\r\n|\r|\n/).forEach(function(sSubstring) {
        if(aElms.length) {
            aElms.push(document.createElement('br'));
        }
        aElms.push(document.createTextNode(sSubstring));
    });
    var $aElms = $(aElms);
    if(bReturnValue) {
        return $aElms;
    }
    return this.empty().append($aElms);
};

0

чтобы улучшить принятый ответ @Luca Filosofi,

при необходимости изменение начального предложения этого регулярного выражения на « /([^>[\s]?\r\n]?)будет» также приведет к учету случаев, когда новая строка идет после тега И некоторого пробела, а не просто тега, сразу за которым следует новая строка


0

Другой способ вставить текст из текстового поля в DOM, сохраняя разрывы строк, - это использовать свойство Node.innerText, которое представляет отображаемое текстовое содержимое узла и его потомков.

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

Свойство стало стандартом в 2016 году и хорошо поддерживается современными браузерами. Могу ли я использовать : 97% глобальное покрытие, когда я опубликовал этот ответ.

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