jQuery конвертувати перерви рядка в br (еквівалент nl2br)


109

Я маю jQuery взяти деякий текстовий вміст і вставити його в лі.

Я хочу, щоб це візуально зберігало розриви рядків.

Має бути дійсно простий спосіб зробити це ...


Примітка XSS: Якщо ви це робите, це здається, що ви безпосередньо змішуєте дані користувача та <br/>, що означає, що ви або відображаєте нові рядки або <br/s>, і, отже, ви можете відкрити атаку XSS , тобто якщо ваша інформація надходить від будь-якого іншого користувача на сайті.
user420667

Відповіді:


163

демо: 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, як заміна, він орієнтований на ланцюг вибору 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 (). Замінити
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-трюки (спасибі @Sablefoste).

Хоча я, як правило, проти прихильності SO для другого відгадування питання, а не відповіді на нього, у цьому випадку заміна нових рядків <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, намагався включити.
Боб Штейн


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.