jQuery konwertuje podziały wierszy na br (odpowiednik nl2br)

109

Mam jQuery pobrać zawartość textarea i wstawić ją do li.

Chcę, aby wizualnie zachowało podziały linii.

Musi być na to naprawdę prosty sposób ...

gbhall
źródło
Uwaga XSS: Jeśli to robisz, brzmi to tak, jakbyś bezpośrednio miksował dane wejściowe użytkownika i <br/>, co oznacza, że ​​wyświetlasz nowe linie lub <br/s>, a zatem możesz być otwarty na atak XSS , to znaczy, jeśli dane wejściowe pochodzą od innego użytkownika witryny.
user420667

Odpowiedzi:

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
źródło
5
Dziękuję, to działa idealnie. Dziwne, że nie jest to oficjalna funkcja jQuery.
gbhall
4
ponieważ jQuery nie ma na celu zastąpienia natywnej funkcji javascript, takiej jak replace, koncentruje się na łańcuchu selektorów CSS i łatwym dostępie! może w przyszłej wersji ;-)
Luca Filosofi
Niesamowite. Pomogło mi ominąć problem z IE7 nie obsługującym białych znaków: wstępne zawijanie
Kevin Pauli
Czy to wyrażenie regularne nie oznaczałoby, że gdyby linia kończyła się na „>”, nie dodałaby BR? Wiem, że w moim kodzie HTML używam & gt; ale treści generowane przez użytkowników nie działają tak dobrze ...
Dave Stein
@DaveStein no Próbowałem tego zarówno z „>”, jak i „& gt;” i za każdym razem są dodawane podziały wierszy. Myślę, że ten kod funkcji jest w zasadzie doskonały :)
Jake,
91

możesz po prostu zrobić:

textAreaContent=textAreaContent.replace(/\n/g,"<br>");
mck89
źródło
Na zdrowie, ten rodzaj zadziałał, z wyjątkiem tego, że traktowałby wiele znaków końca wiersza jako jeden podział.
gbhall
4
Zaktualizowałem to i teraz używa
wyrażenia regularnego,
Dziękuję Ci. Mamy nadzieję, że ktoś uzna Twoją odpowiedź za przydatną, ale działa również poniższa funkcja. Trochę źle się czuję, że robisz więcej wysiłku, ale funkcja jest bardziej pożądana.
gbhall
jeśli pojawi się błąd „x.replace nie jest funkcją”, użyj x.toString (). zamień
Vörös Amadea
29

Umieść to w swoim kodzie (najlepiej w ogólnej bibliotece funkcji js):

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

Stosowanie:

var myString = "test\ntest2";

myString.nl2br();

tworzenie funkcji prototypu łańcucha pozwala na użycie tego na dowolnym łańcuchu.

jnl
źródło
29

W duchu zmiany renderowania zamiast zmiany zawartości , następujący CSS sprawia, że ​​każda nowa linia zachowuje się jak<br> :

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

Dlaczego dwie zasady: pre-linedotyczy tylko nowych linii (dzięki za wskazówkę @KevinPauli). IE6-7 i inne stare przeglądarki wracają do bardziej ekstremalnej wersji, prektóra również zawiera nowrapi renderuje wiele spacji. Szczegóły na temat tych i innych ustawień ( pre-wrap) na mozilla i css-tricks (dzięki @Sablefoste).

Chociaż generalnie jestem niechętny skłonności SO do odgadywania pytania, zamiast odpowiadania na nie, w tym przypadku zastąpienie nowych linii <br>znacznikami może zwiększyć podatność na atak iniekcyjny z nieumytymi danymi wejściowymi użytkownika. Przekraczasz jasnoczerwoną linię, ilekroć zauważysz, że zmieniasz .text()połączenia, na .html()które sugeruje dosłowne pytanie. (Dzięki @AlexS za podkreślenie tego punktu). Nawet jeśli wykluczysz w danym momencie zagrożenie bezpieczeństwa, przyszłe zmiany mogą je wprowadzić nieświadomie. Zamiast tego ten CSS umożliwia tworzenie twardych podziałów wierszy bez znaczników przy użyciu bezpieczniejszego .text().

Bob Stein
źródło
1
W zależności od przypadku jest to najprostsze rozwiązanie i naprawdę najlepiej odpowiada na pytanie. Możesz również rozważyć dowolne inne white-space:opcje, takie jak pre-wrap. Zobacz css-tricks.com/almanac/properties/w/whitespace
Sablefoste
To naprawdę najlepsza odpowiedź - rozwiązania zastępujące ciągi oznaczałyby potrzebę użycia .html()do ustawienia treści, co z kolei pozwoliłoby użytkownikowi wstawić dowolny kod HTML, chyba że odfiltrujesz go wcześniej.
Alex S
Dobra uwaga na temat .html()niebezpieczeństwa @AlexS, próbował włączyć.
Bob Stein
2

Rozwiązanie

Użyj tego kodu

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

Ta funkcja JavaScript rozważa, czy użyć wstawiania czy zamiany do obsługi zamiany.

(Wstaw lub zamień znaki końca wiersza 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);
}

Demo - JSFiddle

Funkcje JavaScript nl2br i br2nl

Nick Tsai
źródło
1

Napisałem do tego małe rozszerzenie 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);
};
Andreas Otto
źródło
0

poprawić zaakceptowaną odpowiedź @Luca Filosofi,

jeśli to konieczne, zmiana początkowej klauzuli tego wyrażenia regularnego na /([^>[\s]?\r\n]?)będzie również uwzględniać przypadki, w których nowa linia pojawia się po tagu ORAZ pewną białą spację, zamiast tylko tagu, po którym bezpośrednio następuje nowa linia

phlare
źródło
0

Innym sposobem wstawiania tekstu z obszaru tekstowego do DOM z zachowaniem podziałów wierszy jest użycie właściwości Node.innerText, która reprezentuje wyrenderowaną zawartość tekstową węzła i jego potomków.

Jako metoda pobierająca aproksymuje tekst, który użytkownik uzyskałby, gdyby podświetlił zawartość elementu kursorem, a następnie skopiował do schowka.

Obiekt stał się standardem w 2016 roku i jest dobrze obsługiwany przez nowoczesne przeglądarki. Can I Use : 97% globalnego zasięgu, kiedy opublikowałem tę odpowiedź.

Volo
źródło