jQuery konvertiert Zeilenumbrüche in br (nl2br-Äquivalent)

109

Ich lasse jQuery Textinhaltsinhalte in ein Li einfügen.

Ich möchte, dass die Zeilenumbrüche visuell beibehalten werden.

Es muss einen wirklich einfachen Weg geben, dies zu tun ...

gbhall
quelle
XSS-Hinweis: Wenn Sie dies tun, scheint es, als würden Sie Benutzereingaben und <br/> direkt mischen. Dies bedeutet, dass Sie entweder Zeilenumbrüche oder <br/s> anzeigen und daher möglicherweise für XSS-Angriffe offen sind Dies ist der Fall, wenn Ihre Eingabe von einem anderen Benutzer auf der Site stammt.
user420667

Antworten:

163

Demo: 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');
}
Luca Filosofi
quelle
5
Danke, das funktioniert perfekt. Seltsam, dass dies keine offizielle Funktion von jQuery ist.
Gbhall
4
Da jQuery nicht die native Javascript-Funktion wie "Ersetzen" ersetzen soll, konzentriert es sich auf die Verkettung von CSS-Selektoren und den einfachen Zugriff! vielleicht in zukünftiger Version ;-)
Luca Filosofi
Genial. Hat mir geholfen, das Problem mit IE7 zu überwinden, das keinen Leerraum unterstützt: Pre-Wrap
Kevin Pauli
Würde diese Regex nicht bedeuten, dass eine Zeile, die mit ">" endet, den BR nicht hinzufügen würde? Ich weiß, dass ich in meinem HTML-Code & gt; Aber benutzergenerierte Inhalte funktionieren damit nicht so gut ...
Dave Stein
@ DaveStein nein, ich habe dies sowohl mit '>' als auch mit '& gt;' versucht. und beide Male werden die Zeilenumbrüche hinzugefügt. Ich denke, dieser Funktionscode ist im Grunde perfekt :)
Jake
90

Sie können einfach tun:

textAreaContent=textAreaContent.replace(/\n/g,"<br>");
mck89
quelle
Prost, diese Art hat funktioniert, außer dass mehrere Zeilenumbrüche als einzelne Zeilenumbrüche behandelt werden.
Gbhall
4
Ich habe es aktualisiert und jetzt wird ein regulärer Ausdruck verwendet. Wenn Sie also mehrere Zeilenumbrüche als ein einziges Zeichen behandeln möchten, ändern Sie den regulären Ausdruck mit: / \ n + / g
mck89
Danke dir. Hoffentlich findet jemand Ihre Antwort hilfreich, aber die folgende Funktion funktioniert auch. Ich fühle mich irgendwie schlecht, dass Sie sich mehr anstrengen, aber eine Funktion ist wünschenswerter.
Gbhall
Wenn Sie die Fehlermeldung "x.replace ist keine Funktion" erhalten, verwenden Sie x.toString (). replace
Vörös Amadea
29

Fügen Sie dies in Ihren Code ein (vorzugsweise in eine allgemeine js-Funktionsbibliothek):

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

Verwendung:

var myString = "test\ntest2";

myString.nl2br();

Durch das Erstellen einer String-Prototyp-Funktion können Sie diese für jeden String verwenden.

jnl
quelle
29

Um das Rendering zu ändern , anstatt den Inhalt zu ändern, verhält sich jede neue Zeile mit<br> dem folgenden CSS wie folgt :

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

Warum zwei Regeln: pre-lineBetrifft nur Zeilenumbrüche (danke für den Hinweis, @KevinPauli). IE6-7 und andere alte Browser greifen auf das Extremere zurück, predas auch nowrapmehrere Leerzeichen enthält und rendert. Details zu diesen und anderen Einstellungen ( pre-wrap) bei Mozilla und CSS-Tricks (danke @Sablefoste).

Während ich im Allgemeinen der SO-Vorliebe abgeneigt bin, die Frage zu erraten, anstatt sie zu beantworten, kann in diesem Fall das Ersetzen von Zeilenumbrüchen durch <br>Markup die Anfälligkeit für Injektionsangriffe durch ungewaschene Benutzereingaben erhöhen . Sie überschreiten eine leuchtend rote Linie, wenn Sie .text()Anrufe ändern , für .html()die die wörtliche Frage impliziert, dass dies getan werden müsste. (Vielen Dank an @AlexS, dass Sie diesen Punkt hervorgehoben haben.) Selbst wenn Sie zu diesem Zeitpunkt ein Sicherheitsrisiko ausschließen, können zukünftige Änderungen es unabsichtlich einführen. Stattdessen können Sie mit diesem CSS mit dem Safer harte Zeilenumbrüche ohne Markup erzielen .text().

Bob Stein
quelle
1
Je nach Fall ist dies die einfachste Lösung und beantwortet die Frage am besten. Sie können auch eine der anderen white-space:Optionen in Betracht ziehen , z pre-wrap. Siehe css-tricks.com/almanac/properties/w/whitespace
Sablefoste
Dies ist wirklich die beste Antwort - String-Ersetzungslösungen würden die Notwendigkeit bedeuten .html(), den Inhalt festzulegen, was es dem Benutzer wiederum ermöglichen würde, beliebigen HTML-Code einzufügen, sofern Sie dies nicht im Voraus herausfiltern.
Alex S
Guter Punkt über .html()Gefahr @AlexS, versucht zu integrieren.
Bob Stein
2

Lösung

Verwenden Sie diesen Code

jQuery.nl2br = function(varTest){
  return varTest.replace(/(\r\n|\n\r|\r|\n)/g, "<br>");
};
Ata ul Mustafa
quelle
1

Diese JavaScript-Funktion berücksichtigt, ob für den Swap Einfügen oder Ersetzen verwendet werden soll.

(HTML-Zeilenumbrüche einfügen oder ersetzen)

/**
 * 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);
}

Demo - JSFiddle

JavaScript nl2br & br2nl Funktionen

Nick Tsai
quelle
1

Ich habe dafür eine kleine jQuery-Erweiterung geschrieben:

$.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);
};
Andreas Otto
quelle
0

um die akzeptierte Antwort von @Luca Filosofi zu verbessern,

Wenn Sie die /([^>[\s]?\r\n]?)Anfangsklausel dieses regulären Ausdrucks bei Bedarf ändern, werden auch die Fälle berücksichtigt, in denen die neue Zeile nach einem Tag UND einem Leerzeichen steht, anstatt nur nach einem Tag, unmittelbar gefolgt von einer neuen Zeile

phlare
quelle
0

Eine andere Möglichkeit, Text aus einem Textbereich in das DOM einzufügen, wobei die Zeilenumbrüche beibehalten werden , ist die Verwendung der Node.innerText- Eigenschaft, die den gerenderten Textinhalt eines Knotens und seiner Nachkommen darstellt.

Als Getter nähert es sich dem Text an, den der Benutzer erhalten würde, wenn er den Inhalt des Elements mit dem Cursor hervorheben und dann in die Zwischenablage kopieren würde.

Die Eigenschaft wurde 2016 zum Standard und wird von modernen Browsern gut unterstützt. Kann ich verwenden : 97% globale Abdeckung, als ich diese Antwort gepostet habe.

Volo
quelle