जब मैं एक textarea से पाठ प्राप्त कर रहा हूँ तो मैं रेखा को कैसे सुरक्षित रखता हूँ?


98

उपयोगकर्ता द्वारा सबमिट किए जाने पर मुझे टेक्स्टारिया में मान मिल रहा है। मैं तब इस मूल्य को लेता हूं और इसे पृष्ठ पर कहीं और रखता हूं। हालांकि, जब मैं ऐसा करता हूं, तो यह उत्पादन को बदसूरत बनाने वाले न्यूलाइन वर्ण खो देता है।

यहाँ मैं देख रहा हूँ textarea है:

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

यहां पोस्ट को एक्सेस करने और इसे ट्रांसक्रिप्ट करने के लिए जावास्क्रिप्ट कोड है।

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 बजे)

आउटपुट है:

समूह अनुसूची: मंगलवार अभ्यास @ ५ वीं मंजिल (रात 8 बजे - ११ बजे) गुरुवार अभ्यास @ ५ वीं मंजिल (रात pm बजे - ११ बजे) रविवार अभ्यास @ (९ बजे - १२ बजे)

तो क्या लाइन ब्रेक को संरक्षित करने का एक तरीका है?


1
यदि आपको jQuery का उपयोग करने की अनुमति है, तो यह आपकी मदद कर सकता है: कॉपी-से-टेक्सारिया-टू-डिव-प्रोटेक्टिंग-लाइनब्रेक वैकल्पिक रूप से यह मदद कर सकता है संरक्षित-लाइन-ब्रेक-इन-टेक्स्टारिया-इनपुट
केविन क्लैट

1
लाइन ब्रेक वास्तव में संरक्षित हैं, लक्ष्य तत्व को पाठ प्रदर्शित करते समय उन्हें अनदेखा करने के लिए सेट किया गया है, लेकिन यदि आप इसका निरीक्षण करते हैं तो आप देखेंगे कि वे यहां हैं। स्टेफानो का जवाब बस लक्ष्य को निर्धारित करता है कि अब उन्हें अनदेखा न करें, शायद सबसे अच्छा तरीका है।
स्पेक्ट्रा

2
नाइटपिक के लिए क्षमा करें, लेकिन getElementById2-से-अंतिम पंक्ति पर कार्य कहाँ है ? मैं मान रहा हूँ या तो आपने इसे कहीं और परिभाषित किया है या आप भूल गए हैं document
trysis

जवाबों:


186

सबसे आसान उपाय यह है कि जिस तत्व को आप पाठ में सम्मिलित कर रहे हैं उसे निम्नलिखित सीएसएस संपत्ति के साथ शैली दें:

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():


Ps। यदि आप सीएसएस संपत्ति का उपयोग किए बिना वास्तव में ऐसा करना चाहते white-spaceहैं, तो एक वैकल्पिक समाधान स्पष्ट रूप से <br>HTML टैग्स के साथ पाठ में किसी भी नए वर्ण को बदलना होगा । मुश्किल हिस्सा यह है कि, सूक्ष्म कीड़े और संभावित सुरक्षा छिद्रों को शुरू करने से बचने के लिए, आपको पाठ में किसी भी HTML मेटाचैकर्स (न्यूनतम &और कम से कम <) से बचना होगा। पहले इस प्रतिस्थापन को करने ।

संभवत: ऐसा करने का सबसे सरल और सुरक्षित तरीका है कि ब्राउज़र को आपके लिए HTML-भागने से बचाए, जैसे:

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

ध्यान दें, जबकि यह लाइन ब्रेक को ठीक कर देगा, यह HTML व्हाट्सएप द्वारा लगातार व्हाट्सएप को गिरने से नहीं रोकेगा। यह संभव है कि (तरह) अनुकरण करें कि पाठ में कुछ व्हाट्सएप को गैर-ब्रेकिंग स्पेस के साथ बदल दिया जाए, लेकिन ईमानदारी से, यह कुछ ऐसी चीज़ों के लिए जटिल हो रहा है जो सीएसएस की एक पंक्ति के साथ तुच्छ रूप से हल हो सकती हैं।


2
यह सबसे व्यापक उत्तर लगता है। यह मतदान क्यों है? यदि इसमें गलत जानकारी है तो कृपया साझा करें
एथन वेंडर हॉर्न

4
व्हाइट-स्पेस: प्री-लाइन ने मेरे लिए काम किया, क्योंकि प्री-रैप में पहली लाइन पर इंडक्शन था।
dev4life

1
धन्यवाद दोस्त। आप मेरा दिन बना दिया
thatman

तो बात यह है कि मैं व्हाट्सएप को टेक्स्ट एरिया में देख पा रहा हूं, लेकिन जब मैं उन्हें एपीआई एंड पर रिसीव करता हूं और उन्हें ईमेल में भेजा जाता है, तो यह स्पेस को संरक्षित नहीं करता है।
अपूर्वा कुंकुलोल

@ApurvaKunkulol: यह आपके सर्वर-साइड कोड में एक समस्या की तरह लगता है। आप इसके बारे में एक नया प्रश्न पूछ सकते हैं, लेकिन आपको एक न्यूनतम प्रतिलिपि प्रस्तुत करने योग्य उदाहरण प्रदान करना होगा जो समस्या को प्रदर्शित करता है।
इल्मरी करोनें

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पंक्ति को रोकने से पाठ की बहुत लंबी पंक्ति क्षैतिज स्क्रॉलबार को बाध्य करेगी।
सलमान ए

10
यह कोड HTML इंजेक्शन के लिए असुरक्षित है, क्योंकि आप बिना इनपुट उपयोगकर्ता इनपुट को असाइन कर रहे हैं innerHTML। इस मामले में, बस के innerHTMLसाथ textContentइसे ठीक कर देगा।
इल्मरी करोनें

1
@IlmariKaronen जो चीजों को तोड़ देगा। आप स्थापित करने की आवश्यकता innerText और textContent । केवल textContentIE (किसी भी संस्करण) में सेटिंग करना काम नहीं करेगा और सेटिंग केवल innerTextभविष्य में क्रोम पर काम नहीं करेगा और फ़ायरफ़ॉक्स पर काम नहीं करेगा।
इस्माईल मिगुएल

3
@IsmaelMiguel: यह अजीब है - मैं इसे IE 11 से पोस्ट कर रहा हूं, और यह यहां ठीक काम करता है। जाहिरा तौर पर IE ने textContentसंस्करण 9 के बाद से समर्थन किया है
इल्मरी करोनन

2
@IlmariKaronen यह अजीब है ... मुझे इसकी जानकारी नहीं थी। लेकिन innerTextअगर आपको IE8 की जरूरत है तो इसे शामिल करना एक अच्छा विचार है ।
इस्माईल मिगुएल

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

फिर इसे जनरेट करने के लिए उपयोग करें, हो सकता है, अधिक पी टैग ...


3
@IlmariKaronen ने क्या कहा: यह कोड गलत है क्योंकि आप सादे textarea.valueसंपत्ति ( innerHTML) को HTML ( ) की अपेक्षा रखने वाली संपत्ति पर असाइन कर रहे हैं । यह एक प्रकार की त्रुटि है जो टूटे हुए पाठ से लेकर सुरक्षा छेद तक की समस्याओं का कारण बनती है। उपयोग करने के बजाय innerHTML, आप के appendChildसाथ document.createTextNode(text)और कर सकते हैं document.createElement('br')
कोस

1
इसे और अधिक कुशल बनाने का एक अच्छा तरीका है document.createDocumentFragment
कोस

1
@ इल्मारिकारोन, कोस, यह सुरक्षा और न ही दक्षता के बारे में एक सवाल नहीं था। मैंने इसे ऑप्टिमाइज़ किया, हालाँकि।
कोलोडी

3
@ मिस्टर: ओपी ने लाइन ब्रेक को संरक्षित करने का एक तरीका पूछा, न कि लाइन ब्रेक को संरक्षित करने और HTML इंजेक्शन की अनुमति देने का तरीका । जब आप एक UI बग को ठीक करने के लिए मदद मांगते हैं तो एक नि: शुल्क सुरक्षा छेद प्राप्त करना पसंद है, जैसे कि जब आप हैमबर्गर के लिए पूछते हैं तो पैटी में एक मुफ्त थंबबैकैक प्राप्त करना। वैसे भी, चूंकि आपका "अनुकूलित" कोड अब असुरक्षित नहीं लगता है, इसलिए मैंने अपना डाउनवोट हटा दिया है।
इल्मरी करोनें

4

यहां एक विचार दिया गया है क्योंकि आपके पास एक टेक्स्टबॉक्स में कई न्यूलाइन हो सकते हैं:

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

यह HTML मान न्यूलाइन को संरक्षित करेगा। उम्मीद है की यह मदद करेगा।


1
यह बिना उपयोग किए गए उपयोगकर्ता इनपुट और HTML टैग्स के मिश्रण का भी उत्पादन करेगा, जो एक HTML इंजेक्शन भेद्यता पैदा करेगा यदि परिणामस्वरूप htmlस्ट्रिंग को वास्तव में HTML के रूप में गाया जाता है।
इल्मरी करोनन

@ इल्मारिकारोन - तो आपको चिंता इस बात की है कि कोई खुद पर हमला कर सकता है? ओपी किसी भी प्रकार के डेटाबेस का उल्लेख नहीं करता है। एक उपयोगकर्ता इनपुट किसी भी तरह से किसी अन्य उपयोगकर्ता को कैसे प्रभावित करेगा? हो सकता है कि यह एक ऐसी चीज है जो केवल ओपी आंखों के लिए है और इसमें स्वच्छता की आवश्यकता है (यदि इसके लिए भी इसकी कोई आवश्यकता है)।
जेसी

1
@ जेसे: सामान्य तौर पर, यह सुनिश्चित करना मुश्किल है कि उपयोगकर्ता इनपुट किसी विश्वसनीय स्रोत से आता है। यहां तक ​​कि अगर किसी हमलावर के लिए टेक्स्टएरिया में सीधे इंजेक्शन लगाने का कोई तरीका नहीं है, तो बहुत सारे सोशल मीडिया वायरस हैं जो सोशल इंजीनियरिंग के माध्यम से भोले उपयोगकर्ताओं को आश्वस्त करने के लिए फैल गए हैं, जो किसी असुरक्षित प्रविष्टि क्षेत्र में कुछ कॉपी-पेस्ट करने के लिए हैं। इसके अलावा, भले ही इनपुट वास्तव में 100% पर भरोसा किया जा सकता है, यह कोड अभी भी किसी भी पाठ को जगाता है जिसमें HTML मेटाचैकर &या जैसे हैं <। भले ही सुरक्षा एक चिंता का विषय नहीं है, फिर भी यह एक बग है।
इल्मरी करोनें

@ इल्मारिकारोन - मैं हमले के बारे में बिल्कुल चिंतित नहीं हूं लेकिन इस जानकारी के लिए धन्यवाद!
एथन वेंडर हॉर्न

3

आप widthजावास्क्रिप्ट का उपयोग करके 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 के रूप में नहीं मानता है और यह आवश्यक नहीं है कि कोई सीएसएस या प्रीप्रोसेसिंग को हटा दें।

<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

इसी तरह के सवाल यहां हैं

एक पाठ क्षेत्र इनपुट में पता लगाने की रेखा टूट जाती है

Textarea में लाइन ब्रेक का पता लगाएं

आप यह कोशिश कर सकते हैं:

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;textarea की पाठ्य सामग्री प्राप्त करेगा और सामग्री में 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
कृपया प्रश्न फिर से लिखें। पोस्टर पूछ रहा है कि किसी टेक्स्टरी से एक पेज पर टेक्स्ट डालते समय लाइन टूटने से कैसे बचा जाए, दूसरे टेक्स्टरी के अंदर नहीं।
जेसी

1
आपका पहला उदाहरण छोटी गाड़ी है और काम नहीं करता है। (आप किसी भी textContent.replace()चीज़ के परिणाम को कभी भी निर्दिष्ट नहीं करते हैं ।) आपका दूसरा उदाहरण उसी HTML इंजेक्शन बग के लिए कई अन्य उत्तरों की तरह असुरक्षित है, क्योंकि आप बिना इनपुट उपयोगकर्ता इनपुट को असाइन कर रहे हैं innerHTML(और आप पहला उदाहरण समान रूप से असुरक्षित होंगे, यदि आपने कोशिश की है वास्तव में replace()कॉल के आउटपुट के साथ कुछ भी उपयोगी है )।
इल्मरी करोनें

धन्यवाद! आउटलुक 2013 वास्तव में जानता है कि <pre> क्या है
user1566694
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.