2012-04-02 30 views
7

Tôi đang sử dụng div có thể chỉnh sửa được kết hợp với thư viện Javascript rangy để chèn HTML ở vị trí con trỏ.div có thể chỉnh sửa được: IE8 không hài lòng với việc xóa bỏ phần tử HTML

End trong ngày các nội dung của div thường trông giống như:

<div contenteditable="true"> 
    "Hello " 
    <button contenteditable="false" data-id="147">@John Smith</button> 
    " " 
</div> 

Người dùng được đề nghị khi nhấn '@' và nhận được sau đó chèn như một nút khi được chọn (ala Google Plus). Tôi cũng chèn một &nbsp; sau nút này.

Nút bị xóa trong Chrome/Safari/Firefox khi bạn nhấn backspace (sau lần đầu tiên xóa &nbsp;), nhưng không phải trong IE8. Trong IE8 con trỏ chỉ đơn thuần nhảy qua nút mà không xóa nó. Điều gì thậm chí còn kỳ lạ hơn trong IE8 là nếu bạn rời khỏi &nbsp; bên cạnh nút - và thay vì đặt con trỏ ngay bên cạnh nút - nó sẽ xóa nút trên backspace. Vì vậy, nó hạnh phúc khi có một &nbsp; ở bên phải của con trỏ.

Có ai biết những gì tôi cần để làm cho IE8 hoạt động i.t.o. xóa nút khi lùi lại mà không cần &nbsp; ở bên phải con trỏ? (một số thông tin về hành vi kỳ lạ này cũng có thể hữu ích)

P.S. Tôi đã không kiểm tra các phiên bản khác của IE

+0

tại sao bạn có contenteditable = false vào nút? – MorganTiley

+1

Vì vậy, nó xóa nó khỏi DOM (trong một lần) khi bạn nhấn backspace hoặc khi bạn nhấn xóa (điều này hiện đang làm việc trong Chrome/Safari/Firefox). Nếu contenteditable = true thì văn bản của nút có thể chỉnh sửa được, đó không phải là trường hợp sử dụng của tôi. –

+0

Tôi không biết điều đó. (Tôi havent làm việc với đầu vào trong contEd trước). Điều gì về việc xử lý keyspace backspace và kiểm tra previoussibling của nút đầu tiên trong phạm vi lựa chọn? – MorganTiley

Trả lời

6

Đề xuất của tôi sẽ là kiểm tra dấu nháy đầu tiên sau khi nút không thể chỉnh sửa và nếu có, hãy tạo phạm vi bắt đầu ngay sau phần tử không thể chỉnh sửa và kết thúc ở vị trí dấu mũ. Kiểm tra xem văn bản trong phạm vi này có trống không. Nếu có, điều đó có nghĩa là dấu mũ được đặt trực tiếp sau phần tử không thể chỉnh sửa, vì vậy trong trường hợp đó, hãy xóa phần tử. Cuối cùng, đặt dấu mũ ở nơi không thể chỉnh sửa được.

Live Demo: http://jsfiddle.net/timdown/vu3ub/

Code:

document.onkeypress = function(e) { 
    e = e || window.event; 
    var keyCode = e.which || e.keyCode; 
    if (keyCode !== 8) { 
     return; 
    } 

    var sel = rangy.getSelection(); 
    if (sel.rangeCount === 0) { 
     return; 
    } 

    var selRange = sel.getRangeAt(0); 
    if (!selRange.collapsed) { 
     return; 
    } 

    var nonEditable = document.getElementById("nonEditable"); 
    if (!nonEditable) { 
     return; 
    } 

    // Check the caret is located after the non-editable element 
    var range = rangy.createRange(); 
    range.collapseAfter(nonEditable); 

    if (selRange.compareBoundaryPoints(range.START_TO_END, range) == -1) { 
     return; 
    } 

    // Check whether there is any text between the caret and the 
    // non-editable element. If not, delete the element and move 
    // the caret to where it had been 
    range.setEnd(selRange.startContainer, selRange.startOffset); 
    if (range.toString() === "") { 
     selRange.collapseBefore(nonEditable); 
     nonEditable.parentNode.removeChild(nonEditable); 
     sel.setSingleRange(selRange); 

     // Prevent the default browser behaviour 
     return false; 
    } 
}; 
+0

Rực rỡ! Cảm ơn rất nhiều cho một câu trả lời kỹ lưỡng như vậy. Tôi đã chỉnh sửa nó một chút - thay vì sử dụng document.getElementById ("nonEditable") tôi đã sử dụng selRange.startContainer.previousSibling (vì tôi không biết nút nào tôi cần phải loại bỏ trên backspace). –

+0

Cảm ơn một tấn cho câu trả lời tuyệt vời, Tim. Điều này đã cực kỳ hữu ích cho tôi ngày hôm nay. –

1

tôi đã thực hiện một jsfiddle với một mẫu nhanh chóng làm thế nào để nhìn vào một loạt các lựa chọn và sử dụng tài sản previousSibling của startContainer để tìm nút: jsfiddle

Đặt con trỏ trong aaa và nó sẽ hiển thị nút là anh chị em. đặt nó trong ccc và bbb sẽ hiển thị. Vì vậy, với điều này bạn có thể xử lý sự kiện keydown của div, kiểm tra xem phím là backspace + previousSibling là nút của bạn, và loại bỏ nó với jQuery. Quay lại đầu trang |

previousSibling là null nếu nó là một textnode mặc dù, chỉ FYI.

+0

Rất hay.Tôi nghĩ rằng tôi có thể sử dụng anh chị em trước đó kết hợp với phạm vi bù đắp như một giải pháp. Tôi sẽ báo cáo lại cách nó đi. –

Các vấn đề liên quan