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...
W czym już testowałem i działa zgodnie z oczekiwaniami?
Z zastrzeżeniami...
W czym nie działa?
[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 :).
Ś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ę.
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?
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:
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ć.
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).