2013-05-24 29 views
7

Ho un div contentedit in cui ho più tag (br, b, u, i) e testo e ho bisogno di ottenere la posizione del caret relativa al div, compresi tutti i tag .Ottieni la posizione del caret in div contenteditable compresi i tag

Ad esempio:

<div id="h" contenteditable="true">abc<b>def<br>ghi</b>jkl</div> 

Se il cursore è tra g ed h, devo posizione del cursore di essere 14. Il problema è che i metodi trovato che utilizzano un TreeWalker non funzionano in questo caso . Il tag grassetto non viene trovato ... probabilmente perché non è chiuso. Inoltre ho provato diversi metodi ma ancora senza fortuna.

Ho bisogno che funzioni in Firefox. Grazie.

+0

Perché avete bisogno questo numero? È essenzialmente privo di significato poiché esistono molti modi per rappresentare lo stesso DOM con HTML diverso che influirà sul numero (ad esempio usando '
' in luogo di '
'). Suppongo che tu lo desideri in modo da poter ottenere un offset relativo alla stringa HTML che stai inviando dal server al browser. –

+0

sì ... è esattamente il motivo per cui ho bisogno del numero. Ho provato diversi mezzi ma ancora nessun successo. – helldrain

+1

Non c'è modo di recuperare la stringa HTML originale tramite DOM, quindi dovrai ri-richiedere la pagina tramite Ajax, analizzare l'HTML e associarlo al DOM corrente. Sarà piuttosto difficile. –

risposta

20

Hai provato questo? Get a range's start and end offset's relative to its parent container

Link diretto al jsfiddle: codice di https://jsfiddle.net/TjXEG/1/

Funzione:

function getCaretCharacterOffsetWithin(element) { 
    var caretOffset = 0; 
    if (typeof window.getSelection != "undefined") { 
     var range = window.getSelection().getRangeAt(0); 
     var preCaretRange = range.cloneRange(); 
     preCaretRange.selectNodeContents(element); 
     preCaretRange.setEnd(range.endContainer, range.endOffset); 
     caretOffset = preCaretRange.toString().length; 
    } else if (typeof document.selection != "undefined" && document.selection.type != "Control") { 
     var textRange = document.selection.createRange(); 
     var preCaretTextRange = document.body.createTextRange(); 
     preCaretTextRange.moveToElementText(element); 
     preCaretTextRange.setEndPoint("EndToEnd", textRange); 
     caretOffset = preCaretTextRange.text.length; 
    } 
    return caretOffset; 
} 

function showCaretPos() { 
    var el = document.getElementById("test"); 
    var caretPosEl = document.getElementById("caretPos"); 
    caretPosEl.innerHTML = "Caret position: " + getCaretCharacterOffsetWithin(el); 
} 

document.body.onkeyup = showCaretPos; 
document.body.onmouseup = showCaretPos; 
+7

Grazie per la risposta. Il problema è che lo
non viene preso in considerazione quando si determina la posizione del cursore. – helldrain

+1

@helldrain Mi chiedo se sei riuscito a trovare una soluzione che includa i tag. –

+0

c'è qualche funzione che include anche la lunghezza dei tag. ? –

3

solo dovuto fare questo quindi c'è qualche soluzione di lavoro (alcuni test può essere richiesto)

l'idea di base è:

  1. ottenere la posizione textContent con questo metodo: Get caret (cursor) position in contentEditable area containing HTML content

  2. iterare attraverso innerHTML di un elemento nella posizione textContent

  3. se si incontra tag html o entità, scorrere fino char normale, quindi continuare

codice di esempio qui:

function getHTMLCaretPosition(element) { 
var textPosition = getCaretPosition(element), 
    htmlContent = element.innerHTML, 
    textIndex = 0, 
    htmlIndex = 0, 
    insideHtml = false, 
    htmlBeginChars = ['&', '<'], 
    htmlEndChars = [';', '>']; 


if (textPosition == 0) { 
    return 0; 
} 

while(textIndex < textPosition) { 

    htmlIndex++; 

    // check if next character is html and if it is, iterate with htmlIndex to the next non-html character 
    while(htmlBeginChars.indexOf(htmlContent.charAt(htmlIndex)) > -1) { 
    // console.log('encountered HTML'); 
    // now iterate to the ending char 
    insideHtml = true; 

    while(insideHtml) { 
     if (htmlEndChars.indexOf(htmlContent.charAt(htmlIndex)) > -1) { 
     if (htmlContent.charAt(htmlIndex) == ';') { 
      htmlIndex--; // entity is char itself 
     } 
     // console.log('encountered end of HTML'); 
     insideHtml = false; 
     } 
     htmlIndex++; 
    } 
    } 
    textIndex++; 
} 

//console.log(htmlIndex); 
//console.log(textPosition); 
// in htmlIndex is caret position inside html 
return htmlIndex; 
} 
+3

Sei il mio eroe. Questo ha funzionato magnificamente e mi ha salvato ore di lacrime. –

Problemi correlati