Otrzymuję wartość w obszarze tekstowym, gdy użytkownik trafia do przesyłania. Następnie biorę tę wartość i umieszczam w innym miejscu na stronie. Jednak kiedy to robię, traci znaki nowej linii, co sprawia, że wynik jest dość brzydki.
Oto obszar tekstowy, do którego mam dostęp:
<textarea id="post-text" class="form-control" rows="3" placeholder="What's up?" required></textarea>
Oto kod JavaScript umożliwiający dostęp do postu i jego transkrypcję.
var post = document.createElement('p');
var postText = document.getElementById('post-text').value;
post.append(postText);
var card = document.createElement('div');
card.append(post);
var cardStack = document.getElementById('#card-stack');
cardStack.prepend(card);
Gdy dane wejściowe są takie jak:
Harmonogram grupowy:
Praktyka wtorkowa na 5. piętrze (20:00 - 23:00)
Ćwiczenia czwartkowe @ 5 piętro (20:00 - 23:00)
Niedzielne treningi @ (21:00 - 12:00)
Wynik to:
Harmonogram grupowy: Praktyki wtorkowe na 5. piętrze (20:00 - 23:00) Ćwiczenia w czwartki na piątym piętrze (20:00 - 23:00) Ćwiczenia w niedzielę @ (21:00 - 12:00)
Czy jest więc sposób na zachowanie łamania linii?
źródło
getElementById
funkcja od drugiego do ostatniego wiersza? Zakładam, że zdefiniowałeś to gdzie indziej lub zapomniałeśdocument
.Odpowiedzi:
Najłatwiejszym rozwiązaniem jest po prostu stylizowanie elementu, do którego wstawiany jest tekst, za pomocą następującej właściwości CSS:
white-space: pre-wrap;
Ta właściwość powoduje, że białe znaki i znaki nowej linii w pasujących elementach są traktowane w taki sam sposób, jak wewnątrz
<textarea>
. Oznacza to, że kolejne białe spacje nie są zwijane, a wiersze są przerywane w jawnych nowych wierszach (ale są również automatycznie zawijane, jeśli przekraczają szerokość elementu).Biorąc pod uwagę, że kilka z opublikowanych tutaj odpowiedzi było podatnych na wstrzyknięcie HTML (np. Ponieważ przypisują one niezmienione dane wejściowe użytkownika do
innerHTML
) lub w inny sposób błędne, pozwól mi podać przykład, jak to zrobić bezpiecznie i poprawnie, w oparciu o oryginalny kod:Pokaż fragment kodu
document.getElementById('post-button').addEventListener('click', function () { var post = document.createElement('p'); var postText = document.getElementById('post-text').value; post.append(postText); var card = document.createElement('div'); card.append(post); var cardStack = document.getElementById('card-stack'); cardStack.prepend(card); });
#card-stack p { background: #ddd; white-space: pre-wrap; /* <-- THIS PRESERVES THE LINE BREAKS */ } textarea { width: 100%; }
<textarea id="post-text" class="form-control" rows="8" placeholder="What's up?" required>Group Schedule: Tuesday practice @ 5th floor (8pm - 11 pm) Thursday practice @ 5th floor (8pm - 11 pm) Sunday practice @ (9pm - 12 am)</textarea><br> <input type="button" id="post-button" value="Post!"> <div id="card-stack"></div>
Zwróć uwagę, że podobnie jak w oryginalnym kodzie powyższy fragment używa
append()
iprepend()
. W chwili pisania tego tekstu funkcje te są nadal uważane za eksperymentalne i nie są w pełni obsługiwane przez wszystkie przeglądarki. Jeśli chcesz być bezpieczny i zachować zgodność ze starszymi przeglądarkami, możesz łatwo je zastąpić w następujący sposób:element.append(otherElement)
można zastąpićelement.appendChild(otherElement)
;element.prepend(otherElement)
można zastąpićelement.insertBefore(otherElement, element.firstChild)
;element.append(stringOfText)
można zastąpićelement.appendChild(document.createTextNode(stringOfText))
;element.prepend(stringOfText)
można zastąpićelement.insertBefore(document.createTextNode(stringOfText), element.firstChild)
;element
jest pusty, obaelement.append(stringOfText)
ielement.prepend(stringOfText)
można je po prostu zastąpićelement.textContent = stringOfText
.Oto ten sam fragment co powyżej, ale bez użycia
append()
lubprepend()
:Pokaż fragment kodu
document.getElementById('post-button').addEventListener('click', function () { var post = document.createElement('p'); var postText = document.getElementById('post-text').value; post.textContent = postText; var card = document.createElement('div'); card.appendChild(post); var cardStack = document.getElementById('card-stack'); cardStack.insertBefore(card, cardStack.firstChild); });
#card-stack p { background: #ddd; white-space: pre-wrap; /* <-- THIS PRESERVES THE LINE BREAKS */ } textarea { width: 100%; }
<textarea id="post-text" class="form-control" rows="8" placeholder="What's up?" required>Group Schedule: Tuesday practice @ 5th floor (8pm - 11 pm) Thursday practice @ 5th floor (8pm - 11 pm) Sunday practice @ (9pm - 12 am)</textarea><br> <input type="button" id="post-button" value="Post!"> <div id="card-stack"></div>
Ps. Jeśli naprawdę chcesz to zrobić bez używania
white-space
właściwości CSS , alternatywnym rozwiązaniem byłoby jawne zastąpienie wszelkich znaków nowego wiersza w tekście<br>
znacznikami HTML. Najtrudniejsze jest to, że aby uniknąć wprowadzania subtelnych błędów i potencjalnych luk w zabezpieczeniach, musisz najpierw usunąć wszelkie metaznaki HTML (co najmniej&
i<
) w tekście, zanim wykonasz tę zamianę.Prawdopodobnie najprostszym i najbezpieczniejszym sposobem na zrobienie tego jest pozwolenie przeglądarce na obsługę kodu ucieczki HTML za Ciebie, na przykład:
var post = document.createElement('p'); post.textContent = postText; post.innerHTML = post.innerHTML.replace(/\n/g, '<br>\n');
Pokaż fragment kodu
document.getElementById('post-button').addEventListener('click', function () { var post = document.createElement('p'); var postText = document.getElementById('post-text').value; post.textContent = postText; post.innerHTML = post.innerHTML.replace(/\n/g, '<br>\n'); // <-- THIS FIXES THE LINE BREAKS var card = document.createElement('div'); card.appendChild(post); var cardStack = document.getElementById('card-stack'); cardStack.insertBefore(card, cardStack.firstChild); });
#card-stack p { background: #ddd; } textarea { width: 100%; }
<textarea id="post-text" class="form-control" rows="8" placeholder="What's up?" required>Group Schedule: Tuesday practice @ 5th floor (8pm - 11 pm) Thursday practice @ 5th floor (8pm - 11 pm) Sunday practice @ (9pm - 12 am)</textarea><br> <input type="button" id="post-button" value="Post!"> <div id="card-stack"></div>
Zauważ, że chociaż naprawi to podziały wierszy, nie zapobiegnie zwijaniu kolejnych białych znaków przez mechanizm renderujący HTML. Można to (w pewnym sensie) naśladować, zastępując część białych znaków w tekście nierozdzielającymi spacjami, ale szczerze mówiąc, jest to dość skomplikowane w przypadku czegoś, co można trywialnie rozwiązać za pomocą jednej linii CSS.
źródło
Kontener docelowy powinien mieć
white-space:pre
styl. Wypróbuj poniżej.<script> function copycontent(){ var content = document.getElementById('ta').value; document.getElementById('target').innerText = content; } </script> <textarea id='ta' rows='3'> line 1 line 2 line 3 </textarea> <button id='btn' onclick='copycontent();'> Copy </button> <p id='target' style='white-space:pre'> </p>
źródło
pre-wrap
lubpre-line
byłoby lepiej.pre
zapobiega zawijaniu wierszy, więc bardzo długi wiersz tekstu wymusza przewijanie w poziomie.innerHTML
. W tym przypadku, po prostu zastępującinnerHTML
zetextContent
by go naprawić.innerText
itextContent
. Tylko ustawienietextContent
nie będzie działać w IE (w żadnej wersji), ainnerText
samo ustawienie może nie działać w przyszłości w przeglądarce Chrome i nie będzie działać w przeglądarce Firefox.textContent
od wersji 9.innerText
jeśli potrzebujesz IE8.function get() { var arrayOfRows = document.getElementById("ta").value.split("\n"); var docfrag = document.createDocumentFragment(); var p = document.getElementById("result"); while (p.firstChild) { p.removeChild(p.firstChild); } arrayOfRows.forEach(function(row, index, array) { var span = document.createElement("span"); span.textContent = row; docfrag.appendChild(span); if(index < array.length - 1) { docfrag.appendChild(document.createElement("br")); } }); p.appendChild(docfrag); }
<textarea id="ta" rows=3></textarea><br> <button onclick="get()">get</button> <p id="result"></p>
Możesz podzielić wiersze textarea na tablicę:
var arrayOfRows = postText.value.split("\n");
Następnie użyj go do wygenerowania być może więcej tagów p ...
źródło
textarea.value
) do właściwości, która oczekuje HTML (innerHTML
). Jest to błąd typu, który powoduje różne problemy, od uszkodzonego tekstu po luki w zabezpieczeniach. Zamiast używaćinnerHTML
, możesz zrobićappendChild
zdocument.createTextNode(text)
idocument.createElement('br')
.document.createDocumentFragment
.Oto pomysł, ponieważ możesz mieć wiele znaków nowej linii w polu tekstowym:
var text=document.getElementById('post-text').value.split('\n'); var html = text.join('<br />');
Ta wartość HTML zachowa znak nowej linii. Mam nadzieję że to pomoże.
źródło
html
ciąg zostanie kiedykolwiek renderowany jako HTML.&
lub<
. Nawet jeśli bezpieczeństwo nie jest problemem, nadal jest to błąd.Możesz ustawić
width
div za pomocą Javascript i dodać, cowhite-space:pre-wrap
spowodujep tag
przerwanie zawartości textarea na końcu każdej linii.document.querySelector("button").onclick = function gt(){ var card = document.createElement('div'); card.style.width = "160px"; card.style.background = "#eee"; var post = document.createElement('p'); var postText = document.getElementById('post-text').value; post.style.whiteSpace = "pre-wrap"; card.append(post); post.append(postText); document.body.append(card); }
<textarea id="post-text" class="form-control" rows="3" placeholder="What's up?" required> Group Schedule: Tuesday practice @ 5th floor (8pm - 11 pm) Thursday practice @ 5th floor (8pm - 11 pm) Sunday practice @ (9pm - 12 am)</textarea> <br><br> <button>Copy!!</button>
źródło
Przypuszczam, że nie chcesz, aby zawartość textarea była analizowana jako HTML. W takim przypadku możesz po prostu ustawić go jako zwykły tekst, aby przeglądarka nie traktowała go jako HTML i nie usuwała znaków nowej linii. Nie jest wymagane CSS ani przetwarzanie wstępne.
<script> function copycontent(){ var content = document.getElementById('ta').value; document.getElementById('target').innerText = content; } </script> <textarea id='ta' rows='3'> line 1 line 2 line 3 </textarea> <button id='btn' onclick='copycontent();'> Copy </button> <p id='target'></p>
źródło
Podobne pytania są tutaj
wykrywa podziały wierszy w polu tekstowym
wykryj łamanie linii w obszarze tekstowym
Możesz spróbować tego:
var submit = document.getElementById('submit'); submit.addEventListener('click', function(){ var textContent = document.querySelector('textarea').value; document.getElementById('output').innerHTML = textContent.replace(/\n/g, '<br/>'); });
<textarea cols=30 rows=10 >This is some text this is another text Another text again and again</textarea> <input type='submit' id='submit'> <p id='output'></p>
document.querySelector('textarea').value;
otrzyma zawartość tekstową obszaru tekstowego itextContent.replace(/\n/g, '<br/>')
znajdzie w treści cały znak nowej linii w kodzie źródłowym/\n/g
i zastąpi go znakiem końca wiersza html<br/>
.Inną opcją jest użycie
<pre>
tagu html . Zobacz demo poniżejvar submit = document.getElementById('submit'); submit.addEventListener('click', function(){ var content = '<pre>'; var textContent = document.querySelector('textarea').value; content += textContent; content += '</pre>'; document.getElementById('output').innerHTML = content; });
<textarea cols=30 rows=10>This is some text this is another text Another text again and again </textarea> <input type='submit' id='submit'> <div id='output'> </div>
źródło
textContent.replace()
do czegokolwiek). Twój drugi przykład jest podatny na ten sam błąd wstrzyknięcia HTML, co kilka innych odpowiedzi, ponieważ przypisujesz dane wejściowe użytkownika bez zmiany znaczeniainnerHTML
(a pierwszy przykład byłby równie podatny, gdybyś spróbował aby faktycznie zrobić cokolwiek pożytecznego z wynikiemreplace()
wywołania).