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.