2012-10-24 11 views
13

Ho una pagina con un'area di testo molto lunga utilizzata per la modifica di grandi quantità di testo. Normalmente, mentre si digita, quando il cursore si avvicina alla parte inferiore dell'area di testo, la pagina scorrerà automaticamente per mantenere il cursore sempre all'interno del viewport (Firefox scorrerà di una riga alla volta, Chrome scorrerà il cursore al centro di il viewport).Come mantenere sempre un punto di accesso del textarea all'interno del viewport?

Il mio problema deriva dal fatto che sto modificando a livello di codice il contenuto dell'area di testo in base a ciò che l'utente digita. In alcuni casi ciò comporta l'aggiunta di contenuti extra, quindi la visualizzazione del caret non viene eseguita.

Non appena l'utente preme un tasto, lo scorrimento automatico viene attivato e il cursore viene spostato in vista, ma non prima, così come l'utente sta digitando, perde di vista il cursore. Speravo di poter semplicemente attivare eventi chiave nell'area di testo affinché il browser eseguisse lo scorrimento automatico, ma gli eventi attivati ​​non emulano completamente il comportamento degli utenti e non ottengo una risposta.

L'unica soluzione che posso vedere ora è quello di cercare di ottenere le coordinate XY del punto di inserimento da:

  1. Trovare la posizione del carattere del cursore.
  2. Costruire un div che rispecchia il contenuto della textarea con un marcatore nella posizione del cursore.
  3. Misurazione della posizione dell'indicatore.

C'è un modo più semplice per farlo?

+1

può essere correlato: http://stackoverflow.com/a/12738472/1615483 –

risposta

0

[La soluzione precedente non era compatibile con Chrome (? WebKit)]

IF, un grande se, il contenuto aggiuntivo è aggiunto alla fine dell'input, l'esercizio al di sotto può offrire la soluzione:

<html> 
    <head> 
    <script> 
     function btnGoOnClick(ctrl) 
     { 
     //-- For this POC the text content is reset to 160 lines of dummy text - 
     //---------------------------------------------------------------------- 

     ctrl.value = ""; 

     for (var i = 0; i < 160; ++i) 
     { 
      ctrl.value += "dummy!\n"; 
     } 

     //-- Then the carret is set to the last position ----------------------- 
     //---------------------------------------------------------------------- 

     if (ctrl.createTextRange) 
     { 
      //-- IE specific methods to move the carret to the last position 

      var textRange = ctrl.createTextRange(); 
      textRange.moveStart("character", ctrl.value.length); 
      textRange.moveEnd("character", 0); 
      textRange.select(); 
     } 
     else 
     { 
      //-- Mozilla and WebKit methods to move the carret 

      ctrl.setSelectionRange(ctrl.value.length, ctrl.value.length); 
     } 

     //-- For WebKit, the scroll bar has to be explicitly set --------------- 
     //---------------------------------------------------------------------- 

     ctrl.scrollTop = ctrl.scrollHeight; 

     //-- Almost there: make sure the control has fucos and is into view ---- 
     //---------------------------------------------------------------------- 

     ctrl.focus(); 
     ctrl.scrollIntoView(false); 
     } 
    </script> 
    </head> 
    <body> 
    <form name="form"> 
     <input type="button" name="btnGo" value="Go!" onClick="btnGoOnClick(document.form.text);" /> 
     <div style="height: 1000px"></div> 
     <textarea name="text" rows="80"></textarea> 
    </form> 
    </body> 
</html> 
+0

Quello che sto vedendo è che scrollIntoView() scorre la finestra verso l'alto del textarea, ma che doesn' t avere alcuna correlazione con la posizione del cursore (l'altezza della mia textarea è maggiore dell'altezza del viewport, quindi il cursore può ancora essere nascosto). – blocks

+0

Scusa, mia cattiva! L'ho provato contro Mozilla e IE, saltando Chrome (WebKit). Ho ideato una soluzione più ampia, a prova di fallimento, e ho intenzione di modificare il mio post. Per favore, anche se hai già soddisfatto i tuoi bisogni, valuta e, se provato bene, contrassegna il mio post come valido. Io (noi) abbiamo bisogno di quei crediti :-) –

0

dal momento che siete già sulla via javascript e supponiamo un'altezza textarea dinamica porrebbe un problema di progettazione, si potrebbe provare il ridimensionamento automatico tua textarea dai contenuti:

function resizeTextarea(textarea) { 
    var lines = textarea.value.split('\n'); 
    var width = textarea.cols; 
    var height = 1; 
    for (var i = 0; i < lines.length; i++) { 
    var linelength = lines[i].length; 
    if (linelength >= width) { 
     height += Math.ceil(linelength/width); 
    } 
    } 
    height += lines.length; 
    textarea.rows = height; 
} 

So che questo non risponde alle specifiche delineate nel tuo post ma fornisce un approccio alternativo adatto al titolo della tua domanda. Quindi, anche se non è utile per te, potrebbe essere proprio questo per gli altri che visitano questa domanda.

Personalmente, odio le aree di testo troppo piccole e, a seconda del caso, preferisco che vengano autilizzate.

+0

Grazie per i pensieri, suppongo che questa sia una soluzione per un altro problema.Nel mio caso stavo già espandendo automaticamente la dimensione della textarea (sebbene la sua dimensione predefinita fosse già più grande della porta di visualizzazione) usando jquery-elastico, che credo abbia lo stesso effetto del codice che hai fornito. – blocks

1

Odio suggerire di aggiungere un'intera libreria per un problema, ma considerare CodeMirror. Gestisce tutte queste cose per te ed è abbastanza semplice da usare.

http://codemirror.net/

Problemi correlati