2009-11-15 8 views
7

chcę wstawić znaki Tab wewnątrz textarea, tak:naciśnięcie klawisza jQuery: Naciśnij TAB wewnątrz TEXTAREA (podczas edycji istniejącego tekstu)

<textarea>{KEYPRESS-INSERTS-TAB-HERE}Hello World</textarea> 

mogę wstawić przed/po istniejący tekst TEXTAREA - i mogę wstawić/zastąpić cały tekst w textarea - ale jeszcze nie udało się wstawić wewnątrz istniejący tekst tEXTAREA (kursorem) w prosty sposób.

$('textarea:input').live('keypress', function(e) { 
    if (e.keyCode == 9) { 
     e.preventDefault(); 

     // Press TAB to append a string (keeps the original TEXTAREA text). 
     $(this).append("TAB TAB TAB AFTER TEXTAREA TEXT"); 

     // Press TAB to append a string (keeps the original TEXTAREA text). 
     $(this).focus().prepend("TAB TAB TAB BEFORE TEXTAREA TEXT"); 

     // Press TAB to replace a all text inside TEXTAREA. 
     $(this).val("INSERT INTO TEXTAREA/REPLACE EXISTING TEXT"); 

    } 
}); 

Istnieje „zakładki w textarea” plug-in dla jQuery ("Tabby") - ale to 254 linii kodu - Miałem nadzieję, że za kilka linii kodu.

Kilka linków, które studiowałem: (ponownie, wolałbym mniej linii kodu).

http://www.dynamicdrive.com/forums/showthread.php?t=34452
http://www.webdeveloper.com/forum/showthread.php?t=32317
http://pallieter.org/Projects/insertTab/

Proszę doradzić. Dzięki.

+0

Link do Tabby umarł, ale repo GitHub jest dostępny: https://github.com/alanhogan/Tabby –

Odpowiedz

13

I było stworzenie prostego AJAX zasilany IDE dla siebie, więc mogę szybko przetestować fragmenty PHP.

Pamiętam, potykając się na ten sam problem, oto jak I rozwiązać go:

$('#input').keypress(function (e) { 
    if (e.keyCode == 9) { 
     var myValue = "\t"; 
     var startPos = this.selectionStart; 
     var endPos = this.selectionEnd; 
     var scrollTop = this.scrollTop; 
     this.value = this.value.substring(0, startPos) + myValue + this.value.substring(endPos,this.value.length); 
     this.focus(); 
     this.selectionStart = startPos + myValue.length; 
     this.selectionEnd = startPos + myValue.length; 
     this.scrollTop = scrollTop; 

     e.preventDefault(); 
    } 
}); 

#input jest identyfikator textarea.

Kod nie jest całkowicie mój, znalazłem go w Google gdzieś.

Testowałem go tylko na FF 3.5 i IE7. To nie działa na IE7 ze smutkiem.

+0

Działa świetnie (FF 3.0.15). Dzięki. –

+3

Musiałem zastąpić 'keypress' przez' keydown', aby to działało w Chrome. – Senseful

+0

Bardzo dobrze ... o wiele lepiej niż w innych przykładach używających ton kodu! Musiałem również zastąpić naciśnięcie klawisza ... zastanawiając się, czy wystarczy nam tylko naciśnięcie klawisza. –

5

Niestety, manipulując tekst wewnątrz elementów textarea nie jest tak proste, jak mogłoby się nadzieję. Powód, dla którego Tabby jest większy niż te proste fragmenty, polega na tym, że działa on lepiej. Ma lepszą kompatybilność z różnymi przeglądarkami i obsługuje takie opcje, jak selekcja tabulatorów.

Po zminimalizowaniu jest to tylko około 5k. Proponuję go użyć. Będziesz jednak musiał odkryć i samodzielnie rozwiązać te same przypadki krańcowe lub nawet nie wiedzieć o nich, jeśli użytkownicy ich nie zgłoszą.

+0

+1 Patrząc na ' Kod Tabby "Nie widzę tam zbyt dużo odpadów, wystarczy kod potrzebny do odtworzenia funkcjonalności karty edytora kodu i zrobić to w sposób zgodny z różnymi przeglądarkami. Zgadzam się, że powinieneś go refaktoryzować za pomocą miniarki i użyć jej. –

+1

+1 Dave, Tak, zdałem sobie sprawę, że pozornie proste zadanie było dość trudne. Rozważę Tabby, jeśli potrzebuję rozwiązania kompatybilnego z przeglądarką. Dzięki./Kristoffer :-) –

1

Tak, radzenie sobie z wyborem pól wejściowych w różnych przeglądarkach jest uciążliwe, zwłaszcza że w IE jest kilka metod, które wyglądają tak, jakby powinny działać, ale tak naprawdę nie działają. (Warto zauważyć, że łączenie przy użyciu setEndPoint, a następnie mierzenie length, które wygląda OK, dopóki wybór nie rozpocznie się lub nie zakończy na znakach nowej linii).

Oto kilka funkcji użytkowych, które wykorzystuję do wyboru wejścia. Zwraca wartość podziału wejścia na bity, które są przed, wewnątrz i po selekcji (z wyborem liczonym jako pusty ciąg w pozycji ustawiania ostrości, jeśli nie jest to wybór). To sprawia, że ​​wystarczy po prostu wymienić i wstawić zawartość w wybranym miejscu, jednocześnie dbając o problem z IE CRLF.

(Może być jQuery, która robi coś podobnego, ale jeszcze jej nie spotkałem.)

// getPartitionedValue: for an input/textarea, return the value text, split into 
// an array of [before-selection, selection, after-selection] strings. 
// 
function getPartitionedValue(input) { 
    var value= input.value; 
    var start= input.value.length; 
    var end= start; 
    if (input.selectionStart!==undefined) { 
     start= input.selectionStart; 
     end= input.selectionEnd; 
    } else if (document.selection!==undefined) { 
     value= value.split('\r').join(''); 
     start=end= value.length; 
     var range= document.selection.createRange(); 
     if (range.parentElement()===input) { 
      var start= -range.moveStart('character', -10000000); 
      var end= -range.moveEnd('character', -10000000); 
      range.moveToElementText(input); 
      var error= -range.moveStart('character', -10000000); 
      start-= error; 
      end-= error; 
     } 
    } 
    return [ 
     value.substring(0, start), 
     value.substring(start, end), 
     value.substring(end) 
    ]; 
} 

// setPartitionedValue: set the value text and selected region in an input/ 
// textarea. 
// 
function setPartitionedValue(input, value) { 
    var oldtop= input.scrollTop!==undefined? input.scrollTop : null; 
    input.value= value.join(''); 
    input.focus(); 
    var start= value[0].length; 
    var end= value[0].length+value[1].length; 
    if (input.selectionStart!==undefined) { 
     input.selectionStart= start; 
     input.selectionEnd= end; 
     if (oldtop!==null) 
      input.scrollTop= oldtop; 
    } 
    else if (document.selection!==undefined) { 
     var range= input.createTextRange(); 
     range.collapse(true); 
     range.moveEnd('character', end); 
     range.moveStart('character', start); 
     range.select(); 
    } 
} 
+0

'getPartitionedValue' podaje błąd w IE na linii' range.moveToElementText (input); 'dla elementów' '(jest to w porządku dla textareas). –

+0

Można to naprawić, zastępując nieprawidłową linię przez 'var inputRange = input.createTextRange(); range.moveToBookmark (inputRange.getBookmark()); ' –

Powiązane problemy