2010-12-21 15 views
7

Đây là vấn đề khá được nói đến trên các diễn đàn jQuery nhưng tôi không thể tìm ra giải pháp cho tình huống của mình.Hàm jQuery text() mất các ngắt dòng trong IE

Tôi có một danh sách không có thứ tự với một số thành phần văn bản trong đó ... người dùng có thể tạo các mục danh sách mới thông qua jQuery, được lưu vào cơ sở dữ liệu SQL. Họ cũng có thể chỉnh sửa các mục danh sách hiện có. Ngoài ra, bởi vì văn bản trong mỗi mục danh sách có thể nhận được khá lâu, họ có tùy chọn 'ẩn' mỗi mục danh sách để nó hiển thị một phiên bản rút gọn của chuỗi. Này được xử lý bởi một tùy chỉnh jQuery plugin mà truncates mục danh sách đó là trên một chiều dài nhất định ... đây là những gì mỗi mục trông như thế nào khi các plugin truncate đã được định dạng nó:

<li id="item_1"> 
<div class="note"> 
    This is the text that shows when this element is truncated <span style="display: none;" class="truncate_ellipsis">...</span> 
<span style="display: inline;" class="truncate_more">This is the text that will be hidden if the user clicks on the 'hide' button</span> 
</div> 
<div class="toggle_wrapper"> 
    <div class="note_toggle"> 
     <a href="#" class="truncate_more_link">Hide note</a> 
    </div> 
    <div style="display: block;" class="note_controls"> 
     <span class="edit_note"><a href="#note_textfield" id="edit_note_1">Edit</a></span> | <span class="delete_note"><a href="#" id="delete_note_1">Delete</a></span> 
    </div> 
</div> 
</li> 

Tôi có vấn đề là người dùng nhấp vào 'chỉnh sửa' và nó lấy nội dung của div bằng ghi chú của lớp và gán nó vào vùng văn bản. Sau đó, người dùng có thể chỉnh sửa văn bản và lưu văn bản. Tôi đang sử dụng các kịch bản sau đây để lấy nội dung của div và gán nó vào textarea:

$('.edit_note a').click(function(event){ 

    // Get the parent li of the 'edit' link that was clicked 
    var parentLi = $(this).closest('li'); 

    // fade out the li that's being edited 
    parentLi.fadeOut('fast'); 

    // remove the '...' that shows when the note is truncated 
    parentLi.find('.truncate_ellipsis').remove(); 

    // find the 'note' div within the li that's being edited 
    var currentNote = parentLi.find('.note'); 

    // grab the id of this note... used when saving to the DB 
    var noteId = $(this).attr('id').substr(10); 

    // Set the current note id variable and editing status 
    currentNoteId = noteId; 
    currentNoteStatus = 'edit'; 

    //add the note ID as a hidden field to the text editor form 
    $('input[name$="note_id"]').val(noteId); 

    // grab the text from this note and add it to the text area 
    // (textarea id is 'notes_content') 
    $('#notes_content').val($.trim(currentNote.text()); // this is the text area 

    // fade in the text area so the user can edit 
    $('div.notes_textarea').fadeIn(); 

}); 

Sau khi đã lưu Tôi đang sử dụng một hàm Tôi tìm thấy trực tuyến để chuyển đổi các dấu ngắt dòng để PN, trước khi giao nội dung của vùng văn bản trở lại với 'lưu ý' div trong mục danh sách thích hợp:

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

bài này hoạt động tốt trong firefox/chrome/opera/safari ... Tuy nhiên, IE được thoát khỏi những ngắt dòng khi nó lấy văn bản thông qua hàm jQuery text(). Này được thảo luận trong các ý kiến ​​của trang này trên các tài liệu jQuery:

http://api.jquery.com/text/

Một số người đã thành công bằng cách nhân bản các yếu tố nguồn, gói nó trong 'trước' thẻ, sau đó tham gia các nội dung về điều đó và đưa nó trong vùng văn bản. Điều này làm việc cho ngắt dòng nhưng cũng mang lại thêm không gian, tab vv và có vẻ hơi lộn xộn. Một giải pháp tốt hơn có vẻ là sử dụng hàm html() jQuery để lấy văn bản, sau đó thay thế br cho các ngắt dòng và loại bỏ bất kỳ định dạng html nào khác.

Tôi mới tham gia Javascript, tuy nhiên, tôi là rác rưởi ở các biểu thức thông thường nên tôi sẽ không biết cách làm điều này và tôi hết thời gian! Tôi cần một biểu thức chính quy, hoặc chỉ một số giúp đỡ với định dạng chuỗi để làm như sau:

  • loại bỏ tất cả các thẻ khoảng từ một chuỗi KHÔNG loại bỏ các nội dung của nhịp (chức năng truncate tôi thêm một khoảng thời với lớp " truncate_more" ... xem mã html ở trên)

  • remove BR và thay thế chúng với các nhân vật xuống dòng mà sẽ hiển thị một cách chính xác trong một phần tử textarea và phù hợp trên các trình duyệt

HOẶC .. nếu có ai biết giải pháp tốt hơn cho vấn đề IE/textarea/linebreak này, tôi thực sự đánh giá cao một hướng dẫn về idiots :)

Khá nhiều thông tin cho một giải pháp đơn giản nhưng tôi nghĩ tôi sẽ cố gắng giải thích tình huống tốt nhất có thể ! Bất kỳ trợ giúp nào cũng sẽ được đánh giá rất cao ....

EDIT: 'Câu trả lời của TheJuice dưới đây làm việc cho vấn đề ngắt dòng/IE (cảm ơn), nhưng tôi cần thực hiện một quy trình tương tự để loại bỏ kéo dài, vì chúng chỉ đóng gói một số văn bản.Tôi cố gắng điều sau đây, mà dường như làm việc tốt trong firefox nhưng trong IE các nhịp còn:

 var withBRs = currentNote.html(); 
    var textWithBreaks = withBRs.replace(/\<br\>/gi,'\r'); 
    textWithBreaks = textWithBreaks.replace(/\<.*span.*\>/g, ''); 

KHÁC EDIT: 'TheJuice' giải quyết vấn đề này quá ... bỏ qua regex khủng khiếp của tôi và chỉ làm những gì ông nói rằng nếu bạn thấy mình trong tình huống tương tự! Nhờ tất cả những người đã đề xuất ...

Trả lời

6

Đây là giải pháp đơn giản hơn nhiều để chuyển đổi bất kỳ HTML nào thành văn bản thuần túy với ngắt dòng dựa trên việc sử dụng các thẻ <br> hoặc <p>.

function htmlDecodeWithLineBreaks(html) { 
    var breakToken = '_______break_______', 
     lineBreakedHtml = html.replace(/<br\s?\/?>/gi, breakToken).replace(/<p\.*?>(.*?)<\/p>/gi, breakToken + '$1' + breakToken); 
    return $('<div>').html(lineBreakedHtml).text().replace(new RegExp(breakToken, 'g'), '\n'); 
} 

Ví dụ, gọi phương thức sau đây:

htmlDecodeWithLineBreaks('line 1<br>line &amp; 2<br />' + 
    'line &gt; 3<p>paragraph 1</p>line 4') 

lợi nhuận:

line 1 
line & 2 
line > 3 
paragraph 1 
line 4 

Hy vọng rằng sẽ giúp;)

+0

Siêu này hoạt động với jQuery 'cheerio' cho Node.js - xem https://github.com/cheeriojs/cheerio/issues/839 – loretoparisi

6

Tôi nghĩ rằng một cái gì đó như thế này sẽ làm việc cho bạn. http://jsfiddle.net/6qbxn/2/. Tôi đã thử nghiệm điều này trong IE 7 FF 4.0b7 và nó hoạt động như mong đợi.

JS:

var withBRs = $('#brText').html(); 
var textWithBreaks = withBRs.replace(/\<br\>/gi,'\r'); 
$('#area').text(textWithBreaks); 

HTML:

<HTML> 
<body> 
    <div id="brText">Hello <br>How<br>Are<br>You?</div> 
    <textarea rows="10" id="area"> 

    </textarea> 
</body> 

Chỉnh sửa: Đây địa chỉ điểm viên đạn thứ hai của bạn.

+0

Đối với viên đạn đầu tiên của bạn, nếu nhịp của bạn chỉ cần quấn văn bản bạn cần, bạn có thể thay đổi bộ chọn của mình để loại bỏ chúng. http://jsfiddle.net/6qbxn/4/ – offner

+0

Cảm ơn các bạn rất nhiều, đó chính xác là những gì tôi đang tìm kiếm! Tôi biết nó sẽ là một cái gì đó đơn giản. Tuy nhiên, tôi vẫn còn một vấn đề nhỏ; span không gói gọn tất cả các văn bản, nó bắt đầu giữa chừng. Div mở ra, sau đó có một số văn bản, sau đó có một khoảng có chứa phần còn lại của văn bản, vì vậy tôi thực sự phải loại bỏ các thẻ mở và đóng (span trong tâm trí css được thêm vào thẻ mở thông qua jQuery cho truncate chức năng - xem đánh dấu ở trên). Có cách nào dễ dàng để làm điều đó với chức năng thay thế tương tự không? Tôi mới đến regex nên những nỗ lực của tôi khá là thảm hại! –

+0

@Mr_Beagle: Tôi sẽ chọn HTML từ khoảng đầu tiên sau đó thêm HTML từ khoảng thứ hai vào nó (giả sử bạn luôn có chỉ 2 nhịp). Sau đó, hãy thay thế nội dung
của bạn. Bạn có thể muốn tránh sử dụng regex nếu bạn có thể như ngay cả mã tôi đã cho thấy bạn sẽ có khả năng phá vỡ nếu ai đó tạo một thẻ như "
". – offner