jQuery text () i znaki nowej linii

114

Chcę móc powiedzieć

$(someElem).text('this\n has\n newlines);

i renderuje się z nowymi wierszami w przeglądarce. Jedynym rozwiązaniem, jakie znalazłem, jest ustawienie właściwości css „white-space” na „pre” w someElem. To prawie działa, ale mam irytująco duże wypełnienie między tekstem a górną częścią jakiegośElem, nawet jeśli ustawię dopełnienie na 0. Czy jest sposób, aby się tego pozbyć?

Joe Armstrong
źródło
2
zawijanie go w <pre>znaczniki (i używanie .html () zamiast .text ()) jest najłatwiejszym i najlepszym sposobem na zachowanie podziałów wierszy z pliku tekstowego lub ze zwykłego tekstu (sugeruje to poniższa odpowiedź Karima). JEDNAK: Nowszą alternatywą jest użycie white-space: pre-wrap;zgodnie z sugestią w odpowiedzi
Cleonga
1
dlaczego nie użyć append()zamiast test()i <br/>zamiast \n? w ten sposób -$(someElem).append("this <br/> has <br/> newlines");
Erfan Ahmed

Odpowiedzi:

132

Jest rok 2015. Poprawną odpowiedzią na to pytanie w tym momencie jest użycie CSS white-space: pre-linelub white-space: pre-wrap. Czysty i elegancki. Najniższa wersja IE obsługująca tę parę to 8.

https://css-tricks.com/almanac/properties/w/whitespace/

PS Dopóki CSS3 nie stanie się powszechny , prawdopodobnie będziesz musiał ręcznie usuwać początkowe i / lub końcowe odstępy.

cleong
źródło
3
To powinna być odpowiedź.
Axel
3
TO jest odpowiedź. Powinien być wyższy. Witamy w 2016 roku.
neoRiley
3
Znalazłem to w 2017 roku: nadal aktualne i nadal odpowiedź na pytanie.
Troy Harris
6
W tym poście jest błąd. Jest rok 2017, a nie 2015. Wszystko inne wygląda dokładnie.
JDB nadal pamięta Monikę z
1
new Date("2016");
Brandito,
60

Jeśli przechowujesz obiekt jQuery w zmiennej, możesz to zrobić:

var obj = $("#example").text('this\n has\n newlines');
obj.html(obj.html().replace(/\n/g,'<br/>'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="example"></p>

Jeśli wolisz, możesz również utworzyć funkcję wykonującą to za pomocą prostego wywołania, tak jak robi to jQuery.text ():

$.fn.multiline = function(text){
    this.text(text);
    this.html(this.html().replace(/\n/g,'<br/>'));
    return this;
}

// Now you can do this:
$("#example").multiline('this\n has\n newlines');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="example"></p>

José Roberto Araújo Júnior
źródło
W drugim wierszu pierwszego fragmentu kodu brakuje nawiasu zamykającego.
Mahmoud Fayez
1
to właściwie odpowiada na pytanie PO
Tommy
Najlepszy, zadziałał jak urok i rozwiązał problem.
ZEESHAN ARSHAD
37

Oto czego używam:

function htmlForTextWithEmbeddedNewlines(text) {
    var htmls = [];
    var lines = text.split(/\n/);
    // The temporary <div/> is to perform HTML entity encoding reliably.
    //
    // document.createElement() is *much* faster than jQuery('<div></div>')
    // http://stackoverflow.com/questions/268490/
    //
    // You don't need jQuery but then you need to struggle with browser
    // differences in innerText/textContent yourself
    var tmpDiv = jQuery(document.createElement('div'));
    for (var i = 0 ; i < lines.length ; i++) {
        htmls.push(tmpDiv.text(lines[i]).html());
    }
    return htmls.join("<br>");
}
jQuery('#div').html(htmlForTextWithEmbeddedNewlines("hello\nworld"));
Peter V. Mørch
źródło
1
W rzeczywistości jest lepszy od sugestii Marka, ponieważ nie jest zagrożony atakiem XSS.
Andrew B.
Myślę, że mógłbyś utworzyć div (tj: document.createElement ('div')) z funkcji i po prostu użyć go do wszystkich wywołań, prawda?
Fabio Zadrozny
@FabioZadrozny: Tak, masz rację! Odpowiednio zredagowałem (prawie) odpowiedź. Element div jest tworzony wewnątrz funkcji, ale teraz poza pętlą. Może być całkowicie poza funkcją, ale wtedy staje się uciążliwy w użyciu.
Peter V. Mørch
1
Uważam, że odpowiedź @ cleong jest najlepszym rozwiązaniem tego
problemu
Jeśli masz wyraźne znaki nowej linii w swoim tekście, możesz podzielić go za pomocą text.split(/\\n/), a nawet text.split(/\\\\n|\\n|\n/). Napotkałem to podczas przekazywania tekstu w formacie JSON z interfejsem API, który osadził literalne \nznaki kontrolne w ciągach.
D. Visser,
20

Alternatywnie spróbuj użyć, .htmla następnie zawiń w <pre>tagi:

$(someElem).html('this\n has\n newlines').wrap('<pre />');
karim79
źródło
13

Można użyć htmlzamiast texti zastąpić każde wystąpienie \nz <br>. Będziesz jednak musiał poprawnie uciec przed tekstem.

x = x.replace(/&/g, '&amp;')
     .replace(/>/g, '&gt;')
     .replace(/</g, '&lt;')
     .replace(/\n/g, '<br>');
Mark Byers
źródło
@Matthew Flaschen: Dzięki, naprawiono.
Mark Byers
7
Niektóre osoby czytające tę odpowiedź prawdopodobnie nie będą wiedzieć, jakie to niebezpieczne. Nigdy nie używaj tego rozwiązania z tekstem dostarczonym przez użytkownika. Preferowane jest rozwiązanie Petera Mørcha.
Andrew B.
1
@kulebyashik Rozwiązanie Piotra użyj, textpodczas gdy ta odpowiedź jest używana htmlbezpośrednio.
John Xiao,
1

Sugerowałbym pracę someElembezpośrednio z elementem, ponieważ zastąpienie go .html()zastąpiłoby również inne znaczniki HTML w ciągu.

Oto moja funkcja:

function nl2br(el) {
  var lines = $(el).text().split(/\n/);
  $(el).empty();
  for (var i = 0 ; i < lines.length ; i++) {
    if (i > 0) $(el).append('<br>');
    $(el).append(document.createTextNode(lines[i]));
  }
  return el;
}

Nazwij to:

someElem = nl2br(someElem);
JochenJung
źródło
1
UWAGA DLA CZYTELNIKA: Ta odpowiedź jest szczególnie przydatna, jeśli planujesz opracować dodatek do przeglądarki Firefox. innerHTML lub (.html () jeśli używasz jQuery) jest mile widziana przez W3C i Mozillę, a powyższy kod jest bardzo pomocny w wyczyszczeniu procesu recenzji. Aby uzyskać więcej informacji, zobacz Zagadnienia dotyczące bezpieczeństwa @ developer.mozilla.org/en-US/docs/Web/API/Element.innerHTML
Delicia Brummitt
1

Spróbuj tego:

$(someElem).html('this<br> has<br> newlines);
daCoda
źródło
0

Korzystanie z właściwości odstępu CSS jest prawdopodobnie najlepszym rozwiązaniem. Użyj Firebug lub Chrome Developer Tools, aby zidentyfikować źródło dodatkowego wypełnienia, które widziałeś.

Andrew B.
źródło