2011-01-29 45 views
26

Tôi đang chèn phần tử vào div có thể chỉnh sửa nội dung nhưng trình duyệt đặt vị trí của con trỏ trước phần tử được chèn. Có thể đặt con trỏ ngay sau phần tử được chèn để người dùng tiếp tục nhập mà không phải điều chỉnh lại vị trí con trỏ không?Đặt vị trí dấu mũ ngay sau phần tử được chèn vào một div nội dung có thể chỉnh sửa

+0

Related: http://stackoverflow.com/questions/2920150/insert-text-at-cursor-in-a-content-editable-div – payne

+0

Điều đó không trả lời được câu hỏi của tôi. Tôi có thể chèn phần tử ở vị trí dấu mũ, nhưng tôi cần đặt dấu mũ ngay sau phần tử được chèn. – Elie

+0

Bạn đã thử mô phỏng sự kiện bàn phím sau khi chèn chuỗi, chẳng hạn như phím "kết thúc" (phím mã số 35) trên bàn phím. – jnkrois

Trả lời

28

Chức năng sau sẽ thực hiện. Đối tượng Phạm vi DOM cấp 2 giúp việc này dễ dàng trong hầu hết các trình duyệt. Trong IE, bạn cần phải chèn một phần tử đánh dấu sau khi nút bạn đang chèn, di chuyển vùng chọn vào nó và sau đó loại bỏ nó.

Sống dụ: http://jsfiddle.net/timdown/4N4ZD/

Code:

function insertNodeAtCaret(node) { 
    if (typeof window.getSelection != "undefined") { 
     var sel = window.getSelection(); 
     if (sel.rangeCount) { 
      var range = sel.getRangeAt(0); 
      range.collapse(false); 
      range.insertNode(node); 
      range = range.cloneRange(); 
      range.selectNodeContents(node); 
      range.collapse(false); 
      sel.removeAllRanges(); 
      sel.addRange(range); 
     } 
    } else if (typeof document.selection != "undefined" && document.selection.type != "Control") { 
     var html = (node.nodeType == 1) ? node.outerHTML : node.data; 
     var id = "marker_" + ("" + Math.random()).slice(2); 
     html += '<span id="' + id + '"></span>'; 
     var textRange = document.selection.createRange(); 
     textRange.collapse(false); 
     textRange.pasteHTML(html); 
     var markerSpan = document.getElementById(id); 
     textRange.moveToElementText(markerSpan); 
     textRange.select(); 
     markerSpan.parentNode.removeChild(markerSpan); 
    } 
} 

Ngoài ra, bạn có thể sử dụng Rangy library tôi. Mã tương đương sẽ có

function insertNodeAtCaret(node) { 
    var sel = rangy.getSelection(); 
    if (sel.rangeCount) { 
     var range = sel.getRangeAt(0); 
     range.collapse(false); 
     range.insertNode(node); 
     range.collapseAfter(node); 
     sel.setSingleRange(range); 
    } 
} 
+4

Heh. Điều này thật thú vị: "Các đối tượng vùng DOM Cấp 2 làm cho việc này trở nên dễ dàng trong hầu hết các trình duyệt." Đã thử nhiều hoán vị khác nhau trong ba ngày với rất ít thành công. (Tôi biết, không phải là một bình luận hữu ích, nhưng chỉ cần phải nói nó) – eon

+0

@eon: :) Có lẽ tôi nên có đủ điều kiện rằng: "So với các khó chịu hack cần thiết trong IE <9, DOM Level 2 Range đối tượng làm cho điều này dễ dàng hầu hết các trình duyệt. " –

+1

Chỉ có vẻ như hoạt động đối với nút văn bản. Đã cố gắng cho nó một yếu tố span và con trỏ kết thúc lên trước khi span ?? – user984003

0

Nếu bạn chèn một div, p hoặc span rỗng, tôi tin rằng cần phải có "thứ gì đó" bên trong phần tử mới được tạo cho phạm vi lấy vào - và trong để đặt dấu mũ bên trong.

Đây là lỗi của tôi có vẻ như hoạt động tốt trong Chrome. Ý tưởng chỉ đơn giản là đặt một chuỗi tạm thời bên trong phần tử, sau đó loại bỏ nó khi dấu mũ ở đó.

// Get the selection and range 
var idoc = document; // (In my case it's an iframe document) 
var sel = idoc.getSelection(); 
var range = sel.getRangeAt(0); 

// Create a node to insert 
var p = idoc.createElement("p"); // Could be a div, span or whatever 

// Add "something" to the node. 
var temp = idoc.createTextNode("anything"); 
p.appendChild(temp); 
// -- or -- 
//p.innerHTML = "anything"; 

// Do the magic (what rangy showed above) 
range.collapse(false); 
range.insertNode(p); 
range = range.cloneRange(); 
range.selectNodeContents(p); 
range.collapse(false); 
sel.removeAllRanges(); 
sel.addRange(range); 

// Clear the non 
p.removeChild(p.firstChild); 
// -- or -- 
//p.innerHTML = ""; 
Các vấn đề liên quan