W czwartek dostałem nauczkę od życia- zbytnio zaufałem technologii.

Sytuacja zwykła w codziennym życiu- jedziesz gdzieś samochodem, nie pamiętasz dokładnie mapy (a wersji papierowej ze sobą nie masz) więc podczas jazdy autem odpalasz aplikację do nawigacji. Tak i w tym wypadku miało być… ale nie było.

Okazało się, że w moim telefonie jest uszkodzony GPS- nie pokazywało mojej pozycji na mapie. Jednocześnie padło przesyłanie danych komórkowych, więc nie miałem dostępu do internetu.

Do miejsca przeznaczenia dojechałem. Wyjechałem mając 40 minut zapasu, dojechałem z 40-toma minutami opóźnienia. Prawo Murphy’ego w pełnym wydaniu.

Oczywiście popełniłem dwa błędy, które są oczywiste i których już więcej nie popełnię- nie sprawdziłem dokładnie mapy, a także zaufałem jakiejś aplikacji, nie biorąc poprawki na to, że coś może pójść nie tak.

I sama ta sytuacja nie jest związana z frontendem (nie licząc designu aplikacji do nawigowania), jednak analogia istnieje.
Nie sprawdziłem dokładnie mapy- następnym razem mogę nie zgłębić odpowiednio danego tematu w dziedzinie programowanie.

Nauczka na przyszłość- upewnić się, że wszystko przemyśleliśmy, upewnić się że mamy rozwiązanie.

Druga sprawa to zawodność technologii- trzeba zawsze zakładać czynnik zewnętrzny, który przeszkodzi nam w zrealizowaniu celu. Może to być na frontendzie wiele rzeczy- stara przeglądarka, słaba przepustowość łącza, wyłączony Javascript, używanie zewnętrznych wtyczek blokujących zawartość, a czasem jest to sam czynnik ludzki- osoba niepełnosprawna, osoba mniej orientująca się w IT czy obcokrajowiec.

Na takie przypadki trzeba się przygotować.i postaram się może opisać kilka przypadków gdzie warto się mieć na baczności, oczywiście głównie na frontendzie


Pierwszym przykładem jest stosowanie pokazywania i wygaszania elementów z użyciem Javascript np. poprzez wykorzystanie metod fadeIn() i fadeOut() przy użyciu biblioteki jQuery. Przyjmijmy, że mamy dwa przyciski- jeden jest ukryty (przypiszę mu klasę o nazwie hidden-button), drugi z kolei powoduje jego pojawianie się (temu damy klasę trigger-button):

<button type="button" class="trigger-button">Pokaż drugi button</button>
<button type="button" class="hidden-button">Ukryty button</button>

W normalnej wersji dodalibyśmy styl CSS do ukrycia buttona:

.hidden-button{
	display:none;
}

do tego użyjmy jQuery, aby po kliknięciu jednego z tych buttonów drugi się pokazywał:

$(".trigger-button").click(function(){
	$(".hidden-button").fadeIn();
});

Wszystko fajnie- mamy to co chcemy. Co jednak w przypadku gdy ktoś ma wyłączoną obsługę Javascript w przeglądarce? Wczyta się jedynie kod CSS, zaś po kliknięciu buttona drugi się nie pojawi.

Lepszym zatem wyjściem byłoby pozostawienie widocznego przycisku w CSS, ale ukrycie go z pomocą Javascript- wtedy ten kto ma włączoną obsługę Javascript skorzysta z funkcjonalności, zaś ten który ma ta obsługę wyłączoną będzie miał widoczny element- w obu przypadkach użytkownik otrzymuje funkcjonalność z której może korzystać w równym stopniu:

$(".hidden-button").fadeOut();
$(".trigger-button").click(function(){
	$(".hidden-button").fadeIn();
});

Podobnie można potraktować np. okienko modalne- umieszczamy je na dole strony przykładowo, dodajemy mu identyfikator. Elementem wywołującym je będzie link, którego adres prowadzi do modalnego okienka:

<a class="modal-link" href="#modal1">Pokaż okienko modalne numer 1</a>
<a class="modal-link" href="#modal2">Pokaż okienko modalne numer 2</a>
<a class="modal-link" href="#modal3">Pokaż okienko modalne numer 3</a>
<main>
	tu będzie główna treść
</main>
<aside id="modal1" class="modal-box">modalne okienko</aside>
<aside id="modal2" class="modal-box">modalne okienko</aside>
<aside id="modal3" class="modal-box">modalne okienko</aside>
<script>
	$(document).ready(function() {
		$(".modal-box").fadeOut();
		$(".modal-link").click(function(event){
			event.preventDefault();
			var modal_id = $(this).attr("href");
			$(modal_id).fadeIn();
		});
	});
</script>

Jak widać powyżej- mamy kilka okienek modalnych oraz kilka odnośników do każdego z nich. Stworzyłem więc szybki skrypt, który najpierw je ukrywa z użyciem metody fadeOut() z biblioteki jQuery (z którą uwielbiam pracować, bo znacznie skraca czas tworzenia wielu funkcjonalności), następnie po kliknięciu konkretnego linku jego domyślne działanie (czyli przejście do adresu podanego w atrybucie href) jest zastopowane, następnie tworzona jest zmienna o nazwie modal_id, która pobiera wartość atrybutu href (czyli adres linku, a tym samym identyfikator konkretnego okienka modalnego), a następnie wykonuje metodę fadeIn() dla identyfikatora, którego nazwa zapisana jest w tej zmiennej.

W ten sposób mamy funkcjonalność dla osoby posiadającej włączoną funkcję obsługi Javascript w przeglądarce. Gdy nie ma ona tej obsługi włączonej to następuje domyślna akcja po kliknięciu linku- po prostu przejdziemy do miejsca w którym nasze konkretne okienko modalne jest.


Innym przykładem może być nie tylko zapewnianie wsparcia, ale też oszczędzenie komuś tego co mu nie zadziała. Przykładem będzie tutaj przycisk powrotu na górę strony.

Zanim przejdę do kodu przeanalizujmy ten przypadek. Chcę by ten przycisk powodował przejście na górę strony po kliknięciu i chcę by zrobił to płynnie. Chcę też by pojawiał się dopiero gdy zjadę jakieś 50px w dół strony i znikał gdy jestem na górze strony lub powyżej tej granicy wytyczonej przez 50px. Dobrze by to była płynna animacja pojawiania się i znikania elementu. OK, mogę napisać HTML dla tego elementu w dokumencie strony, ale co z osobami, które mają wyłączony Javascript? W tym wypadku mogę dać regułę CSS z display:none. Jednak źle się z tym będę czuł- to ukrycie niedziałającego elementu, coś jak przykrycie dziury w ścianie obrazem- niby się sprawdza, ale niesmak pozostaje, a dziura nadal tam jest szyderczo się uśmiechając…

Może zatem lepiej będzie nie ograniczać tej funkcjonalności, a po prostu nie tworzyć jej na urządzeniu które jej nie obsłuży? Czyli tworzyć element dynamicznie, w zależności od potrzeby? No to bum:

$(document).ready(function() {
	$(function () {
		var scrollDiv = document.createElement("div");
		$(scrollDiv).attr("id", "toTop").html("powrót na górę").appendTo("body");
		$("#toTop").fadeOut;
		$(window).scroll(function () {
			if ($(this).scrollTop() > 50) {
				$("#toTop").fadeIn();
			} else {
				$("#toTop").fadeOut()
			}
		});
		$("#toTop").click(function () {
			$("body,html").animate({	
				scrollTop: 0
			},
			800);
		});
	});
});

Gdy strona jest już załadowana wykonywana jest funkcja, w której zostanie stworzony element div, następnie dorzucamy mu identyfikator toTop, umieścimy w nim jako zawartość odpowiedni napis, a całość wrzucimy do elementu body. Ten div wygaszamy z pomocą metody fadeOut().

Następnie podczas scrollowania witryny sprawdzamy naszą odległość od góry naszej strony i jeśli zescrollowaliśmy w dół powyżej 50px to pokazujemy nasz element za pomocą metody fadeIn(), w innym zaś przypadku następuje jej ponowne wygaszenie za pomocą metody fadeOut().
Ostatnie co chcemy to by po kliknięciu naszego elementu płynnie nas przenosiło do góry strony- animuję zatem element body i html nakazując powrót do góry w czasie 800 milisekund.

Działa przy włączonym Javascript, a przy wyłączonym elementu niepotrzebnego nie ma.
Oczywiście lepiej byłoby zapewnić funkcjonalność i też dla tych z wyłączoną obsługą Javascript np. umieszczając na górze kotwicę, do której nasz toTop by się odwoływał na tej samej zasadzie jak przykład z okienkami modalnymi- to dam już Wam samym do przećwiczenia ;)


Wspominałem o przeglądarkach nieobsługujących Javascript, jednak większość z Was zada pytanie "jaki to promil użytkowników odwiedzających stronę?" i faktycznie- takich internautów długo można by szukać (choć np. korzystając z TOR’a większość osób ma wyłączony Javascript by być jeszcze mniej możliwym do namierzenia). Jest jednak całkiem spora rzesza osób korzystających ze starych przeglądarek, które nie znają czegoś takiego jako HTML5- użycie znacznika <main> czy <aside> spowoduje tylko chaos bo przeglądarka taka nie zna składni HTML5 i nie wie jak się zachować. Z pomocą przychodzą nam jednak CSS i Javascript.

W samym CSS możemy dodać regułę:

header, section, footer, aside, nav, main, article, figure {
	display: block;
}

dzięki niej przeglądarka wie, że element taki ma się zachowywać jak element blokowy (czyli jak np. div). Jednak Internet Explorer 8 oraz wcześniejsze wersje nie pozwala na stylizację nieznanych elementów, więc powyższy trick nie zadziała.
Z pomocą przyjdzie nam jednak skrypt napisany przez pewnego Holendra … Sjoerd Visscher napisał skrypt Javascript o nazwie HTML5 Shiv, dzięki któremu HTML5 odpalimy nawet na Internet Explorer 6, Safari 4 czy Mozilla Firefox 3:

<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>

Możemy też zaoszczędzić trochę naszych użytkowników i tym oto trickiem spowodować by ten skrypt wgrywał się tylko użytkownikom Internet Explorer poniżej wersji 9:

<!--[if lt IE 9]>
	<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<![endif]-->

Przykładów można mnożyć w nieskończoność- animacje, CSS3, flexbox, grid, urządzenie, orientacja urządzenia itd. itd. itd. Warto jednak zapamiętać to, żeby nie zawierzać tylko jednemu rozwiązaniu, nie pokładać nadziei w tym że wszystko będzie super i nic się nie zepsuje lub nie wystąpi żadna nie sprzyjająca okoliczność.

Zawsze przemyśl co może pójść nie tak, zawsze miej asa w rękawie na wypadek gdyby coś poszło nie tak. Bo prawo Murphy’ego jest wredne, ale cierpliwe i tylko czeka by komuś dołożyć...