jQuery แปลงตัวแบ่งบรรทัดเป็น br (เทียบเท่า nl2br)


110

ฉันมี jQuery ใช้เนื้อหา textarea และแทรกลงใน li

ฉันต้องการให้มันรักษาเส้นแบ่งไว้ด้วยสายตา

ต้องมีวิธีง่ายๆจริงๆ ...


หมายเหตุ XSS: หากคุณกำลังทำสิ่งนี้ดูเหมือนว่าคุณกำลังผสมอินพุตของผู้ใช้โดยตรงกับ <br/> ซึ่งหมายความว่าคุณกำลังแสดงบรรทัดใหม่หรือ <br/s> ดังนั้นจึงอาจเปิดกว้างสำหรับการโจมตี XSS นั่นคือถ้าข้อมูลของคุณมาจากผู้ใช้รายอื่นในไซต์
user420667

คำตอบ:


165

การสาธิต: 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');
}

5
ขอบคุณที่ทำงานได้อย่างสมบูรณ์แบบ แปลกที่นี่ไม่ใช่หน้าที่อย่างเป็นทางการของ jQuery
gbhall

4
สาเหตุ jQuery ไม่ได้หมายถึงการแทนที่ฟังก์ชันดั้งเดิมของจาวาสคริปต์เช่นแทนที่มันมุ่งเน้นไปที่การเชื่อมโยงตัวเลือก CSS และเข้าถึงได้ง่าย! อาจจะเป็นเวอร์ชั่นอนาคต ;-)
Luca Filosofi

น่ากลัว ช่วยให้ฉันผ่านพ้นปัญหา IE7 ไม่รองรับ white-space: pre-wrap
Kevin Pauli

regex หมายความว่าถ้าบรรทัดลงท้ายด้วย ">" มันจะไม่เพิ่ม BR? ฉันรู้ว่าใน HTML ของฉันฉันใช้ & gt; แต่เนื้อหาที่ผู้ใช้สร้างขึ้นไม่ได้ผลกับสิ่งนั้น ...
Dave Stein

@DaveStein ไม่ฉันได้ลองใช้ทั้ง '>' และ '& gt;' และทั้งสองครั้งจะมีการเพิ่มตัวแบ่งบรรทัด ฉันคิดว่ารหัสฟังก์ชันนี้สมบูรณ์แบบโดยทั่วไป :)
Jake

91

คุณสามารถทำได้:

textAreaContent=textAreaContent.replace(/\n/g,"<br>");

ไชโยการทำงานประเภทนี้ยกเว้นว่าจะถือว่าการแบ่งบรรทัดหลายบรรทัดเป็นการแบ่งบรรทัดเดียว
gbhall

4
ฉันได้อัปเดตแล้วและตอนนี้ใช้ regexp ดังนั้นหากคุณต้องการใช้การแบ่งบรรทัดหลายบรรทัดเป็น br เดียวให้เปลี่ยน regexp ด้วย: / \ n + / g
mck89

ขอบคุณ. หวังว่าจะมีคนพบว่าคำตอบของคุณมีประโยชน์ แต่ฟังก์ชันด้านล่างก็ใช้ได้เช่นกัน ฉันรู้สึกแย่ที่คุณพยายามมากขึ้น แต่ฟังก์ชั่นเป็นที่ต้องการมากกว่า
gbhall

หากคุณได้รับข้อผิดพลาด "x.replace ไม่ใช่ฟังก์ชัน" ให้ใช้ x.toString () แทนที่
Vörös Amadea

29

ใส่สิ่งนี้ลงในโค้ดของคุณ (ควรอยู่ในไลบรารีฟังก์ชัน js ทั่วไป):

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

การใช้งาน:

var myString = "test\ntest2";

myString.nl2br();

การสร้างฟังก์ชันต้นแบบสตริงช่วยให้คุณใช้สิ่งนี้กับสตริงใดก็ได้


29

ด้วยจิตวิญญาณของการเปลี่ยนการแสดงผลแทนที่จะเปลี่ยนเนื้อหา CSS ต่อไปนี้จะทำให้บรรทัดใหม่แต่ละบรรทัดมีพฤติกรรมเหมือน<br> :

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

ทำไมต้องมีกฎ 2 ข้อ: pre-lineมีผลกับการขึ้นบรรทัดใหม่เท่านั้น (ขอบคุณสำหรับเบาะแส @KevinPauli) IE6-7 และเบราว์เซอร์เก่าอื่น ๆ ถอยกลับไปสู่จุดสูงสุดpreซึ่งรวมถึงnowrapและแสดงช่องว่างหลายช่อง รายละเอียดเกี่ยวกับการตั้งค่าเหล่านี้และอื่น ๆ ( pre-wrap) ที่mozillaและcss-tricks (ขอบคุณ @Sablefoste)

ในขณะที่โดยทั่วไปฉันไม่ชอบ SO predilection สำหรับการคาดเดาคำถามเป็นครั้งที่สองแทนที่จะตอบคำถามในกรณีนี้การแทนที่บรรทัดใหม่ด้วย<br>มาร์กอัปอาจเพิ่มช่องโหว่ในการโจมตีด้วยการฉีดยาด้วยการป้อนข้อมูลของผู้ใช้ที่ไม่เคยซัก คุณกำลังข้ามเส้นสีแดงสดเมื่อใดก็ตามที่คุณพบว่าตัวเองกำลังเปลี่ยน.text()สาย.html()ซึ่งคำถามตามตัวอักษรจะต้องทำ (ขอบคุณ @AlexS สำหรับการเน้นประเด็นนี้) แม้ว่าคุณจะตัดความเสี่ยงด้านความปลอดภัยในขณะนั้นการเปลี่ยนแปลงในอนาคตอาจทำให้เกิดขึ้นโดยไม่เจตนา แต่ CSS .text()นี้จะช่วยให้คุณได้รับการขึ้นบรรทัดใหม่โดยไม่ยากมาร์กอัปใช้ที่ปลอดภัย


1
นี่เป็นวิธีแก้ปัญหาที่ง่ายที่สุดและตอบคำถามได้ดีที่สุดทั้งนี้ขึ้นอยู่กับกรณี นอกจากนี้คุณยังอาจพิจารณาใด ๆ ของอีกตัวเลือกเช่นwhite-space: pre-wrapดูcss-tricks.com/almanac/properties/w/whitespace
Sablefoste

นี่เป็นคำตอบที่ดีที่สุด - โซลูชันการเปลี่ยนสตริงจะหมายถึงความจำเป็นในการใช้.html()เพื่อตั้งค่าเนื้อหาซึ่งจะทำให้ผู้ใช้สามารถแทรก HTML ได้ตามอำเภอใจเว้นแต่คุณจะกรองสิ่งนั้นล่วงหน้า
Alex S

จุดดีเกี่ยวกับ.html()อันตราย @AlexS พยายามรวม
Bob Stein


1

ฟังก์ชัน JavaScript นี้พิจารณาว่าจะใช้การแทรกหรือแทนที่เพื่อจัดการการแลกเปลี่ยน

(แทรกหรือแทนที่ตัวแบ่งบรรทัด 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);
}

สาธิต - JSFiddle

ฟังก์ชัน JavaScript nl2br & br2nl


1

ฉันเขียนส่วนขยาย 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);
};

0

เพื่อปรับปรุงคำตอบที่ยอมรับของ @Luca Filosofi

หากจำเป็นการเปลี่ยนประโยคเริ่มต้นของ regex นี้จะเป็นการ/([^>[\s]?\r\n]?)รวมกรณีที่บรรทัดใหม่มาหลังแท็กและช่องว่างบางส่วนแทนที่จะเป็นเพียงแท็กตามด้วยขึ้นบรรทัดใหม่ทันที


0

อีกวิธีหนึ่งในการแทรกข้อความจาก textarea ใน DOM ทำให้การแบ่งบรรทัดคือการใช้คุณสมบัติNode.innerTextที่แสดงถึงเนื้อหาข้อความที่แสดงผลของโหนดและลูกหลาน

ในฐานะผู้เริ่มต้นมันจะประมาณข้อความที่ผู้ใช้จะได้รับหากพวกเขาไฮไลต์เนื้อหาขององค์ประกอบด้วยเคอร์เซอร์แล้วคัดลอกไปยังคลิปบอร์ด

สถานที่ให้บริการนี้กลายเป็นมาตรฐานในปี 2559 และได้รับการสนับสนุนอย่างดีจากเบราว์เซอร์สมัยใหม่ ฉันสามารถใช้ได้ไหม: ความครอบคลุมทั่วโลก 97% เมื่อฉันโพสต์คำตอบนี้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.