텍스트 영역에서 텍스트를 가져올 때 줄 바꿈을 어떻게 유지합니까?


96

사용자가 제출을 누르면 텍스트 영역에 값이 표시됩니다. 그런 다음이 값을 페이지의 다른 곳에 배치합니다. 그러나 이렇게하면 개행 문자가 없어 출력이 매우 추악합니다.

내가 액세스하는 텍스트 영역은 다음과 같습니다.

<textarea id="post-text" class="form-control" rows="3" placeholder="What's up?" required></textarea>

다음은 게시물에 액세스하고이를 전사하는 JavaScript 코드입니다.

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);

입력이 다음과 같은 경우 :

그룹 일정 :

화요일 연습 @ 5 층 (오후 8시-오후 11시)

목요일 연습 @ 5 층 (오후 8시-오후 11시)

일요일 연습 @ (오후 9시-오전 12시)

출력은 다음과 같습니다.

그룹 일정 : 화요일 연습 @ 5 층 (오후 8시-오후 11시) 목요일 연습 @ 5 층 (오후 8시-오후 11시) 일요일 연습 @ (오후 9시-오전 12시)

그렇다면 줄 바꿈을 유지하는 방법이 있습니까?


1
당신이 당신을 도울 수있는 jQuery를 사용할 수있는 경우 : 복사부터 텍스트 영역 - 투 - 사업부 - 보존 - 바꿈을 양자 택일이 힘의 도움을 보존-바꿈 --에서 텍스트 영역에 입력
케빈 Kloet

1
줄 바꿈은 실제로 유지되며 대상 요소는 텍스트를 표시하는 동안 무시하도록 설정되어 있지만 검사하면 여기에있는 것을 볼 수 있습니다. Stefano의 대답은 단순히 목표를 더 이상 무시하지 않도록 설정합니다. 아마도 가장 좋은 방법 일 것입니다.
스펙트럼

2
짤막하게해서 미안하지만 getElementById두 번째에서 마지막 줄 의 함수 는 어디에 있습니까? 나는 당신이 그것을 다른 곳에서 정의했거나 document.
trysis 2016

답변:


175

가장 쉬운 해결책은 다음 CSS 속성을 사용하여 텍스트를 삽입 할 요소의 스타일을 지정하는 것입니다.

white-space: pre-wrap;

이 속성 은 일치하는 요소 내의 공백과 줄 바꿈이 <textarea>. 즉, 연속 된 공백은 축소되지 않고 줄은 명시적인 줄 바꿈에서 끊어집니다 (하지만 요소의 너비를 초과하면 자동으로 줄 바꿈 됨).

지금까지 여기에 게시 된 몇 가지 답변이 HTML 주입 (예 : 이스케이프되지 않은 사용자 입력을에 할당하기 때문에) 에 취약 innerHTML하거나 버그가있는 경우 원본 코드를 기반으로이 작업을 안전하고 올바르게 수행하는 방법에 대한 예제를 제공하겠습니다.


원본 코드와 마찬가지로 위의 스 니펫은 append()prepend(). 이 글을 쓰는 시점에서 이러한 기능은 여전히 ​​실험적인 것으로 간주되며 모든 브라우저에서 완전히 지원되지는 않습니다. 안전하고 이전 브라우저와의 호환성을 유지하려면 다음과 같이 쉽게 대체 할 수 있습니다.

  • element.append(otherElement)로 대체 될 수 있습니다 element.appendChild(otherElement).
  • element.prepend(otherElement)로 대체 될 수 있습니다 element.insertBefore(otherElement, element.firstChild).
  • element.append(stringOfText)로 대체 될 수 있습니다 element.appendChild(document.createTextNode(stringOfText)).
  • element.prepend(stringOfText)로 대체 될 수 있습니다 element.insertBefore(document.createTextNode(stringOfText), element.firstChild).
  • 특별한 경우로, 경우는 element비어있는, 모두 element.append(stringOfText)element.prepend(stringOfText)간단하게 교체 할 수 있습니다 element.textContent = stringOfText.

다음은 위와 동일한 스 니펫이지만 append()또는 사용하지 않습니다 prepend().


추신. CSS 속성 사용 하지 않고이 작업을 수행하려는 경우 white-space대체 솔루션은 텍스트의 모든 줄 바꿈 문자를 <br>HTML 태그 로 명시 적으로 바꾸는 것 입니다. 까다로운 부분은 미묘한 버그와 잠재적 인 보안 허점을 방지 하기 위해이 대체를 수행 하기 전에 먼저 텍스트 에서 HTML 메타 문자 (최소 &<)를 이스케이프해야한다는 것 입니다.

아마도 가장 간단하고 안전한 방법은 다음과 같이 브라우저가 HTML 이스케이프를 처리하도록하는 것입니다.

var post = document.createElement('p');
post.textContent = postText;
post.innerHTML = post.innerHTML.replace(/\n/g, '<br>\n');

이렇게하면 줄 바꿈이 수정되지만 HTML 렌더러에 의해 연속 된 공백이 축소되는 것을 방지 할 수는 없습니다. 텍스트의 일부 공백을 끊기지 않는 공백으로 대체하여 (일종의) 에뮬레이션 할 수 있지만 솔직히 CSS 한 줄로 사소하게 해결할 수있는 문제는 다소 복잡해집니다.


2
이것이 가장 포괄적 인 대답 인 것 같습니다. 왜 반대 투표입니까? 잘못된 정보가 포함 된 경우 공유하십시오.
Ethan Vander Horn

4
white-space : pre-wrap은 첫 줄에 들여 쓰기가 있었기 때문에 pre-line이 저에게 효과적이었습니다.
dev4life

1
고마워 친구. 당신은 내 일을했다
thatman

그래서 문제는 텍스트 영역에서 공백을 볼 수 있지만 API 끝에서 수신하고 이메일로 전송되면 공백을 보존하지 않습니다.
Apurva Kunkulol

@ApurvaKunkulol : 서버 측 코드에 문제가있는 것 같습니다. 그것에 대해 새로운 질문을 할 수 있지만 문제를 보여주는 재현 가능한 최소한의 예 를 제공해야합니다 .
Ilmari Karonen

23

대상 컨테이너에는 white-space:pre스타일 이 있어야합니다 . 아래에서 시도해보십시오.

<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>


10
pre-wrap아니면 pre-line더 좋을 것입니다. pre줄 바꿈을 방지하므로 매우 긴 텍스트 줄은 가로 스크롤바를 강제로 적용합니다.
Salman A

10
이 코드는 이스케이프되지 않은 사용자 입력을에 할당하므로 HTML 삽입에 취약합니다 innerHTML. 이 경우, 단순히 교체 innerHTMLtextContent문제를 해결할 것입니다.
Ilmari Karonen 2016

1
@IlmariKaronen 그게 깨질거야. innerText 을 설정해야합니다 textContent. 설정 textContent만은 IE (모든 버전) innerText에서 작동하지 않으며 설정 만은 향후 Chrome에서 작동하지 않을 수 있으며 Firefox에서는 작동하지 않을 수 있습니다.
Ismael Miguel

3
@IsmaelMiguel : 이상합니다-IE 11에서 게시하고 있으며 여기에서 잘 작동합니다. 분명히 IE는 지원하고 textContent버전 9 이후
Ilmari 카로 넨에게

2
@IlmariKaronen 이상하네요 ... 저도 몰랐어요. 그러나 innerTextIE8이 필요한 경우 포함하는 것이 좋습니다 .
Ismael Miguel

7

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>

textarea 행을 배열로 분할 할 수 있습니다.

var arrayOfRows = postText.value.split("\n");

그런 다음 더 많은 p 태그를 생성하는 데 사용합니다.


3
@IlmariKaronen이 말한 것 : textarea.valueHTML ( innerHTML)이 필요한 속성에 일반 텍스트 ( )를 할당하기 때문에이 코드는 올바르지 않습니다 . 이것은 깨진 텍스트에서 보안 허점에 이르기까지 다양한 문제를 일으키는 유형 오류입니다. 대신에 사용하는 innerHTML, 당신은 할 수 appendChilddocument.createTextNode(text)document.createElement('br').
Kos

1
이를보다 효율적으로 만드는 좋은 방법은 document.createDocumentFragment.
Kos

1
@IlmariKaronen, Kos, 이것은 보안이나 효율성에 대한 질문이 아닙니다. 그래도 최적화했습니다.
kolodi

3
@misher : OP는 줄 바꿈을 유지 하고 HTML 삽입을 허용 하는 방법이 아니라 줄 바꿈을 유지하는 방법을 요청했습니다 . UI 버그 수정을 위해 도움을 요청할 때 무료 보안 허점을 얻는 것은 햄버거를 요청할 때 패티에 무료 압정을 얻는 것과 같습니다. 어쨌든, "최적화 된"코드가 더 이상 취약하지 않은 것 같기 때문에 내 반대 투표를 제거했습니다.
Ilmari Karonen 2016

3

다음은 텍스트 상자에 여러 줄 바꿈이있을 수있는 아이디어입니다.

 var text=document.getElementById('post-text').value.split('\n');
 var html = text.join('<br />');

이 HTML 값은 개행을 유지합니다. 도움이 되었기를 바랍니다.


1
또한 이스케이프 처리되지 않은 사용자 입력과 HTML 태그가 혼합되어 결과 html문자열이 실제로 HTML로 렌더링되는 경우 HTML 주입 취약점이 발생 합니다.
Ilmari Karonen 2016

@IlmariKaronen-누군가가 자신을 공격 할 수 있다는 우려가 있습니까? OP는 어떤 유형의 데이터베이스도 언급하지 않습니다. 한 사용자 입력이 다른 사용자에게 어떤 영향을 미칠까요? 아마도 이것은 OP의 눈만을위한 것이고 위생에 대한 필요성이 전혀없는 것일 수도 있습니다 (아무것도 필요하다면).
Jesse

1
@Jesse : 일반적으로 사용자 입력이 신뢰할 수있는 출처에서 나온 것인지 확인하기는 어렵습니다. 공격자가 텍스트 영역에 직접 텍스트를 주입 할 수있는 방법이 없더라도 사회 공학을 통해 순진한 사용자가 취약한 입력 필드에 무언가를 복사하여 붙여 넣도록 설득하여 확산 된 소셜 미디어 바이러스가 많이 있습니다. 게다가, 입력이 정말 100 % 신뢰할 수있는 경우에도,이 코드는 여전히 같은 HTML 메타 문자가 포함 된 텍스트 미치게 &하거나 <. 보안이 문제가되지 않더라도 여전히 버그입니다.
Ilmari Karonen 2016

@IlmariKaronen-공격에 대해 전혀 걱정하지 않지만이 정보에 감사드립니다!
Ethan Vander Horn

3

widthJavascript를 사용하여 div를 설정 하고에 추가 white-space:pre-wrap할 수 있습니다 p tag. 이렇게하면 각 줄의 끝에서 텍스트 영역 내용이 중단됩니다.

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>


3

텍스트 영역 내용이 HTML로 구문 분석되는 것을 원하지 않는다고 가정합니다. 이 경우 브라우저가 HTML로 처리하지 않고 개행 문자를 제거하지 않도록 일반 텍스트로 설정하면됩니다. CSS 또는 전처리가 필요하지 않습니다.

<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>


2

비슷한 질문이 있습니다.

텍스트 영역 입력에서 줄 바꿈 감지

텍스트 영역에서 줄 바꿈 감지

이것을 시도 할 수 있습니다.

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;텍스트 영역의 텍스트 콘텐츠를 가져오고 콘텐츠의 textContent.replace(/\n/g, '<br/>')소스 코드 /\n/g에서 모든 줄 바꿈 문자를 찾아 html 줄 바꿈으로 바꿉니다 <br/>.


또 다른 옵션은 html <pre> 태그 를 사용하는 것 입니다. 아래 데모보기

var 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>


2
질문을 다시 읽으십시오. 포스터는 텍스트 영역의 텍스트를 다른 텍스트 영역이 아닌 페이지에 넣을 때 줄 바꿈을 유지하는 방법을 묻습니다.
Jesse

1
첫 번째 예는 버그가 있고 작동하지 않습니다. (결과 textContent.replace()를 아무것도 할당하지도 않습니다 .) 두 번째 예제는 이스케이프되지 않은 사용자 입력을 할당하기 때문에 다른 여러 답변과 동일한 HTML 주입 버그에 innerHTML취약합니다. 실제로 replace()호출 출력으로 유용한 작업을 수행합니다 .)
Ilmari Karonen 2016

감사합니다! Outlook 2013은 실제로 <pre>가 무엇인지 알고 있습니다
user1566694
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.