Podstawy#

Powiadomienia#

Powiadomienie (notification) stanowi ogólna koncepcję, która pozwala wyświetlić komunikat dla końcowego użytkownika poza kontekstem strony internetowej. Mechanizm przypomina analogiczne rozwiązania z desktopowych lub mobilnych aplikacji. Powiadomienie najczęściej wykorzystywane jest do informowania o nadejściu nowej wiadomości e-mail. Całość opisywana jest w dwóch równorzędnych specyfikacjach:

Specyfikacje nie określają dokładnego sposobu w jaki aplikacje klienckie powinny wyświetlać powiadomienia; najlepsza prezentacja zależy od urządzenia, na którym uruchomiono aplikację kliencką. Kiedy specyfikacje odnoszą się do wyświetlania powiadomień na "pulpicie", to na ogół dotyczy to jakiegoś statycznego obszaru wyświetlania poza obrębem strony internetowej, ale może przyjmować różne formy, włącznie z:

Specyfikacje zostały zaprojektowane tak, aby były zgodne z istniejącymi platformami powiadomień w jak największym zakresie, ale z jednoczesnym zachowaniem niezależności od platformy. Ponieważ większość platform nie oferuje tej samej funkcjonalności, to specyfikacje wskazują, które zdarzenia są gwarantowane a które nie. W szczególności dotyczy to samej budowy powiadomień, gdzie dozwolona jest jedynie zawartość tekstowa i ikony.

Generalnie model zdarzeń dla powiadomień jest najlepszy z możliwych; o ile sam obiekt Notification obsługuje zdarzenie typu click i aplikacje mogą zwiększać swoją funkcjonalność poprzez nasłuchiwanie tego zdarzenia, to nigdy nie powinny polegać wyłącznie na jego przechwyceniu, gdyż podstawowa platforma powiadomień może nie przewidywać takiej możliwości.

Tworzenie i obsługa powiadomień#

Z powiadomieniami związanych jest kilka kluczowych pojęć i algorytmów. Dokładna analiza materiału jest jak najbardziej wskazana, ale dla osób mniej obytych z algorytmami opiszę podstawy całego mechanizmu.

Powiadomienie utożsamiamy z jakąś informacją umieszczaną w pewnym miejscu ekranu urządzenia, poza kontekstem strony i najczęściej poza całą przeglądarką internetową. Wiadomość taka może być odbierana nawet wtedy, gdy użytkownik zminimalizuje program.

Na chwilę obecną jedynie przeglądarki Chrome i Firefox wspierają mechanizm powiadomień, ale Chrome robi to zdecydowanie lepiej. Oto kilka istotnych cech w każdej z przeglądarek:

Chrome #

Przeglądarka w danej chwili wyświetla tylko trzy powiadomienia, które będą stale widoczne do momentu, kiedy użytkownik ich nie zamknie lub aktywuje. Reszta powiadomień (oczekujących w kolejce do wyświetlenia) trafia do specjalnego kontenera dla powiadomień, który jest reprezentowany przez pojawiający się w zasobniku systemowym symbol dzwonka (okolice zegarka). Zamknięcie lub aktywacja któregoś z aktualnie wyświetlanych powiadomień powoduje, że zwalnia się miejsce dla wyświetlenia kolejnego powiadomienia z oczekującej kolejki.

Istotne jest to, że wszystkie powiadomienia, które nie zostały zamknięte (np. symbolem "X" lub programowo metodą Notification.close()) trafiają do tego kontenera. Możemy je tam dokładnie przeanalizować i podjąć określone decyzje, np. ponownie aktywować lub usunąć. Akcje podjęte w kontenerze również wygenerują zdarzenia dla powiadomień. Sam kontener udostępnia kilka innych przydatnych opcji, np. usuwanie wszystkich powiadomień, całkowitą dezaktywację mechanizmu i kontrolę zezwoleń dla powiadomień z różnych źródeł.

Powiadomienia w przeglądarce Chrome

Rysunek. Powiadomienia w przeglądarce Chrome

Można powiedzieć, że w Chrome wszystko hula jak powinno. Implementacja jest przemyślana i bardzo wygodna z punktu widzenia zwykłego użytkownika.

Firefox #

Na dzień dzisiejszy obsługa powiadomień w tej przeglądarce wygląda jak proteza (jeśli porównamy z Chrome). Nie ma żadnego kontenera powiadomień, wszystko ląduje na ekranie użytkownika (tyle ile się zmieści, reszta oczekuje w kolejce). Co gorsza, powiadomienia są zamykane automatycznie po upływie ok. 4 sekund. Nie możemy zatem stwierdzić, czy użytkownik przeczytał stosowną informację i czy przypadkiem nie trzeba wysłać danego powiadomienia jeszcze raz.

Powiadomienia w przeglądarce Firefox

Rysunek. Powiadomienia w przeglądarce Firefox

Sama aktywacja powiadomienia (poprzez kliknięcie w jego obszarze) powoduje, że zostaje ono zamknięte, i w konsekwencji otrzymamy dwa zdarzenia typu click oraz close, co jest odmienne z zachowaniem Chrome (pominięcie zdarzenia close). Istnieją jeszcze inne błędy, jak chociażby problem z szybką generacją (np. w pętli) więcej niż jednego powiadomienia. Miejmy nadzieję, że ekipa Firefoksa upora się ze wszystkimi bolączkami w bieżącej implementacji tego ciekawego API.

Przejdźmy teraz do obsługi skryptowej. Powiadomienie będzie reprezentowane przez jeden lub większą liczbę obiektów typu Notification, z kilkoma przydatnymi właściwościami i metodami (niektóre z nich są statyczne i pochodzą bezpośrednio z interfejsu Notification).

Obiekt reprezentujący powiadomienie tworzymy za pomocą konstruktora new Notification(), choć w specyficznych sytuacjach również przy użyciu metody Notification.getClones(). Utworzenie obiektu nie stanowi problemu i jest dozwolone w każdym momencie, ale żeby odpowiadające powiadomienie zostało wyświetlone, to najpierw należy sprawdzić, czy użytkownik zezwolił na wyświetlanie powiadomień. Aktualny stan zezwolenia odczytamy ze statycznej właściwości Notification.permission. Jeśli użytkownik do tej pory nie podjął żadnej decyzji (tzn. wartością zezwolenia jest "default") to za pomocą statycznej metody Notification.requestPermission() można poprosić użytkownika o pozwolenie bądź odrzucenie możliwości wyświetlania powiadomień dla naszej witryny. Przeglądarka wygeneruje stosowny pojemnik (np. dodatkowy pasek, chmurkę czy inny widżet). Podjęcie decyzji (akceptacja lub odrzucenie) powoduje, że wysyłane przez przeglądarkę zapytanie już nigdy nie będzie wyświetlane, no chyba że użytkownik samodzielnie cofnie podjętą decyzję.

Prosty przykład:

  1. L
  2. K
  3. T'
  4. T
  5. A
  6. O
  7. Z'
  8. Z
  9. #
<script>

	// Powiadomienia są obsługiwane i użytkownik nie podjął jeszcze decyzji lub zablokował ich wyświetlanie
	if (Notification && Notification.permission != "granted"){

		Notification.requestPermission(function(permit){

			// Przy blokadzie wyświetlania powiadomień zwróć wskazówkę
			if (permit == "denied"){

				document.write("Oj pozwól mi ten jeden raz. Ręcznie przestaw zezwolenia dla celów testowych.");
				document.close();

			}

		})

	}

	// Powiadomienia są obsługiwane i użytkownik zezwala na ich wyświetlanie
	if (Notification && Notification.permission == "granted"){

		new Notification("Tytuł powiadomienia", {
			body:"Ciało powiadomienia",
			icon: "http://www.crimsteam.site90.net/icon.ico"
		});

	}

</script>

Stosowanie etykiet w powiadomieniach#

Przy domyślnych ustawieniach powiadomienia generowane są niezależnie od siebie i stanowią osobne zadanie dla przeglądarki. Zachowanie to może być problematyczne, szczególnie kiedy aplikacja kliencka ma niewyrafinowaną implementację powiadomień (np. Firefox), gdzie duża liczba powiadomień generowanych przez jedną i tę samą aplikację webową może wprowadzać lekką dezorientację. Problem dotyczy sytuacji, kiedy aplikacja webowa stanowi pojedynczą instancję (tzn. działa w jednej karcie) jak i w przypadku wielu instancji (tzn. działa w wielu kartach).

Eleganckim sposobem zapanowania nad wyświetlaniem wielu niepotrzebnych powiadomień w tym samym czasie jest zastosowanie wspólnej etykiety przy tworzeniu powiadomienia. Etykieta powoduje, że oznakowane nią powiadomienia zajmują jedno wspólne miejsce na ekranie urządzenia, i jeśli jakieś nowe powiadomienie nadejdzie, to zostanie wyświetlone w miejscu poprzedniego.

Prosty przykład:

  1. L
  2. K
  3. T'
  4. T
  5. A
  6. O
  7. Z'
  8. Z
  9. #
<script>

	// Powiadomienia są obsługiwane i użytkownik nie podjął jeszcze decyzji lub zablokował ich wyświetlanie
	if (Notification && Notification.permission != "granted"){

		Notification.requestPermission(function(permit){

			// Przy blokadzie wyświetlania powiadomień zwróć wskazówkę
			if (permit == "denied"){

				document.write("Oj pozwól mi ten jeden raz. Ręcznie przestaw zezwolenia dla celów testowych.");
				document.close();

			}

		})

	}

	// Powiadomienia są obsługiwane i użytkownik zezwala na ich wyświetlanie
	if (Notification && Notification.permission == "granted"){

		for (var i = 0; i < 2; i++){

			setTimeout(function(){

				new Notification("Tytuł samodzielnego powiadomienia", {
					body:"Ciało samodzielnego powiadomienia",
					icon: "http://www.crimsteam.site90.net/icon.ico",
				});

			}, i*300);

		}

		for (; i < 6; i++){

			setTimeout(function(){

				new Notification("Tytuł wspólnego powiadomienia", {
					body:"Ciało wspólnego powiadomienia",
					icon: "http://www.crimsteam.site90.net/icon.ico",
					tag: "grupa"
				});

			}, i*300);

		}

		for (; i < 8; i++){

			setTimeout(function(){

				new Notification("Tytuł samodzielnego powiadomienia", {
					body:"Ciało samodzielnego powiadomienia",
					icon: "http://www.crimsteam.site90.net/icon.ico",
				});

			}, i*300);

		}

		for (; i < 12; i++){

			setTimeout(function(){

				new Notification("Tytuł wspólnego powiadomienia", {
					body:"Ciało wspólnego powiadomienia",
					icon: "http://www.crimsteam.site90.net/icon.ico",
					tag: "grupa"
				});

			}, i*300);

		}

	}

</script>

Warto nadmienić, że przeglądarka Firefox zachowuje pozycję wyświetlania wspólnych powiadomień (początek stanowi miejsce pojawienia się pierwszego wspólnego powiadomienia), co jedynie podkreśla, że faktycznie stosowany jest algorytm kroków zastąpienia. W Chrome wszystko odbywa się na zasadzie kasowania i dodawania, dlatego nowe powiadomienia są zawsze wyświetlane na wierzchu (na samej górze).

Zdarzenia i uchwyty zdarzeń dla powiadomień#

Specyfikacja definiuje jedynie cztery następujące uchwyty zdarzeń i odpowiadające im typy zdarzeń:

uchwyt zdarzeniatyp zdarzenia
Notification.onclickclick
Notification.onshowshow
Notification.onerrorerror
Notification.oncloseclose

Istotne jest to, że interfejs Notification dziedziczy po interfejsie EventTarget, dlatego obiekty typu Notification będą miały dostęp do standardowych poleceń dla nasłuchów zdarzeń. Możliwe jest nawet stworzenie i wysłanie do powiadomienia niezaufanego zdarzenia.

Prosty przykład:

  1. L
  2. K
  3. T'
  4. T
  5. A
  6. O
  7. Z'
  8. Z
  9. #
<script>

	// Tworzymy nowe powiadomienie
	var notification = new Notification("Tytuł powiadomienia");

	document.write(notification); // [object Notification]
	document.write("<br>");
	document.write(notification.title); // Tytuł powiadomienia

	notification.addEventListener("test", function(e){

		var data = "Interfejs: " + e
			+ "<br>" + "e.type: " + e.type
			+ "<br>" + "e.bubbles: " + e.bubbles
			+ "<br>" + "e.cancelable: " + e.cancelable
			+ "<br>" + "e.target: " + e.target
			+ "<br>" + "e.currentTarget: " + e.currentTarget
			+ "<br>" + "e.eventPhase: " + e.eventPhase + "<br><br>";

		document.write(data);
		document.close();

	}, false);

	var new_event = new Event("test", {bubbles: true, cancelable: true});

	setTimeout(function(){

		notification.dispatchEvent(new_event);

	}, 2000);

</script>

Możliwy obszar występowania powiadomień#

Interfejs Notification ma w swojej definicji Web IDL atrybut rozszerzający typu [Exposed]:

  1. L
  2. K
  3. T'
  4. T
  5. A
  6. O
  7. Z'
  8. Z
  9. #
[Exposed=Window,Worker]

Oznacza to, że wspomniany interfejs (i w konsekwencji implementujące go obiekty powiadomień) mogą występować zarówno w wątku głównym jak i wątkach roboczych przeglądarki internetowej.

Na chwilę obecną żadna przeglądarka internetowa nie eksponuje powiadomień w wątkach roboczych.

Zarządzanie zezwoleniami wyświetlania powiadomień#

Wyświetlanie powiadomień odbywa się tylko i wyłącznie za zgodą użytkownika, który musi na to zezwolić. Ma to zabezpieczyć odbiorców przed nachalnym wyświetlaniem niechcianych informacji. Minusem jest to, że zezwolenia trzeba przydzielić osobno dla każdej witryny (pod uwagę brane jest pochodzenie), kiedy witryna o to poprosi i kiedy wartością właściwości Notification.permission jest "default". Podjęta decyzja zostaje zapamiętana i późniejsze zapytania nie będą generowane.

Z praktycznego punktu widzenia mechanizm ten będzie zależny od danej przeglądarki internetowej. W Firefoksie możemy ustawić zezwolenia na stałe lub tylko dla bieżącej sesji:

Pytanie o zezwolenie wyświetlania powiadomień w przeglądarce Firefox

Rysunek. Pytanie o zezwolenie wyświetlania powiadomień w przeglądarce Firefox

W przypadku Chrome mamy mniej opcji do wyboru oraz decyzję podejmujemy na stałe:

Pytanie o zezwolenie wyświetlania powiadomień w przeglądarce Chrome

Rysunek. Pytanie o zezwolenie wyświetlania powiadomień w przeglądarce Chrome

Firefox automatycznie zezwala na wyświetlanie powiadomień (wartość "granted") dla zasobów z dysku lokalnego (protokół file://), kiedy Chrome wciąż zachowuje domyślne ustawienie ("default").

Kolejna sprawa to zarządzanie zapamiętanymi zezwoleniami, które ustawiono w sposób trwały. Jest to szczególnie istotne w przypadku testowania omawianego API, gdzie szybkie cofanie zezwoleń to podstawa. Nie będzie niespodzianką, że i tym razem wszystko zależy od stosowanego programu.

W przypadku Firefoksa klikamy prawym przyciskiem myszy na stronie, wybieramy Pokaż informacje o stronie, przechodzimy do zakładki Uprawnienia i w polu Wyświetlanie powiadomień możemy dokonać stosownych korekt:

Zarządzanie zezwoleniami wyświetlania powiadomień w przeglądarce Firefox

Rysunek. Zarządzanie zezwoleniami wyświetlania powiadomień w przeglądarce Firefox

W Chrome będzie bardzo podobnie, klikamy prawym przyciskiem myszy na stronie, wybieramy Wyświetl informacje o stronie, w zakładce Uprawnienia mamy pole Powiadomienia:, gdzie możemy dokonać stosownych korekt:

Zarządzanie zezwoleniami wyświetlania powiadomień w przeglądarce Chrome

Rysunek. Zarządzanie zezwoleniami wyświetlania powiadomień w przeglądarce Chrome

Całkowite wyczyszczenie historii przeglądania w przeglądarce Firefox usunie zapamiętane zezwolenia wyświetlania powiadomień dla wszystkich stron (sposób nie zadziała w Chrome).

Pasek społecznościowy

SPIS TREŚCI AKTUALNEJ STRONY

Podstawy (H1) Powiadomienia (H2) Tworzenie i obsługa powiadomień (H3) Stosowanie etykiet w powiadomieniach (H4) Zdarzenia i uchwyty zdarzeń dla powiadomień (H4) Możliwy obszar występowania powiadomień (H4) Zarządzanie zezwoleniami wyświetlania powiadomień (H3)