2010-05-16 16 views
13

Ho letto alcuni post sul posizionamento del cursore, ma nessuno sembra rispondere al mio particolare problema.JavaScript 'contenteditable' - Ottenimento/impostazione della posizione di inserimento

  1. Ho 2 div (div1 e div2)
  2. div1 = non modificabile div
  3. div2 = contentEditable div
  4. entrambi i div contengono esattamente gli stessi contenuti
  5. quando l'utente fa clic su div1, viene nascosto e div2 appare in posizione precisa e l'utente può modificare

Il problema: Voglio il cursore ad apparire in posizione precisa sulla div2 come div1

Così, ho bisogno di qualche modo di leggere la posizione in cui l'utente fa clic su div1 e quindi quando div2 appare posiziona il cursore/cursore nella stessa posizione, quindi un set di funzioni getCaretLocation (in_div_id) e setCaretLocation (in_div_id).

Un modo per farlo?

Grazie -

+0

Ciao, hai trovato una soluzione? Sto affrontando lo stesso problema che mi rende folle .. –

risposta

7

Risposta breve: non è possibile

Risposta lunga: Il problema si faccia è che sarete in grado di ottenere (x, y) le coordinate per l'evento click su div1, ma qualsiasi implementazione della posizione del cursore mentre richiede di conoscere la posizione del cursore nel contenuto (che è il numero di caratteri che precedono il cursore).

Per convertire le coordinate (x, y) in una posizione di carattere, è necessario conoscere quanti caratteri ci sono prima (cioè a sinistra sulla riga corrente e sopra, se il testo è ltr).

Se si utilizza un carattere a larghezza fissa, è possibile semplificare il problema: associazione di una coordinata (x, y) a una (linea, colonna) di coordinate su una griglia di caratteri.

Tuttavia, si sta ancora affrontando il problema di non sapere come viene avvolto il testo. Per esempio:

------------------ 
|Lorem ipsum  | 
|dolor sit amet | 
|consectetur  | 
|adipiscing elit | 
------------------ 

Se l'utente fa clic sul d in dolor, si sa che il personaggio è il 1 ° al 2 ° linea, ma senza conoscere l'algoritmo di avvolgimento non c'è modo sarete sappi che è il tredicesimo personaggio di "Lorem ipsum dolor sit ...". E non vi è alcuna garanzia che tale algoritmo di avvolgimento sia identico tra browser e piattaforma.

Ora, quello che mi chiedo è perché dovresti utilizzare 2 differenti sincronizzati div in primo luogo? Non sarebbe più semplice utilizzare un solo div e impostare il suo contenuto in modo modificabile quando l'utente fa clic (o aleggia)?

+0

utilizzando 2 div perché sto abilitando l'utente a DRAG div in giro, che interferisce con il testo SELEZIONA (evidenziando per rendere in grassetto per esempio). – OneNerd

+0

pensando che posso ottenere le coordinate e fare scattare l'evento click() con le stesse coordinate su div2 - proverò a vedere come funziona. – OneNerd

+0

@OneNerd: Mi piacerebbe un handle o qualcosa per il trascinamento, ma senza sapere cosa sia il resto dell'interfaccia utente, non saprei se questo ha senso per quello che stai facendo. –

0

Sembra che tu stia cercando di eseguire una modifica in linea ... hai guardato il plug-in jeditable?

1

È possibile inserire un piccolo elemento di span sul punto di inserimento, ottenere la sua posizione e rimuoverlo. Per una gamma di cross-browser e una libreria di selezione, vedere rangy.

+0

+1 per rangy. Cercare di gestire le gamme da solo è un disastro –

0

Quando si fa clic su un elemento, viene creato un oggetto Selezione con lunghezza zero (prelevarlo da element.getSelection(), dove elemento è il div in questione). L'oggetto focusOffset di quell'oggetto ti farà sapere che hai cliccato su, ad esempio, il settantesimo carattere in quel div (questa è la cosa che Adrien ha detto che era impossibile in una risposta diversa).

1

si può, in pratica è necessario impostare il contenuto temporanea modificabile sul vostro primo div per catturare pos Caret

$('div1').hover(function() 
{ $(this).attr('contenteditable','true'); 
},function() 
{ $(this).removeAttr('contenteditable'); 
}).mouseup(function() 
{ var t = $(this); 
    // get caret position and remove content editable 
    var caret = t.getCaret(); 
    t.removeAttr('contenteditable'); 
    // do your div switch stuff 
    ... 
    // and apply saved caret position 
    $('div2').setCaret(caret); 
}); 

ora solo bisogno di ottenere/metodo di accento circonflesso set :)

Modifica> qui è la mia, (live demo)

 getSelection:function($e) 
     { if(undefined === window.getSelection) return false; 
      var range = window.getSelection().getRangeAt(0); 

      function getTreeOffset($root,$node) 
      { if($node.parents($root).length === 0) return false; // is node child of root ? 
       var tree = [], treesize = 0; 
       while(1) 
       { if($node.is($root)) break; 
        var index, $parent = $node.parent(); 
        index = $parent.contents().index($node); 
        if(index !== -1) { tree[treesize++] = index; } $node = $parent; 
       }; return tree.reverse(); 
      } 

      var start = getTreeOffset($e,$(range.startContainer)); 
      var end = getTreeOffset($e,$(range.endContainer)); 

      if(start & end === false) return false; 

      return {start:start,end:end,startOffset:range.startOffset,endOffset:range.endOffset}; 
     }, setSelection:function($e,s,win) 
     { $e.focus(); if(s === false) return; var sel = win.getSelection(); sel.removeAllRanges(); 

      function getNode($e,s) 
      { var node = $e; 
       for(var n=0;n<s.length;n++) 
       { var index = s[n]; if(index < 0) break; 
        node = node.contents(':eq('+index+')'); 
       } return node.get(0); 
      } 

      var start = getNode($e,s.start), end = getNode($e,s.end), range = win.document.createRange(); 
      range.setStart(start,s.startOffset); range.setEnd(end,s.endOffset); sel.addRange(range); 
     } 
0

Leggere la posizione del cursore nel testo e quindi impostare la posizione del punto di inserimento nella finestra di modifica.

Problemi correlati