2013-03-07 8 views
5

Ho scritto un codice per rilevare la fine della selezione utilizzando javascript e per posizionare un marcatore nella posizione finale. Vedere questo jsfiddle: http://jsfiddle.net/vCwwN/rileva la posizione di fine selezione utilizzando javascript

Il codice di cui sopra quanto segue:

  • Gestisce tutti gli script LTR (ad esempio inglese) correttamente (mostrando correttamente marcatore alla fine).
  • Per script LTR (ad esempio inglese) Gestisce se la selezione è in avanti (da sinistra/dall'alto a destra/in basso) o indietro (da destra/in basso a sinistra/in alto) correttamente mostrando il marcatore in cui la selezione è stata interrotta (usando il mouse o tastiera).
  • Utilizza getClientRects per trovare tutti i limiti dei rettangoli di selezione e un hack per rilevare la direzione della selezione (se indietro o meno). A seconda di queste due informazioni, posiziona il marcatore alla fine.

È possibile provare a selezionare ciò che è descritto sopra per lo script inglese senza alcun problema. L'unico problema è quando si tenta di gestire gli script RTL (ad es. In arabo), quindi il marker viene visualizzato all'inizio dello script RTL selezionato anziché alla fine (in cui il mouse/tastiera sono effettivamente fermati). Questi problemi di causa:

  • Inizia selezione all'interno di script RTL (arabo) e termina la selezione all'interno di script RTL (arabo). Questo mostra il marcatore all'inizio della selezione.
  • Inizia la selezione all'interno dello script LTR (inglese) e termina la selezione all'interno dello script RTL (arabo). Questo mostra il marcatore all'inizio della selezione dello script RTL (piuttosto che alla fine di esso).

Fondamentalmente, la selezione che inizia ovunque (LTR o RTL) e termina con lo script RTL non è corretta. Qualsiasi altro caso viene gestito correttamente (ad es. Inizia con LTR o RTL e termina con LTR, anche passando per script RTL sulla strada).

Il problema è che la direzione del flusso è capovolta per gli script RTL, e quindi indietro è avanti e avanti è indietro. Questo è il motivo per cui il mio codice non può gestire correttamente RTL e l'hack arretrato è invertito.

Una soluzione a cui ho pensato è di rilevare l'ultimo carattere della selezione e vedere se ha o meno lo script RTL, quindi basandoci su questo, girate la bandiera all'indietro. Ho già inserito una funzione per rilevare se un testo termina con un carattere RTL (è nello stesso jsfiddle inutilizzato). Potrebbe aiutarti, aiutami a risolverlo :)

+0

L'elemento di ingresso non si comporta come un ingresso di RTL per me. 'dir = rtl' manca? – Halcyon

+0

No, dovrebbe rimanere come è (cioè LTR, il valore predefinito). Se si imposta dir = rtl, l'intero oggetto viene capovolto per entrambi gli script (RTL/LTR).Ho gestito (dir = rtl) nel mio codice, ma ho deciso di rimuovere questo caso aggiuntivo per semplificare il codice e aumentare la possibilità di avere una risposta. – tria

risposta

0

Vedere se questo è un passo nella giusta direzione.

Esso sfrutta il seguente codice Return HTML from a user selection pubblicato da Tim Down:

function getSelectionHtml() { 
    var html = ""; 
    if (typeof window.getSelection != "undefined") { 
     var sel = window.getSelection(); 
     if (sel.rangeCount) { 
      var container = document.createElement("div"); 
      for (var i = 0, len = sel.rangeCount; i < len; ++i) { 
       container.appendChild(sel.getRangeAt(i).cloneContents()); 
      } 
      html = container.innerHTML; 
     } 
    } else if (typeof document.selection != "undefined") { 
     if (document.selection.type == "Text") { 
      html = document.selection.createRange().htmlText; 
     } 
    } 
    return html; 
} 

Una volta che è definito, è possibile chiamare il metodo lastCharTRL definito per verificare se l'ultimo carattere era RTL e agire di conseguenza.

if (lastCharRTL(getSelectionHtml())) 
    $('#pointer').css({top: rects[n].top + 10, left: rects[n].left - 10}).show(); 
else if(backwards) 
    $('#pointer').css({top: rects[0].top + 10, left: rects[0].left - 10}).show(); 
else 
    $('#pointer').css({top: rects[n].top + 10, left: rects[n].right}).show(); 

DEMO

+0

Mentre la tua soluzione/demo ha il problema originale (la selezione della fine RTL è ancora invertita) probabilmente a causa di innerHTML e if/else-if/else, penso di aver avuto l'idea di ottenere il testo di selezione. So che con 'getSelection' puoi chiamare' toString' e avere il testo. Quindi controlla l'inizio o la fine (a seconda della direzione della selezione) per vedere se c'è il carattere RTL. Proverò a farlo e vedrò. Grazie. – tria