2012-12-31 7 views
6

Si consideri il seguente div contenteditableCome impostare la posizione di cursore/cursore in un div in contentedabile tra due div.

<div contenteditable="true"> 
<div>bold text</div><div>bold text</div> 
</div> 

Se posiziono il cursore tra i due div e inizio a digitare il testo esce grassetto invece di inserire un nuovo nodo di testo tra i due div. Lo stesso accade se colpisci a casa e provi a digitare qualcosa di fronte al primo div. Diventa parte del primo div.

Se analizzo lo startContainer dell'intervallo restituito dalla selezione, ottengo il contenuto di uno dei div anziché di un nodo di testo vuoto come mi aspetterei.

Vai a questa http://jsfiddle.net/9ZZpX/3/

La domanda è: perché questo accade? Come posso selezionare lo spot tra i div in modo che quando scrivo qualcosa non sia in grassetto? (Ovviamente posso aggiungere uno spazio e questo aggira il problema ma è abbastanza brutto.)

Si può vedere questo funziona correttamente su Facebook se si inserisce un @mentione in una casella di aggiornamento stato e si preme HOME. Se si digita il testo non verrà evidenziato.

L'unica cosa che ho potuto pensare è di intercettare il keypress e inserire un nodo di testo a livello di codice, ma questo sembra brutto.

Ho cercato come un matto e non riesco a trovare riferimenti che documentano come questo dovrebbe funzionare. C'è ovviamente qualcosa che non capisco e in questo campo manca davvero la documentazione.

(Quello che voglio essere in grado di fare è anche rilevare quando il cursore sta per entrare in uno di questi div e saltarci sopra. Se i due div sono l'uno accanto all'altro, il cursore salta in uno di il div e mucks le opere)

Maggiori informazioni su quello che sto cercando di fare. http://a-software-guy.com/2012/12/the-horrors-of-cursor-positioning-in-contenteditable-divs/

+0

Ho effettuato il rialzo per l'articolo. Grazie per la documentazione! –

risposta

7

browser sono in contrasto su questo. Firefox ti consentirà di posizionare il cursore in più posizioni rispetto alla maggior parte dei browser, ma WebKit e IE hanno entrambe idee precise sulle posizioni di caret valide e modificheranno un intervallo aggiunto alla selezione per conformarsi alla posizione valida più vicina. Questo ha senso: avere diverse posizioni del documento e quindi comportamenti per la stessa posizione di visualizzazione visiva è fonte di confusione per l'utente. Tuttavia, questo è a costo di inflessibilità per lo sviluppatore.

Questo non è documentato da nessuna parte. Il current Selection spec non dice nulla a riguardo, principalmente perché non esistevano specifiche quando i browser implementavano le loro API di selezione e non c'era un comportamento uniforme per le specifiche attuali da documentare.

Un'opzione sarebbe quella di intercettare l'evento keypress come suggerito, anche se questo non sarà di aiuto quando l'utente incolla il contenuto utilizzando i menu di modifica o di contesto. Un altro sarebbe quello di tenere traccia della selezione usando il mouse e gli eventi dei tasti, creare elementi con, diciamo, un carattere di spazio a larghezza zero per il cursore da inserire e posizionare il cursore in uno di questi elementi quando necessario. Come dici tu, brutto.

+0

Grazie. Eccellente. Questo è esattamente ciò di cui avevo bisogno. –

+0

(BTW, grazie per Rangy. Molto utile.) –

+0

Un articolo sui miei sforzi e l'approccio che sto provando: http://a-software-guy.com/2013/01/you-cant-select-that -webkit-browser-selezioni-e-intervalli-in-chrome-and-safari/ –

4

La mia risposta sarà solo un'aggiunta a quella di Tim, che è completa.

AFAIK Facebook non usa il contenuto modificabile. La casella di stato è costituita da una semplice area di testo e da uno strato div al di sotto della quale vengono visualizzati i riquadri blu per i nick.

Anche se lo facessero, sarebbe un caso diverso, perché il nick sarebbe un elemento in linea e fortunatamente con elementi in linea la situazione è più semplice :).

Per quanto riguarda il posizionamento del cursore in punti inaccessibili, al CKEditor abbiamo riscontrato lo stesso problema. Esistono molti luoghi in cui l'utente non può spostare il cursore. Abbiamo deciso di risolvere questo problema con un plug-in chiamato Magic-line. Come puoi vedere nella demo, abbiamo completamente ignorato il problema della selezione e penso che questo sia il modo migliore per risolvere questo problema. È molto utilizzabile e in CKEditor 4.0.1 sarà (e già è su master) completamente accessibile da tasti.

+0

Questa è una soluzione interessante. +1. –

+0

Molto interessante +1. Ho iniziato a provare a replicare ciò che Facebook ha fatto, ma ho realizzato rapidamente che quello che voglio realizzare è un po 'diverso. Solo un argomento fuori tema, se si apre una linea in alto, non sembra esserci un modo, in Chrome sotto Linux, per eliminare la riga superiore. Premo cancella e l'intera area viene evidenziata. –

0

Un'altra cosa che puoi fare è usare un osservatore di mutazioni per catturare le mutazioni e poi sistemarle dopo il fatto. Nel mio caso d'uso ho avuto la fortuna che ogni elemento avesse un testo predefinito. Quando l'osservatore di mutazione si attiva, ho semplicemente spostato il testo modificato in un nuovo nodo di testo prima o dopo l'elemento, a seconda dei casi. Questo sembra molto più semplice delle altre opzioni perché l'osservatore spara per tutte le modifiche ai dati dei personaggi, e ha anche una registrazione corretta di tutte le modifiche, a differenza dell'evento di keypress.