2012-10-24 8 views
13

Mam stronę z bardzo długim tekstem, używanym do edycji dużych ilości tekstów. Zwykle podczas pisania, gdy kursor zbliża się do dolnej krawędzi obszaru tekstowego, strona będzie automatycznie przewijana, tak aby karetka zawsze znajdowała się w okienku podglądu (Firefox będzie przewijać pojedynczą linię naraz, Chrome przewinie karetkę do środka rzutnia).Jak zachować ostrożność textarea zawsze w widocznym obszarze?

Mój problem wynika z faktu, że programowo zmieniam zawartość obszaru tekstowego na podstawie tego, co użytkownik wpisze. W niektórych przypadkach wiąże się to z dodawaniem dodatkowej treści, co powoduje odsunięcie wątku z widoku.

Po naciśnięciu klawisza autoportret rozpoczyna się i przewijany jest widok przewijania - ale nie wcześniej, więc podczas pisania użytkownik traci wzrok na karetkę. Miałem nadzieję, że po prostu uruchomię kluczowe zdarzenia w obszarze tekstowym, aby przeglądarka automatycznie przeszła autoprzesyłanie, ale zdarzenia wyzwalane nie w pełni emulują zachowanie użytkownika i nie otrzymuję odpowiedzi.

Jedynym rozwiązaniem widzę teraz jest, aby spróbować dostać współrzędne XY karetki przez:

  1. Znalezienie położenia znaków karetki.
  2. Budowanie elementu div, który odzwierciedla zawartość textarea za pomocą znacznika na pozycji caret.
  3. Pomiar pozycji znacznika.

Czy jest to prostszy sposób?

+1

mogą być związane z: http://stackoverflow.com/a/12738472/1615483 –

Odpowiedz

0

[Dotychczasowe rozwiązanie nie jest zgodne z Chrome (? WebKit)]

IF, BIG, jeśli dodatkowa zawartość jest dołączana do końca wejścia, poniżej ćwiczenie może zaoferować rozwiązanie:

<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

Co ja widzę, że scrollIntoView() przewija rzutnię do górnej części pola tekstowego, ale to nie robi” t mieć dowolną korelację z pozycją karetki (wysokość mojego textarei jest większa niż wysokość rzutni, więc karetka może nadal być niewidoczna). – blocks

+0

Przepraszam, moje złe! Przetestowałem to na Mozilli i IE, pomijając Chrome (WebKit). Opracowałem szersze, odporne na awarie rozwiązanie i zamierzam edytować mój post. Proszę, nawet jeśli już spełniłeś swoje potrzeby, oceń i, jeśli to potwierdziłeś, zaznacz moje stanowisko jako prawidłowe. Ja (my) potrzebujemy tych kredytów :-) –

0

Skoro już jesteśmy na ścieżce i załóżmy javascript dynamicznym wysokość textarea stanowiłby problem projektowania, można spróbować automatycznej zmiany Twojego textarea o treści:

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; 
} 

Wiem, że to nie odpowiada na szczegółowe informacje zawarte w twoim poście, ale zapewnia alternatywne podejście pasujące do twojego tytułu. Więc nawet jeśli nie jest to dla ciebie przydatne, może to być po prostu dla innych odwiedzających to pytanie.

Ja osobiście nienawidzę zbyt małych obszarów tekstowych i zależnych od przypadku, wolałbym je autosynchronizować.

+0

Dzięki za przemyślenia, przypuszczam, że jest to rozwiązanie innego problemu.W moim przypadku byłem już automatycznie rozszerzany rozmiar textarea (chociaż jego domyślny rozmiar był już większy niż port widoku) za pomocą jquery-elastic, który, jak sądzę, robi to samo, co podany kod. – blocks

1

Nienawidzę sugerować dodanie całej biblioteki do jednego problemu, ale rozważ spojrzenie na CodeMirror. Obsługuje wszystkie takie rzeczy dla ciebie i jest dość prosty w użyciu.

http://codemirror.net/

Powiązane problemy