Temat responsywnych stron internetowych jest obecnie „na fali” – wszędzie się o tym mówi, a firmy coraz chętniej inwestują w responsywne strony WWW. Nic dziwnego, obserwując bowiem zagraniczne rynki można wyciągnąć prosty wniosek – opłaca się mieć mobilną stronę.
Tak więc powrócę jeszcze na chwilę do Media Queries, który jest pomocny przy implementowaniu Responsive Web Design. Tym razem jednak zajmiemy się tematem od dupy strony, czyli obsługą Media Queires z poziomu języka JavaScript :-)
Jeśli nie miałeś jeszcze styczności z Media Queries, sprawdź w pierwszej kolejności wpis objaśniający czym jest Media Queries dla CSS3. Jako ciekawostkę możesz potraktować również wpis o nadchodzącym, niestabilnym jeszcze standardzie – Media Queries dla CSS4.
CSSOM View
Natywne wsparcie dla Media Queires z poziomu JavaScriptu pojawiło się w specyfikacji CSS Object Model (CSSOM) View Module. Ze specyfikacji możemy się dowiedzieć o nowej metodzie matchMedia(), dostępnej z poziomu obiektu window. Zadaniem tej metody jest sprawdzenie warunku (znanego z CSS Media Queires) z obecnym widokiem strony.
Użycie może wyglądać następująco:
1 | var match = window.matchMedia("(orientation:landscape)"); |
Jak więc widzisz, do metody matchMedia wystarczy przekazać ciąg tekstowy na wzór tego, którego już znasz z CSS. W odpowiedzi, do zmiennej match zostanie przypisany obiekt MediaQueryList z dwoma właściwościami:
- media – przekazuje z powrotem regułkę Media Queries użytą jako argument metody matchMedia,
- matches – zwraca true lub false, w zależności od wyniku porównania reguły z obecnym widokiem strony.
Tak więc po wykonaniu powyższego kodu, w zmiennej match otrzymamy następującą odpowiedź:
1 2 3 4 | { "media": "(orientation:landscape)", "matches": false } |
W ten sposób możemy oczywiście sprawdzać czy jest spełniony nasz warunek i w zależności od rezultatu odpowiednio zareagować:
1 2 3 4 5 | if (window.matchMedia("(orientation:landscape)").matches) { // Do something... } else { // Do something else... } |
Taki warunek oczywiście na niewiele się zdaje, bowiem nie wykona się w momencie zmiany widoku strony, np. przy zmianie orientacji tabletu. Niemniej jednak i taka sytuacja została przewidziana i odpowiednio rozwiązana. W tym celu dostaliśmy możliwość nasłuchiwania zdarzeń na zwróconym obiekcie.
Wróćmy więc do pierwszego przykładu:
1 | var match = window.matchMedia("(orientation:landscape)"); |
Nie bez powodu do zmiennej match zostaje przekazany obiekt. Poza wcześniej omówionymi właściwościami udostępnia od także dwie metody:
- addListener – umożliwia podpięcie funkcji nasłuchujących zmiany w widoku strony,
- removeListener – usuwa funkcje nasłuchujące.
Przykładowe użycie funkcji nasłuchującej:
1 2 3 4 5 6 7 8 9 10 11 | var handleMediaChange = function(mediaQueryList) { if (mediaQueryList.matches) { // The browser window is at least 768px wide match.removeListener(handleMediaChange); } else { // The browser window is less than 768px wide } } var match = window.matchMedia("(min-width: 768px)"); match.addListener(handleMediaChange); |
W powyższym kodzie dodaliśmy funkcję nasłuchującą zmiany pod kątem regułek przekazanych w window.matchMedia. W momencie zmiany wielkości okna powyżej (lub poniżej) 768 pikseli zostaje wywoływana funkcja handleMediaChange. Kiedy warunek się spełni (okno ma ponad 768px szerokości), usuwamy naszą funkcję nasłuchującą.
Taki przypadek może zostać użyty do np. „płynnego” wczytania zdjęć na stronę (ukrywasz wszystkie obrazki, informujesz o ich wczytywaniu, a po zakończeniu odkrywasz ukryte tagi).
Kiedy, jak i po co?
Teoretycznie CSS i JavaScript to dwa różne światy, w praktyce jednak czasem muszą się przeplatać – choćby dla zaoszczędzenia transferu czy ulepszenia interaktywności bądź też użyteczności strony. Tak jak wyżej wskazałem, window.matchMedia może posłużyć do np. warunkowego wczytywania obrazków, czcionek czy innych zasobów (lazy loading).
Czasem też z poziomu JavaScriptu musimy wykonać inne operacje na dokumencie, a skoro mamy różne arkusze stylów to musimy różnie reagować. Nie trzeba zatem obserwować window.resize, window.orientationchange czy innych zdarzeń – wystarczy śledzić same zmiany dla ustawionego widoku strony.
window.matchMedia jest obecnie obsługiwany przez wszystkie nowoczesne przeglądarki, także mobilne. Jak każdy wie, do takich przeglądarek nie zaliczają się IE9 i niższe, jak również Opera Mini. Dla nich jednak można znaleźć polyfill.