CASE STUDY: kolejność zdarzeń w JS

Wpadłam ostatnio na zagwozdkę, która prawie strąciła mnie z fotela. Zobaczymy, jak będzie z Wami!

Z grubsza opiszę, na czym polegał mój problem. Miałam na stronie inputa – wyszukiwarkę, która działała w ten sposób, że po wpisaniu do niej hasła, pojawiała się pod nią lista z wynikami wyszukiwania (powiedzmy produktami). Obok każdego produktu pojawiał się też dedykowany przycisk do, powiedzmy, dodania do koszyka. Proste? Proste.

https://balsamiq.com

Jednak sama metoda dodająca produkt do koszyka nie działała. Nie wywoływała się. Dlaczego? Aplikacja miała ważne założenie – w odpowiedzi na akcję onblur() na inpucie powinna wywoływać się metoda czyszcząca wszelakie komunikaty walidacyjne i… chowająca listę wyszukanych produktów. Nadążacie? Klikając na przycisk “dodaj do koszyka” wywoływałam jednocześnie akcję onblur() chowającą owy nieszczęsny przycisk. I wszystko. Się. Sypało.

Pewnie rozumiecie, że wszelakie rady zmieniające UI nie wchodzą w grę.

Przyznaję się bez bicia, że źle podeszłam do problemu. Nie widziałam go na początku. Aplikacja w rzeczywistości była czymś dużo większym od pojedynczej wyszukiwarki. Nie szukałam źródła problemu, którego nie mogłam odnaleźć w czasie krótszym niż 10 minut. Szukałam po prostu innych sposobów osiągnięcia takiej samej funkcjonalności. Czasami taka metoda się sprawdza. Nie w tym przypadku. Tu zawsze problem sprowadzał się do jednego i tego samego źródła – czasu.

Einstein uważał, że czas jest względny tak bardzo, jak osobiste jest nasze jego postrzeganie. Facet nie poznał Javascriptu.

Źródłem problemu wywalania się aplikacji w opisanym przeze mnie przykładzie jest kolejność zdarzeń onblur() oraz onclick(). Bez dyskusji oba muszą się zadziać. Bez dyskusji nie mogą się blokować. I bez dyskusji onblur() zawsze zadzieje się szybciej niż onclick(). Oh no.

A teraz chwila dla Was. Czy wiecie, jak to ogarnąć?

/ czas na myślenie /

Dobra, powiem Wam, jak ja to zrobiłam.

Zamieniłam akcję onclick() na… onmousedown(). Bo po prostu onmousedown() dzieje się szybciej niż onblur(). Generalnie możemy zakładać taką kolejność: onmousedown() -> onblur() -> onmouseup() -> onclick(). Ale ciężko tu mówić cokolwiek więcej o kolejności zdarzeń wszelakich. Implementacja takich rzeczy jest mocno zależna od przeglądarki.

Co z RWD? Akurat mój projekt korzysta z Reacta, który udostępnia zdarzenie onTouchStart. A więc po problemie. Czysty JS również posiada ontouchstart(), jednak póki co tylko, ekhm, eksperymentalnie.

Co z A11Y? Wystarczy dodać kolejne zdarzenie onkeydown(), które jest klawiaturowym odpowiednikiem myszkowego onmousedown(). Czytniki to ogarną.


Jeśli macie inne sposoby na rozwiązanie problemu kolejności onclika oraz onblura, jeśli kiedykolwiek spotkaliście się z podobnym problemem wyścigu zdarzeń – koniecznie piszcie w komentarzach! Podzielmy się naszym doświadczeniem ze światem!

Artykuły, które mogą Ci się spodobać...

Wpisz hasło, którego szukasz i naciśnij ENTER, aby je wyszukać. Naciśnij ESC, aby anulować.

Dawaj na górę