MooTools 1.2 - detekcja przeglądarki
04 lipca, 2008
Największą bolączką programistów piszących skrypty z użyciem JavaScript są oczywiście różnice w implementacji tego języka w różnych przeglądarkach - różnice pomiędzy Internet Explorerem, a Firefoksem są ogromne, a nie brak także różnic pomiędzy Firefoksem i Operą czy Safari. Dlatego też niezwykle istotną kwestią przy pisaniu uniwersalnego skryptu jest detekcja przeglądarki użytkownika.
Oczywiście MooTools 1.2 oferuje w tym zakresie bardzo wiele zwłaszcza, że pozwala nie tylko wykryć jakiej przeglądarki używa użytkownik, ale jest w stanie także udzielić nam informacji o systemie operacyjnym, możliwościach przeglądarki czy wersji pluginu Flash.
Obiekt Browser wszystko Ci powie
W obiekcie Browser zawarte są 4 właściwości: Engine, Platform, Features i Plugins. Pierwsza z nich zawiera informacje o wersji przeglądarki, druga zawiera informacje o systemie operacyjnym, a trzecia i czwarta są związane z dodatkowymi możliwościami przeglądarki. Zacznijmy od omówienia pierwszych dwóch właściwości.
Powiedz mi jakiej przeglądarki używasz, a będę wiedział co dalej
Nie będę owijał w bawełnę - z wszystkich możliwości wykrywania przeglądarki najczęściej będziecie używali tej, która wykrywa IE ;)
Ogólnie MooTools 1.2 pozwala wykrywać przeglądarki tylko ze względu na typ silnika renderującego, jak i ze względu na wersje tegoż silnika.
Poniżej pełna lista właściwości wykrywających poszczególne przeglądarki:
- Browser.Engine.trident - Internet Explorer (a także dowolna przeglądarka oparta na silniku IE),
- Browser.Engine.trident4 -Internet Explorer,
- Browser.Engine.trident5 - Internet Explorer 7,
- Browser.Engine.gecko - dowolna przeglądarka oparta na silniku Gecko,
- Browser.Engine.gecko18 - Firefox 2 (i wszystkie inne przeglądarki oparte na Gecko 1.8),
- Browser.Engine.gecko19 - Firefox 3 (i wszystkie inne przeglądarki oparte na Gecko 1.9),
- Browser.Engine.webkit - Safari i Konqueror,
- Browser.Engine.webkit419 - Safari 2 i inne przeglądarki oparte na Webkicie w wersji <= 419,
- Browser.Engine.webkit420 - Safari 3 i inne przeglądarki oparte na Webkicie w wersji >419,
- Browser.Engine.presto - Opera,
- Browser.Engine.presto925 - Opera 9.25 i starsze,
- Browser.Engine.presto950 - Opera 9.5 i nowsze
Sprawdzenie czy użytkownik korzysta z danej przeglądarki polega na stworzeniu warunku postaci:
if(Browser.Engine.odpowiedniEngine){ // kod który wykona się tylko w danej przeglądarce }
Dodatkowo istnieje właściwość Browser.Engine.name, która zwraca nam nazwę silnika renderującego przeglądarki. Przykładowo pod Firefoksem otrzymamy "gecko".
Gdy ważny jest system operacyjny
Wykrywanie systemu operacyjnego użytkownika przebiega w podobny sposób - różnica polega na tym, że odwołujemy się do właściwości Platform:
- Browser.Platform.mac - MacOs
- Browser.Platform.win - Windows.
- Browser.Platform.linux - Linux.
- Browser.Platform.ipod - iphone, ipod touch (a w zasadzie każde urządzenie, które oferuje właściwość window.orientation).
- Browser.Platform.other - inny system operacyjny
Nie ukrywam, że z pewnością najciekawsza aktualnie wydaje się możliwość wykrycia iphone'a/ipod touch'a jako przeglądarki - dzięki temu można na przykład załadować odpowiednie style dla tych urządzeń lub też uniemożliwić uruchomienie aplikacji dedykowanych tym urządzeniom na zwykłych pecetach.
Oczywiście Browser.Platform.name zwraca nam nazwę platformy - w wypadku Windows będzie to "win".
Co potrafisz przeglądarko ?
Dzięki właściwości Features możemy zweryfikować co dana przeglądarka potrafi - mamy możliwość sprawdzenia następujących kwestii:
- Browser.Features.air - wsparcie dla środowiska Adobe Air
- Browser.Features.xhr - wsparcie dla asynchronicznych zapytań (AJAX)
- Browser.Features.xpath - wsparcie dla XPath
I znów podobnie jak w wypadku właściwości obiektów Platform i Engine musimy tworzyć odpowiednie instrukcje warunkowe by zweryfikować możliwości przeglądarek.
Jaka wersja Flasha ?
Ostatnia właściwość obiektu Browser - Plugins, pozwala sprawdzić jakiej wersji pluginu Flash używa dana przeglądarka. Obiekt Browser.Plugins.Flash posiada dwie właściwości: version i build, zatem by wyświetlić pełną wersję pluginu Flash używanego w danej przeglądarce zapiszemy:
alert("Używasz pluginu Flash w wersji : " + Browser.Plugins.Flash.version + "." + Browser.Plugins.Flash.build);
eval nie jest dobry na wszystko
Gdyby się kogoś spytać jak wykonać tekst jako kod JavaScript to z pewnością większość pytanych (a może ankietowanych :>) odpowie, że wystarczy użyć funkcji eval dostępnej natywnie w JS. Ta odpowiedź jest oczywiście dobra, ale nie w 100% wypadków.
Weźmy dla przykładu taki oto kod:
function dodajZmienna() { var kod = 'var zmienna = "Tekst testowy"'; eval(kod); } dodajZmienna(); alert(zmienna);
Powyższy kod nie zadziała, ponieważ nowa zmienna nie istnieje poza funkcją. Gdybyśmy zastosowali taki kod:
function dodajZmienna() { var kod = 'var zmienna = "Tekst testowy"'; eval(kod); alert(zmienna); } dodajZmienna();
Wszystko będzie w porządku. Zatem jak widać problem polega na tym, że kod nie jest wykonywany przez funkcję eval globalnie. Lekarstwem na to w IE jest window.execScript (w innych przeglądarkach z reguły kończy się na dodaniu znacznika script z odpowiednim kodem JS), a uniwersalnym rozwiązaniem jakie oferuje MooTools jest funkcja $exec - zmieńmy pierwszy przykład, a dokładniej 3 linijkę:
function dodajZmienna() { var kod = 'var zmienna = "Tekst testowy"'; $exec(kod); } dodajZmienna(); alert(zmienna);
Powyższy kod powinien zadziałać bez zarzutu. Podsumowując - jeżeli potrzebujemy globalnie wykonać kod JS zapisany w postaci ciągu znaków, to stosujemy funkcję $exec zamiast eval.
Wzbogacony obiekt document
Na koniec słów kilka o obiekcie document - MooTools dodaje do niego kilka właściwości, które mogą się przydać:
- document.head - zwraca uchwyt do sekcji head dokumentu,
- document.html - zwraca uchwyt do elementu html dokumentu,
- document.window - zwraca uchwyt do obiektu okna dla danego dokumentu (to samo co document.defaultView i document.parentWindow tylko w wersji uniwersalnej)
Podsumowanie
Wiemy już jak dokonać detekcji przeglądarki i systemu operacyjnego użytkownika, potrafimy też wykonywać kod JS zapisany jako ciąg znaków globalnie oraz lokalnie. W kolejnych częściach kursu skupimy się na obiektach natywnych JavaScript.
Komentarze do wpisu "MooTools 1.2 - detekcja przeglądarki":
1.
Mateusz Żeromski napisał(a):
05 lipca 2008, 14:25:07
Proponuję od razu przejść do lektury jquery.com i praktycznego zastosowania – znikna problemy z róznym interpretowaniem javascriptu.
MooTools jest fajne, ale jquery fajniejsze.
Pozatym wpis ogólnie jest przepisaniem części dokumentacji http://docs.mootools.net/Core/Browser co jest bez sensu.
Moim zdaniem powinieneś podać przykłady zastosowania tych możliwości mootools aby ten wpis miał sens i wniósł coś nowego do internetu :). Polecam autorskie przykłady a nie tłumaczenia już istniejących.
2.
Dziudek napisał(a):
05 lipca 2008, 14:36:36
@Mateusz Żeromski – szczerze ? Nie wiem czy się śmiać czy płakać. Pisząc : „MooTools jest fajne, ale jquery fajniejsze” pokazujesz, że masz blade pojęcie o frameworkach JavaScript – MooTools chociażby w kwestii animacji jest lata świetlne do przodu w stosunku do jQuery (chodzi mi o sam framework, a nie jakieś dodatki typu script.aculu.us do Prototype). jQuery ma swoje zalety i wady, MooTools także i dlatego warto znać oba – kursów jQuery jest kilka w polskiej części sieci, czego nie można powiedzieć o MooTools.
Jeżeli według Ciebie przepisałem dokumentację to wskaż mi proszę, gdzie w dokumentacji masz wspomniane o właściwościach: Browser.Features.air, Browser.Engine.gecko18, Browser.Engine.gecko19, document.window, document.html, document.head ? Gdzie jest napisane po co istnieje w ogóle funkcja $exec ? Między innymi po to piszę ten kurs – by zweryfikować to co jest w oficjalnej dokumentacji, by inni nie musieli przedzierać się przez tysiące linii kodu MooTools, a także innych stron związanych z JS. A co do przykładów – jeżeli te wszystkie kody źródłowe widziałeś pod wspomnianym przez Ciebie adresem to gratuluję...
3.
Mateusz Żeromski napisał(a):
05 lipca 2008, 17:39:11
ok, skoro mowisz ze mootools jest lepsze od jqeury, to podaj konkretny przykład, w czym mootools przebija jquery, pomijając miganie/przewijanie etc warstw bo to nie ma wpływu na działanie aplikacji/stronki, ja ci podam jeden bez którego ani rusz, plugin tablesorter (z stronicowaniem) – http://tablesorter.com/docs/.
Przytoczone przez Ciebie przykłady w niczym sie nie przydadzą, a jak tak to podaj prosze przykład kiedy ff3 inaczej interpretuje js niz ff2, document.* – jest to tylko alias do istniejących obiektów – równiez nic nowego nie wnosi.
Podany przykład przez ciebie ze zmienną wprowadziłby w kodzie niepotrzebne zamieszanie – tak naprawdę, jak byś chciał wiedzieć, wszystkie zmienne powinno sie deklarować nawet jeżeli tego język nie wymaga (np śmietnikowaty php).
Proponuję Ci założenie stronki która będzie dotyczyła tylko kursu mootools po polsku bo w tym momencie masz rację, blog to niezbyt trafna forma na pisanie tłumaczenia dokumentacji z przykładami – system jaki byłby odpowiedni to mediawiki – http://www.mediawiki.org/wiki/Download/pl
4.
Mateusz Żeromski napisał(a):
05 lipca 2008, 17:53:26
Dopisz do prosze do mojego koma.
Zauważ że ja napisałem
Pozatym wpis ogólnie jest przepisaniem części dokumentacji http://docs.mootools.net/Core/Browser co jest bez sensu.
CZĘŚCI – nie całości, podaj jakiś konkretny przykład wyższości podanych przez Ciebie funkcjonalniści mootools nad tymi które już istnieją (tzn rozróznienie ff,opery, czy zmienna „pseudo globalna”), poza informacją o tym kto uzywa jakiej przeglądarki – wtedy napiszę że masz rację i wyjdziesz z twarzą, a tak nadal uważam że takie wpisy zachwaszczają internet i nic nie wnoszą nowego.
5.
Dziudek napisał(a):
05 lipca 2008, 18:23:32
@Mateusz Żeromski – dla Ciebie to miganie, przewijanie to mało istotne kwestie, a dla innych są to rzeczy bardzo ważne, więc proszę Cię nie mierz potrzeb wszystkich programistów swoją miarą. A co do przytoczonego plugina – to jest właśnie plugin, a nie część jQuery, więc o czym w ogóle mówimy ?
„document.* – jest to tylko alias do istniejących obiektów – równiez nic nowego nie wnosi” – trudno żeby skakał, śpiewał i mrygał, alias jest po to, żeby się można było łatwo do elementów na które wskazuje odnosi i spełnia swoją funkcję wyśmienicie…
A co do możliwości obiektu Browser – przejrzyj sobie kod MooTools i zobacz gdzie poszczególne właściwości są wykorzystywane, a jak jakieś przypadkiem nie są wykorzystywane, to nie znaczy, że są bezużyteczne – lepiej mieć trochę w zapasie, niż w czymś braki. MooTools z reguły ma długie okresy pomiędzy kolejnymi wydaniami zatem na to pół roku obiekt Browser powinien wystarczyć wraz ze swoimi możliwościami – a nikt nie powiedział, że Fx3 nie ma jakichś dziwnych zachowań, które poprzez odpowiednią detekcję trzeba będzie wykluczyć.
Mam po prostu wrażenie, że szukasz dziury w całym, ale daruj sobie – jak Ci się mój kurs MooTools nie podoba to poszukaj sobie innych źródeł – nikt mi łaski nie robi, że to czyta. A ja dalej będę pisał mój kurs zgodnie z układem MooTools i nie będę pomijał żadnych aspektów tego frameworka, bo po kilkuset napisanych skryptach wiem, że te drobiazgi i wydawałoby się zbędne dodatki jakie oferuje MooTools okazywały się bardzo przydatne, a nieraz niezbędne do sensownego rozwiązania problemu…
A co do formy kursu – do tej pory wszystkim forma pasowała, dopóki nie pojawiłeś się Ty… Ja formy kursu nie zmienię, bo ona mi odpowiada…
EOT
6.
Mateusz Żeromski napisał(a):
05 lipca 2008, 22:01:49
Dziudek – nie obrażaj się tylko wdaj się w dyskusję, może i się czepiam, ale przeczytaj mój pierwszy komentarz, podaj troche przykładów praktycznych, piszesz o różnych interpretacjach js, to podaj przykłady, o to mi chodziło bo jestem ciekaw – bo nie znam sytuacji aby te javascript inaczej działały pod ie i ff, (wiadomo czasem jest problem ze zmiennymi – ale je trzeba deklarować).
Później mnie uświadomiłeś że istnieje „jakas” różnica miedzy ff2 i ff3 (i dlatego nawet powstały sposoby rozróżniania tych przeglądarek) – tutaj również podaj przykład bo ja nie znam.
Jestem pewien w 100%, że nie uda Ci się znaleźć przykładów, napisz że nowe funkcjonalności są tylko teoretyczne (czytaj: akademickie) co uzmysłowi mi że jednak niczego nowego się nie dowiem drążąc ten temat z Tobą (ale w sumie napisaleś setki skryptów powinieneś móc mnie olśnić i bez problemu podać przykład który udowodni Twoją wiedzę i umiejętności).
7.
Dziudek napisał(a):
06 lipca 2008, 13:56:59
@Mateusz Żeromski: piszesz w JS i stwierdzasz: „bo nie znam sytuacji aby te javascript inaczej działały pod ie i ff, (wiadomo czasem jest problem ze zmiennymi – ale je trzeba deklarować)” ?
Rozróżnianie wszystkich rodzajów przeglądarek to sprawa kluczowa chociażby w wypadku zdarzenia DOMContentLoaded – w IE stosuje się dość brutalny hack z document.write, w Fx i Operze zdarzenie to występuje natywnie, a w Safar/Konqueror document.readyState – bez rozróżniania przeglądarki ani rusz.
Rozróżnanie IE6 i IE7 przydaje się by włączyć w tym pierwszym cache dla obrazków tła (poprzez window.execCommand). O przezroczystości PNG nie wspomnę.
Co do Firefoksa 2 i 3, bo widzę te przeglądarki leżą Ci najbardziej na sercu – polecam lekturę
Są tam wymienione nowości obsługiwane przez Firefoksa 3. Do tego czasem może się zdarzyć, że Firefoks 2 inaczej renderuje stronę niż Firefoks 3 – dzięki możliwości rozróżnienia tych przeglądarek możemy zlikwidować problemy. Na razie być może takich problemów nie stwierdzono, ale to raczej kwestia czasu, by zaszły różnice.
Co do Opery 9.2x i 9.5 – jest spory problem ze zmiennymi globalnymi 9.2x – po prostu skrypty wewnątrz pliku nie widziały zmiennych globalnych deklarowanych w kodzie strony.
Po więcej przykładów polecam po prostu jak wspominałem – przejrzeć kod MooTools chociażby i zobaczyć gdzie jakie właściwości są wykorzystywane.
8.
Mateusz Żeromski napisał(a):
06 lipca 2008, 16:46:56
A widzisz i tutaj mnie zadowoliłeś bo napisałeś coś o co mi chodziło, jednak nie zwiększyło mojej wiedzy :(. Jak piszę produkcyjny JS, to zawsze obiektowo z wykorzystaniem jqeury i znikają wszystkie problemy z DOMContentLoaded, a oddzielając js od html znika problem z operą i zmiennymi, więc tej komplikacji nigdy nie udało mi się odkryć.
Ogólnie mam takie podejście że wolę korzystać z gotowych rozwiązań i nie zaglądać do środka póki wszystko działa.
W każdym razie dzięki i pzdr, i nie unoś się z powodu takich błachych spraw bo nie warto :)
9.
Dziudek napisał(a):
06 lipca 2008, 17:06:32
@Mateusz Żeromski – przepraszam, że trochę mnie momentami poniosło, ale po prostu wczoraj i dziś jeszcze trochę, byłem dość wyczulony na wszelkie uwagi w kierunku tego co robię i po prostu pewne teksty mogły na mnie zadziałać jak czerwona płachta na byka ;)
Co do kursu – niestety ale pierwsze kilka-kilkanaście wpisów muszę poświęcić rzeczom, które może nie są porywające, ale trzeba omówić by kurs jako całość trzymał się kupy. Wiem, że omawianie niektórych spraw może być nużące, ale trzeba to przeboleć by móc później zająć się ciekawymi zagadnieniami jak manipulacje DOM, AJAX itp. ;)
10.
Piter2k1 napisał(a):
04 sierpnia 2009, 21:40:59
O co chodzi z przezroczystością? Wiem że IE6 nie obsługuję poprawnie PNG. Czy można coś z tym zrobić poza hackami typu ActiveX dostępnymi w internecie?
Pozdrawiam!
11.
Dziudek napisał(a):
04 sierpnia 2009, 21:43:02
W IE6 można poprawić problemy z przezroczystością np. poprzez filtry w CSS. IE6 nie obsługuje domyślnie w ogóle żadnej przezroczystości dla PNG.
Dodaj komentarz: