jQuery chuyển đổi ngắt dòng thành br (tương đương nl2br)


109

Tôi đang yêu cầu jQuery lấy một số nội dung textarea và chèn nó vào một li.

Tôi muốn nó giữ lại các ngắt dòng một cách trực quan.

Phải có một cách thực sự đơn giản để làm điều này ...


Lưu ý XSS: Nếu bạn đang làm điều này, có vẻ như bạn đang trộn trực tiếp đầu vào của người dùng và của <br/>, điều đó có nghĩa là bạn đang hiển thị các dòng mới hoặc <br/s>, do đó có thể bị tấn công XSS , đó là nếu thông tin đầu vào của bạn đến từ bất kỳ người dùng nào khác trên trang web.
user420667

Câu trả lời:


163

demo: 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
Cảm ơn bạn điều này hoạt động hoàn hảo. Kỳ lạ là đây không phải là một chức năng chính thức của jQuery.
gbhall

4
vì jQuery không có nghĩa là thay thế hàm javascript gốc như thay thế, nó tập trung vào chuỗi bộ chọn CSS và dễ dàng truy cập! có thể trong phiên bản tương lai ;-)
Luca Filosofi

Tuyệt vời. Giúp tôi vượt qua các vấn đề với IE7 không hỗ trợ white-space: pre-wrap
Kevin Pauli

Điều đó có nghĩa là regex không nếu một dòng kết thúc bằng ">" thì nó sẽ không thêm BR? Tôi biết trong HTML của mình, tôi sử dụng & gt; nhưng nội dung do người dùng tạo không hoạt động tốt với điều đó ...
Dave Stein

@DaveStein không Tôi đã thử điều này với cả '>' và '& gt;' và cả hai lần ngắt dòng được thêm vào. Tôi nghĩ rằng mã chức năng này về cơ bản là hoàn hảo :)
Jake

91

bạn chỉ có thể làm:

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

Chúc mừng, kiểu này đã hoạt động, ngoại trừ nó sẽ coi nhiều ngắt dòng như một ngắt dòng.
gbhall

4
Tôi đã cập nhật nó và bây giờ nó sử dụng một regexp vì vậy nếu bạn muốn để điều trị nhiều ngắt dòng như một sự thay đổi duy nhất BR regexp với: / \ n + / g
mck89

Cảm ơn bạn. Hy vọng rằng ai đó sẽ thấy câu trả lời của bạn hữu ích, nhưng chức năng bên dưới cũng hoạt động. Tôi cảm thấy thật tệ khi bạn đang nỗ lực nhiều hơn, nhưng một chức năng lại đáng mơ ước hơn.
gbhall

nếu bạn nhận được lỗi "x.replace không phải là một chức năng", sau đó sử dụng x.toString () thay thế.
Vörös Amadea

29

Đặt điều này vào mã của bạn (tốt nhất là trong thư viện hàm js chung):

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

Sử dụng:

var myString = "test\ntest2";

myString.nl2br();

tạo một hàm nguyên mẫu chuỗi cho phép bạn sử dụng nó trên bất kỳ chuỗi nào.


29

Với tinh thần thay đổi kết xuất thay vì thay đổi nội dung , CSS sau đây làm cho mỗi dòng mới hoạt động như<br> sau:

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

Tại sao hai quy tắc: pre-line chỉ ảnh hưởng đến dòng mới (cảm ơn vì manh mối, @KevinPauli). IE6-7 và các trình duyệt cũ khác trở lại cực đoan hơn pre, nó cũng bao gồm nowrapvà hiển thị nhiều khoảng trắng. Thông tin chi tiết về cài đặt này và các cài đặt khác ( pre-wrap) tại mozillacss-trick (cảm ơn @Sablefoste).

Mặc dù tôi thường không thích xu hướng SO để đoán câu hỏi thứ hai hơn là trả lời câu hỏi , trong trường hợp này, việc thay thế các dòng mới bằng <br>đánh dấu có thể làm tăng khả năng bị tấn công tiêm với đầu vào của người dùng chưa được rửa. Bạn đang vượt qua ranh giới màu đỏ tươi bất cứ khi nào bạn thấy mình thay đổi .text()các cuộc gọi .html()mà câu hỏi theo nghĩa đen ngụ ý sẽ phải được thực hiện. (Cảm ơn @AlexS đã nêu bật điểm này.) Ngay cả khi bạn loại trừ rủi ro bảo mật vào thời điểm đó, những thay đổi trong tương lai có thể vô tình giới thiệu nó. Thay vào đó, CSS này cho phép bạn ngắt dòng cứng mà không cần đánh dấu bằng cách sử dụng an toàn hơn .text().


1
Tùy từng trường hợp, đây là giải pháp đơn giản nhất và thực sự trả lời câu hỏi tốt nhất. Bạn cũng có thể xem xét bất kỳ white-space:tùy chọn nào khác , chẳng hạn như pre-wrap. Xem css-tricks.com/almanac/properties/w/whitespace
Sablefoste

Đây thực sự là câu trả lời tốt nhất - các giải pháp thay thế chuỗi sẽ có nghĩa là cần phải sử dụng .html()để thiết lập nội dung, do đó sẽ cho phép người dùng chèn HTML tùy ý trừ khi bạn lọc trước.
Alex S

Điểm tốt về .html()sự nguy hiểm @AlexS, đã cố gắng kết hợp.
Bob Stein

2

Giải pháp

Sử dụng mã này

jQuery.nl2br = function(varTest){
  return varTest.replace(/(\r\n|\n\r|\r|\n)/g, "<br>");
};

1

Hàm JavaScript này xem xét việc sử dụng chèn hoặc thay thế để xử lý hoán đổi.

(Chèn hoặc thay thế ngắt dòng 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);
}

Demo - JSFiddle

Các hàm JavaScript nl2br & br2nl


1

Tôi đã viết một phần mở rộng jQuery nhỏ cho điều này:

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

để cải thiện câu trả lời được chấp nhận của @Luca Filosofi,

nếu cần, việc thay đổi mệnh đề bắt đầu của regex này thành /([^>[\s]?\r\n]?)cũng sẽ dẫn đến các trường hợp dòng mới đứng sau thẻ VÀ một số khoảng trắng, thay vì chỉ một thẻ ngay sau dòng mới


0

Một cách khác để chèn văn bản từ một vùng văn bản trong DOM giữ cho các ngắt dòng là sử dụng thuộc tính Node.innerText đại diện cho nội dung văn bản được hiển thị của một nút và con cháu của nó.

Là một getter, nó ước tính văn bản mà người dùng sẽ nhận được nếu họ đánh dấu nội dung của phần tử bằng con trỏ và sau đó sao chép vào khay nhớ tạm.

Thuộc tính trở thành tiêu chuẩn vào năm 2016 và được hỗ trợ tốt bởi các trình duyệt hiện đại. Tôi có thể sử dụng : 97% phạm vi toàn cầu khi tôi đăng câu trả lời này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.