Artykuł

picjumbo.com picjumbo.com
mar 07 2014
0

Nie jesteś skazany na jQuery! Poznaj nowy, lepszy JavaScript

Gdy blisko 5 lat temu zacząłem używać jQuery w jednym z moich projektów w pracy, poczułem jakbym dostał mannę z nieba. W moje rączki trafiła bowiem biblioteka, która rozwiązywała większość problemów z kompatybilnością JavaScriptu, a także w wymierny sposób skracała tworzony kod - jednym słowem rewelacja!

Internet się jednak zmienia i dziś JavaScript wygląda już zupełnie inaczej. Jest to język bardziej dojrzały, który zyskał nowe możliwości oraz przede wszystkim lepsze wsparcie w przeglądarkach. Odsetek starych - złych IE jest już naprawdę niski i wielu przypadkach można porzucić wsparcie dla tych aplikacji, co też uczyniło nawet samo jQuery w linii 2.x. Czas w końcu ruszyć do przodu!

Niestety wielu programistów wciąż żyje w złotych czasach jQuery i wykorzystuje tą bibliotekę do najprostszych nawet czynności. Czas skończyć z tym podejściem, przyszła najwyższa pora by zaprezentować światu nowy, lepszy JavaScript!

Dlaczego jQuery nie zawsze jest dobrym rozwiązaniem?

jQuery jest dużą i ciężką biblioteką (ponad 80 KB dla wersji 2.1.0 oraz blisko 100 KB dla wersji 1.11.0) i nawet mimo wycięcia wsparcia dla IE6-8 w linii 2.x, wciąż musimy pobrać/załadować blisko 80 KB kodu. Dlatego często warto się zastanowić czy kilka - kilkanaście kilobajtów kodu prostej aplikacji jest warte pobierania całego jQuery. Oczywiście jeśli jesteś doświadczonym deweloperem, prawdopodobnie będzie w stanie zbudować swój własny build w oparciu o kod biblioteki znajdujący się na GitHubie. Zanim jednak radośnie udasz się pod wskazany przed chwilą link, zauroczony myślą że jQuery może być mniejsze, dobrze się zastanów czy tak naprawdę potrzebujesz jeszcze tej biblioteki w aktualnie prowadzonym projekcie.

Tak jak wspomniałem we wstępie, JavaScript nie jest już takim językiem jakim jeszcze był 5 lat temu. Pojawiło się tutaj sporo nowych funkcji m.in. takich, które są odpowiedzialne za selekcjonowanie elementów, czyli jedno z tych zadań z których najbardziej zasłynęło jQuery. Poprawiono również obsługę zdarzeń oraz dodano wiele nowych elementów związanych z różnymi rozszerzeniami HTML5, takimi jaki localStorage, czy Canvas.

JavaScript, a starsze przeglądarki

Żeby dobrze zacząć z nowym JavaScriptem, trzeba dobrze znać target swojej witryny i wiedzieć z jakich przeglądarek korzystają nasi użytkownicy. W moim przypadku tylko niecałe 8% odwiedzających zagląda tutaj przy użyciu IE. 1/5 tej grupy korzysta z wersji przeglądarki starszej niż 9 (IE 6-8). Sumarycznie rzecz biorąc tylko około 2% wszystkich użytkowników, wchodzi na mój blog przy pomocy problematycznej przeglądarki. Może zabrzmi to trochę brutalnie, ale myślę że ten odsetek mogę pominąć.

Oczywiście jeśli prowadzisz komercyjną stronę, na której liczy się każdy użytkownik, wsparcie dla wszystkich przeglądarek jest bardziej niż pożądane. W takim przypadku wciąż możesz używać linii jQuery 1.x, bądź też pisać warunkowy kod w JS. W pozostałych przypadkach, zachęcam do wykorzystania poniższych konstrukcji;-)

Lepsze selektory

Kilka akapitów wcześniej wspominałem o nowych możliwościach pobierania elementów w JavaScripcie, a teraz chciałbym powiedzieć kilka słów więcej na ten temat. W starym JS mieliśmy funkcje getElementById, getElementsByTagName oraz getElementsByClassName, które pozwalały kolejno na pobieranie elementów o określonym id (tylko jeden element), o określonej nazwie tagu oraz o określonej klasie. Teraz cały ten proces ulepszono poprzez dodanie funkcji querySelector oraz querySelectorAll, które można wywołać na całym dokumencie jak i konkretnym elemencie.

Pierwsza z nich pozwala na pobranie pojedynczego elementu (pierwszy dopasowany), druga natomiast umożliwia pobranie tablicy wszystkich dopasowanych elementów. W praktyce bardzo zbliżyliśmy się więc do wzorca znanego z biblioteki jQuery. Spójrzcie na poniższy przykład, by zobaczyć jak to wszystko działa w praktyce:

/* Tak robiliśmy to kiedyś */
var element = document.getElementById("#myid");
var elementsByClassName = document.getElementsByClassName("myclass");
var elementsByTagName = document.getElementsByTagName("p");

/* Tak robiliśmy to z jQuery */
var element = $("#myid");
var elementsByClassName = $(".myclass");
var elementsByTagName = $("p");

/* Tak możemy to robić dziś */
var element = document.querySelector("#myid");
var elementsByClassName = document.querySelectorAll(".myclass");
var elementsByTagName = document.querySelectorAll("p");

Jak widać, sporo się zmieniło, a sama składnia bardziej przypomina rozwiązanie znane z jQuery. Oczywiście jest to wciąż zapis dłuższy niż w przypadku naszej ulubionej biblioteki, ale jest też on dużo bardziej logiczny aniżeli wcześniej znane konstrukcje z JavaScriptu.

Nowe funkcje pozwalają na znacznie więcej, a powyższy listing to tylko namiastka możliwości wprowadzonych funkcji. Spójrzcie na bardziej wyrafinowane przykłady:

/* Pobieranie różnych elementów do wspólnej tablicy */
var elements = document.querySelectorAll("#myid,#myotherid");

/* Pobranie wszystkich pasujących elementów p 
   leżących poniżej elementu o id #myid */
var elements = document.querySelectorAll("#myid p");

/* Pobranie wszystkich pasujących elementów p 
   leżących bezpośrednio poniżej elementu o id #myid */
var elements = document.querySelectorAll("#myid > p");

/* Pobranie wszystkich elementów input typu text */
var elements = document.querySelectorAll("input[type='text']");

Jak widać opcji jest całkiem sporo i brakuje mi chyba zasadniczo tylko obsługi pseudoklas oraz XPath. Na szczęście te pierwsze można w większości przypadków zastąpić selektorami opartymi o atrybuty (patrz jeden z przykładów wyżej), a te drugie odpowiednio skonfigurowanymi zapytaniami.

Lepsza obsługa zdarzeń

Oprócz selektorów, osobiście bardzo często korzystam w jQuery z funkcjonalności bindowania zdarzeń. Również w tej materii zaszło sporo zmian w samym JS - przede wszystkim ujednolicono cały mechanizm w taki sposób, by był on spójny dla różnych zdarzeń.

Dotychczas pisząc kod zdarzeń w JavaScripcie, bardzo często podpinaliśmy konkretne funkcje zdarzeń (onclick, onmouseover, onmouseout itp.) do wybranego obiektu. Obecnie lepiej jest w tym celu zaprzęgnąć metodę addEventListener, która binduje zdarzenie do wskazanego przez nas elementu.

Nowa metoda ma kilka istotnych zalet. Przede wszystkim jej użycie zapobiega nadpisaniu istniejących zdarzeń dla wybranego elementu, pozwala na pisanie ładniejszego kodu oraz na obsługę propagacji zdarzeń (przechwycenia określonego zdarzenia zanim zostanie złapane przez jakiś element, której znajduje się niżej w drzewie elementów).

Spójrzmy na przykładowe zastosowanie tej metody:

var element = document.querySelector("#myotherid");
element.addEventListener("click", function(){
	alert(this.textContent);
}, false);

Na wstępie pobieramy interesujący nas element za pomocą poznanej wcześniej funkcji querySelector. W kolejnym kroku podpinamy zdarzenie wykorzystując nową metodę (2-4). Warto tutaj zwrócić uwagę na kilka rzeczy:

  • Metoda przyjmuje trzy argumenty: nazwę zdarzenia, funkcję zwrotną oraz flagę która determinuje czy zdarzenie ma być propagowane w dół, czy też nie
  • Nazwę zdarzenia podajemy już bez przedrostka on (click, mouseover, mouseout itd.)
  • Funkcja zwrotna może być anonimowa, bądź też możemy skorzystać z istniejącej gdzieś indziej w naszym kodzie konstrukcji (przekazać jej nazwę)

Cały mechanizm działa bardzo dobrze i efektywnie.

Podsumowanie

Motywem przewodnim tego tekstu było przekonanie Was, że w wielu przypadkach jQuery można odstawić do kąta i swobodnie korzystać z JavaScriptu. Dzięki nowym funkcjom możemy komfortowo pobierać interesujące nas elementy z drzewa DOM, obsługiwać zdarzenia i robić sporo innych interesujących rzeczy. Oczywiście jQuery to wciąż bogate repozytorium wtyczek na każdą okazję, więc w wielu przypadkach zgodnie z zasadą nie wymyślaj koła od nowa lepiej użyć coś co już istnieje, ale jeśli tylko tworzycie stronę która nie wymaga żadnych dodatkowych wtyczek, to wydaje mi się, że mimo wszystko warto rzucić okiem na nowy i lepszy JavaScript.

Linki

Data ostatniej modyfikacji: 08.03.2014, 10:40.

Podoba Ci się ten wpis? Powiedz o tym innym!

Send to Kindle

Komentarze

blog comments powered by Disqus