Strona robocza Nux-a
Ostatnia modyfikacja: 2009-09-06

Przydługi wstęp

Tu muszę się wytłumaczyć. Jakiś czas temu chciałem zrobić na Wikipedii wyszukiwanie w polu tekstowym. Napotkałem jednak przy tym trochę problemów, z których większość rozbijała się o to jak to zrobić, żeby działało w IE, Operze i Firefoksie. Wtedy rozpocząłem poszukiwania zmierzające ku wykryciu możliwie uniwersalnych metod poszukiwania i zaznaczania. Stąd właśnie wziął się tutejszy skrypcik (widoczny w źródle strony). Nie jest napisany przeze mnie – po prostu znalazłem go w sieci i troszkę uporządkowałem (oryginalny kod znajduje się w serwisie javascript.faqts i został udostępniony jako bezpłatny przez Freda Jountersa i Martina Honnena).

Po paru testach i sprawdzeniu jak to jest opisane w standardach miał powstać artykuł i skrypt mojej produkcji... Jednak w między czasie ktoś już zrobił bardzo fajne wyszukiwanie, które delikatnie podrasowałem i przetłumaczyłem. Stąd pierwsza potrzeba, właściwie zniknęła. Z drugiej strony tamten skrypt działa słabo w Operze (tu akurat problem z przewijaniem pola tekstowego <textarea>), no i w IE jak zwykle są różnorodne problemy (głównie z zaznaczaniem fragmentów). Ostatnio trochę wziąłem się za robienie klasy do wyszukiwania i zamiany, ale do właściwej wersji jeszcze dług droga. Tymczasem trochę notatek...

Testarea

Twój agent ;) –

input


textarea


Wyniki testów

W czym już testowałem i działa zgodnie z oczekiwaniami?

  • Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)*
  • Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.10) Gecko/20050921 Firefox/1.0.7 Mandriva/1.0.6-15mdk (2006.0)
  • Mozilla/5.0 (X11; U; Linux i686; pl; rv:1.8.1) Gecko/20061010 Firefox/2.0 Mandriva/1.0.6-15mdk (2006.0)
  • Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1
  • Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.8.1.5) Gecko/20070713 Firefox/2.0.0.5
* Windows NT 5.1 = Windows XP

Z zastrzeżeniami...

  • Opera/9.10 (Windows NT 5.1; U; pl) – nie działa przejście na koniec/początek, ale tylko jeśli zaznaczony jest jakiś obszar, co w sumie nie jest dużym problemem.

W czym nie działa?

  • Konqueror 3.4.2 (ani jeden z przycisków/funkcji)

[OT] Muszę przyznać, że nie działanie w Konqerorze mnie specjalnie nie martwi. Od czasu gdy zobaczyłem jak rozwalił kompletnie moją stronę wstawiając przycisk (input) w wersji z ustawień systemowych, który był blisko dwukrotnie większy niż przeciętny przycisk... No więc od tego czasu uznaję, że jest tylko jedna przeglądarka do której żywię szczerszą niechęć niż IE i jest nim właśnie Konqeror. Jeśli ktoś tego używa, to przepraszam, ale wystarczą mi już problemy Opera, IE i FF. Chociaż jeśli ktoś zna rozwiązanie tego problemu to może do mnie napisać na maila :).

Wnioski

Śmiało można założyć, że zawarta tutaj implementacja jest wstępnie wystarczająca. Oczywiście, żeby podstawowe cele zostały spełnione, problem występujący w Operze musi zostać rozwiązany, ale tu drobne korekty załatwiają sprawę.

Jak przesunąć okienko?

To głównie problem textarea. Załóżmy, że chcemy zrobić wspomnianą we wstępie wyszukiwarkę. Zaznaczanie już mamy, ale co jeśli mamy do czynienia z długim tekstem, który w danym momencie nie znajduje się na ekranie? Jak przewinąć pole textarea?

scrollTop

Można w tym momencie radośnie zauważyć, że istnieje atrybut scrollTop oznaczający pozycję górnej krawędzi ramki pola tekstowego. Jest z nim jednak parę problemów:

  1. Jednostką scrollTop są piksele – czy istnieje prosty sposób na przeliczenie wysokości linii?
  2. Czy można w prosty sposób przeliczyć indeks pierwszej literki zaznaczenia na linijkę, w której się znajduje?
  3. Czy scrollTop działa tak samo w Operze, FF i IE?

Obawiam się, że odpowiedzi na wszystkie te pytania są negatywne.

Ad.1. Niby istnieje atrybut lineHeight, ale z doświadczenia wiem, że nie przekłada się bezpośrednio na to o co nam w tym wypadku chodzi. Zdaje się, że nie zawsze ten atrybut jest ustalony, ale muszę jeszcze sprawdzić co tam było nie tak. To w każdym razie jest do rozwiązania np. na zasadzie eksperymentalnego ustawienia jakiegoś mnożnika, czy wręcz stałej wysokości dla naszego textarea.

Ad.2. Oczywiście można policzyć ilość nowych linijek w tekście. Problem jednak w tym, że w związku z zawijaniem tekstu, praktycznie nie jest możliwe obliczenie ile rzeczywiście jest linijek tekstu nad danym fragmentem (pierwszym znakiem fragmentu). Tu jedyne rozwiązanie jakie znam, to oszacowanie tej liczby przy pomocy średniej długości linii (ustalonej eksperymentalnie). Ale niestety problemem jest nawet ustalenie jaka jest szerokość naszego textarea – nie jest ona znana w przypadku gdy ustawimy szerokość pola na 100%. Rozwiązaniem jest ustawienie sztywnej szerokości (przynajmniej na czas wyszukiwania), a najłatwiej będzie jeśli ustawimy na sztywno ilość kolumn (cols)

Ad.3. To właściwie podchwytliwe pytanie. Jak na dzień dzisiejszy Opera (wersja 9.1) nie uwzględnia w ogóle czegoś takiego jak scrollTop (nie znalazłem żadnego analogicznego atrybutu). Jakaż tego przyczyna? Taka jak zwykle – Opera nie przejmuje się tym, że coś zwykle działa w FF, czy IE, tylko czy dana funkcjonalność jest opisana w standardach. Jest to oczywiście w pewnym stopniu godne pochwały, ale czasem też irytujące – podobnie jak to, że w Operze link z samym "#" nie działa jako przejście do góry strony (no, ale to taka dygresyjka). Co ciekawe na w3.org wyszperałem coś takiego jak CSSOM, w którym znajduje się rzeczony scrollTop (wersja z 18 czerwca 2007). Przerzucając kolejne wersje mogę powiedzieć, że wstępnie dokument wygląda całkiem ciekawie, a tym ciekawiej, że głównym redaktorem (a właściwe redaktorką) jest pracowniczka Opera Software ASA... Jest więc nadzieja na przyszłość, raczej jeszcze nie najbliższą, ale patrząc na tempo – może w przyszłym roku?

Podsumowując – nie jest łatwo, ale jakoś da się obejść problemy użycia scrollTop w FF i IE, a z Operą jeszcze trzeba poczekać.

Inne pomysły

Właściwie można powiedzieć, że problem Opery nie istnieje, bo od najwcześniejszych wersji, które używałem (chyba 7.x), możliwe jest wyszukiwanie w polach tekstowych połączone z wyszukiwaniem na stronie (dostępne też w FF od wersji 2.0). Nie jest to jednak w pełni zadowalające, bo w Operze wyszukanego tekstu nie można czymś zamienić. Innymi słowy nie jest to zaznaczenie tożsame z tym zaznaczeniem, które wykonuje się przy użyciu kursora...

Miałem kiedyś taki pomysł, żeby zadziałać analogicznie jak wtedy gdy po zaznaczeniu fragmentu nacisnę CTRL+X, CTRL+V. Po pierwszej operacji przeglądarka sama przewinie pole tekstowe, druga operacja ma za zadanie odtworzyć skasowany tekst. Problem jest tylko jeden – w JS nie da się symulować wciskania klawiszy i prawdopodobnie nigdy nie będzie się dało (względy bezpieczeństwa). Jest jeszcze gorzej, bo wycięcie fragmentu zaznaczonego tekstu (zastąpienie go pustym) powoduje powrót scrolla do góry...

Jak to odkryłem, to myślałem, że to już koniec – trzeba skupić się na scrollTop i tyle. Niespodziewanie jednak z pomocą przychodzi IE dostarczając funkcję, która przecież i tak musi być zaimplementowana w każdej z wymienianych tu przeglądarek „scrollIntoView”! W Mozillowatych co prawda też jest coś takiego, ale dotyczy tylko elementów, którym to nie jest zaznaczenie (DOM:element.scrollIntoView).

top