2011-01-29 18 views
26
)

yerleştirildikten hemen sonra, bir contentEditable div öğesine bir öğe ekliyorum ancak tarayıcı, imlecin yerleştirilen öğeden önce konumunu ayarlar. İmleci, eklenen elemandan hemen sonra ayarlamak mümkün mü, kullanıcı imleç konumunu tekrar ayarlamak zorunda kalmadan yazmaya devam ediyor?Yerleştirilen öğeden bir contentEditable div öğesine (

+0

İlgili: http://stackoverflow.com/questions/2920150/insert-text-at-cursor-in-a-content-editable-div soruma cevap vermez – payne

+0

. Öğeyi düzeltme pozisyonuna yerleştirebiliyorum, ancak yerleştirilen elemandan hemen sonra düzeltmeyi yerleştirmem gerekiyor. – Elie

+0

Klavyede "son" (tuş kodu # 35) tuşu gibi bir dizgeyi ekledikten sonra klavye olayını simüle etmeye çalıştınız. – jnkrois

cevap

28

Aşağıdaki işlev bunu yapacaktır. DOM Level 2 Range nesneleri çoğu tarayıcıda bunu kolaylaştırır. IE'de, eklediğiniz düğümden sonra bir işaretleyici öğesi eklemeniz, seçimi ona taşımanız ve sonra çıkarmanız gerekir.

Canlı örnek: http://jsfiddle.net/timdown/4N4ZD/

Kodu:

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

Alternatif olarak, benim Rangy library kullanabilirsiniz. Boş bir div, p veya yayılma ekliyorsanız eşdeğer kod

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. Bu komik: "DOM Düzey 2 Aralığı nesneleri çoğu tarayıcıda bunu kolaylaştırır." Bunun için üç gün boyunca çeşitli başarılar deniyordum. (Biliyorum, yararlı bir yorum değil, sadece söylemek zorunda kaldı) – eon

+0

@eon: :) Belki de şunu kabul etmeliydim: "IE <9'da gerekli olan kötü kesmeye kıyasla DOM Level 2 Range nesneleri bunu kolaylaştıracak çoğu tarayıcı. " –

+1

Sadece metin düğümü için çalışıyor gibi görünüyordu. Bir span elemanı vererek çalıştı ve imleç açıklıktan önce biter? – user984003

0

olacağını, ben üzerine kapmak için aralığı için yeni oluşturulan elemanın içinde "şey" olması gerekir inanıyoruz - ve orada kafesi takmak için.

Burada, Chrome'da Tamam gibi görünen bir kesmek var. Bu fikir basitçe, elemanın içinde geçici bir dize koymak, sonra da kafanın içinde olduğunda onu çıkarmaktır.

// 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 = ""; 
İlgili konular