2011-01-29 14 views
26

Inserisco un elemento in un content contentabile ma il browser imposta la posizione del cursore prima dell'elemento inserito. È possibile impostare il cursore subito dopo l'elemento inserito in modo che l'utente continui a digitare senza dover regolare nuovamente la posizione del cursore?Imposta la posizione di inserimento a destra dopo l'elemento inserito in un contentEditable div

+0

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

+0

Questo non risponde alla mia domanda. Sono in grado di inserire l'elemento nella posizione di inserimento, ma devo posizionare il cursore subito dopo l'elemento inserito. – Elie

+0

Si è tentato di simulare un evento tastiera dopo aver inserito la stringa, ad esempio il tasto "fine" (codice chiave # 35) sulla tastiera. – jnkrois

risposta

28

La seguente funzione lo farà. Gli oggetti DOM Level 2 Range lo rendono facile nella maggior parte dei browser. In IE, devi inserire un elemento marker dopo il nodo che stai inserendo, spostare la selezione su di esso e quindi rimuoverlo.

vivo esempio: http://jsfiddle.net/timdown/4N4ZD/

Codice:

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

In alternativa, è possibile utilizzare la mia Rangy library. Il codice equivalente ci sarebbe

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. Questo è divertente: "Gli oggetti DOM Level 2 Range lo rendono facile nella maggior parte dei browser." Ho provato varie permutazioni di questo per tre giorni con scarso successo. (Lo so, non un commento utile, ma dovevo dirlo) – eon

+0

@eon: :) Forse avrei dovuto qualificarmi: "Rispetto al brutto trucco necessario in IE <9, gli oggetti DOM Livello 2 rendono questo facile la maggior parte dei browser. " –

+1

Sembrava funzionare solo per il nodo di testo. Provato dandogli un elemento di span e il cursore finisce prima dell'estensione ?? – user984003

0

Se si sta inserendo un div vuoto, p o luce, credo che ci deve essere "qualcosa" all'interno dell'elemento appena creato per la gamma a cui aggrapparsi - e in per mettere il cursore all'interno.

Ecco il mio trucco che sembra funzionare correttamente in Chrome. L'idea è semplicemente di inserire una stringa temporanea all'interno dell'elemento, quindi rimuoverla una volta che il punto di inserimento è all'interno.

// 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 = ""; 
Problemi correlati