Interesujący dyngs
Zwrot deklaratywny trwa w najlepsze. Oprócz obsługi komend, ostatnio pojawiło się też Interest Invoker API (API Wyzwalacza Zainteresowania).
Zainteresowanie?
Wypada zacząć od wyjaśnienia, czym jest zainteresowanie
w tym kontekście. W oficjalnej propozycji nowego API jest to wyjaśnione mocno enigmatycznie:
[…] rather than being activated via a click on the element, this API uses a lighter-touch way for the user to “show interest” in an element without fully activating it.
[[…] zamiast aktywowania poprzez klik na elemencie, to API używa lżejszego sposobu okazania przez osobę użytkowniczą “zainteresowania” elementem bez jego pełnej aktywacji.]
Taka definicja nie wyjaśnia za dużo, ale na szczęście jest cała sekcja poświęcona różnym sposobom interakcji z urządzeniem i jak się to przekłada na zainteresowanie:
| Sposób interakcji z urządzeniem | Sposób okazywania zainteresowania | Sposób tracenia zainteresowania |
|---|---|---|
| Myszka | Najechanie kursorem myszy (hover) i przytrzymanie go na elemencie przez pewien czas | Zjechanie kursorem myszy z elementu |
| Klawiatura | Sfocusowanie elementu i pozostawienie go sfocusowanym przez pewien czas | Zabranie focusu z elementu, naciśnięcie Esc |
| Ekran dotykowy | Gest długiego naciśnięcia (long press) | Dotknięcie poza elementem |
| Pozostałe | Przeglądarka dobiera odpowiedni sposób | Przeglądarka dobiera odpowiedni sposób |
Innymi słowy: “okazywanie zainteresowania” to ulepszony hover. Działa bowiem nie tylko z myszką, dostosowuje się także do innych urządzeń wejściowych i sposobów interakcji z urządzeniem.
Nowe API
Dygresja
Dla uproszczenia, będę opisywał API z perspektywy osoby korzystającej z myszy. Niemniej wszędzie tam, gdzie pojawia się najechanie myszą, tak naprawdę chodzi o wszystkie wymienione wyżej sposoby interakcji.
Tooltipy
Nowe API jest podobne do istniejącego Invoker Commands API. Jego głównym elementem jest atrybut [interestfor]. Można go dodać do elementów a, area, button oraz a w SVG. Wskazuje on na element, z którym coś ma się stać, gdy elementowi z tym atrybutem okaże się zainteresowanie. Sztandarowym przykładem jest pokazanie tooltipa:
<button interestfor="tooltip">Jakiś przycisk</button> <!-- 1 -->
<span popover="hint" id="tooltip">Jakiś tooltip</span> <!-- 2 -->
Przycisk ma atrybut [interestfor], wskazujący na element #tooltip (1). Z kolei element #tooltip ma atrybut [popover=hint] (2). Dzięki temu po najechaniu myszą na przycisk, po chwili powinien pod nim pojawić się tooltip:

Natomiast sama wartość hint dla atrybutu [popover] informuje przeglądarkę, że ma traktować ten popover jako pomocniczy. Dzięki temu jego pojawienie się będzie zamykać jedynie inne pomocnicze popovery. Pozostałe będą go ignorować.
Położenie tooltipa można kontrolować przy pomocy własności CSS position-area:
[popover=hint] {
position-area: bottom; /* 1 */
}
W naszym przykładzie użyliśmy wartości bottom (1), dzięki czemu tooltip pojawia się pod przyciskiem.
CSS pozwala także zmienić opóźnienie po interakcji z elementem, po którym przeglądarka uzna, że ktoś wyraża zainteresowanie:
[interestfor] { /* 2 */
interest-delay: 0s; /* 1 */
}
W powyższym przykładzie ustawiliśmy opóźnienie na 0s (1). Tym samym będzie się to zachowywać praktycznie identycznie do pseudoklas :hover i :focus. Warto też zauważyć, że własność tę należy dodać do elementu z atrybutem [interestfor], nie zaś do popovera (2).
Zaawansowane interakcje
Można jednak tworzyć o wiele bardziej skomplikowane interakcje, niż pokazywanie tooltipa:
W powyższym przykładzie najechanie na przycisk sprawi trzy rzeczy:
- najechany przycisk dostanie pomarańczowe tło,
- kółko na środku strony zmieni kształt i kolor obramowania,
- kółko na środku dostanie kolor tła równy zawartości atrybutu
[data-color]najechanego przycisku.
Kod HTML wygląda następująco:
<p>
<button interestfor="circle" data-color="pink">Różowy</button> <!-- 1 -->
<button interestfor="circle" data-color="blue">Niebieski</button> <!-- 2 -->
<button interestfor="circle" data-color="green">Zielony</button> <!-- 3 -->
</p>
<div class="circle" id="circle"></div> <!-- 4 -->
Każdy z przycisków (1, 2, 3) ma atrybut [interestfor] wskazujący na element #circle (4).
Z kolei kod CSS odpowiedzialny za zmianę tła przycisków oraz obramowania koła prezentuje się tak:
:interest-source { /* 1 */
background: orange; /* 2 */
}
:interest-target { /* 3 */
border: 2px #f00 dashed; /* 4 */
}
Pseudoklasa :interest-source (1) wskazuje na aktualnie najechany elementy z atrybutem [interestfor]. Dostanie on pomarańczowe tło (2). Z kolei element wskazywany przez atrybut [interestfor] aktualnie najechanego elementu jest wskazywany przez pseudoklasę :interest-target (3). Dostanie on czerwone, przerywane obramowanie (4).
Natomiast do zmiany tła kółka potrzebujemy kodu JS:
const circle = document.querySelector( '#circle' );
circle.addEventListener( 'interest', ( evt ) => { // 1
evt.target.style.backgroundColor = evt.source.dataset.color; // 2
} );
circle.addEventListener( 'loseinterest', ( evt ) => { // 3
evt.target.style.backgroundColor = 'transparent'; // 4
} );
Gdy najedziemy na przycisk z atrybutem [interestfor], na elemencie przez niego wskazywanym odpali się zdarzenie interest (1). Gdy zajdzie, do kółka przypisujemy kolor wskazywany przez atrybut [data-color] przycisku (2). Własność evt.target przechowuje element wskazywany przez atrybut [interestfor], podczas gdy evt-source – element z atrybutem [interestfor]. Z kolei, gdy zjedzie się myszą z przycisku, wówczas na kółku zostanie odpalone zdarzenie loseinterest (3). Wtedy też usuwamy mu tło (4).
Przyszłość
Nowe API ma zdecydowanie gorsze wsparcie niż swój klikalny odpowiednik. Na ten moment działa wyłącznie w Chrome i Edge’u. Co nie jest aż takie zaskakujące, jeśli weźmie się pod uwagę, że Interest Invoker API nie ma jeszcze nawet oficjalnej specyfikacji. To oznacza, że jeszcze trochę sobie poczekamy na w pełni natywne, deklaratywne tooltipy. A jest na co czekać, bo zrobienie ich dobrze, z dobrym pozycjonowaniem tooltipów, to jest zaskakująco skomplikowany problem. Istnieją całe biblioteki, takie jak Floating UI, których jedynym zadaniem jest obliczanie, w którym miejscu okienko z pomocną etykietą powinno się pokazać. Do tego trzeba dodać całą JS-ową logikę, która będzie pokazywać tooltipa po odpowiednio długim przytrzymaniu myszy na elemencie. A przecież trzeba jeszcze obsłużyć inne sposoby “okazywania zainteresowania”. To w gruncie rzeczy problem podobny do zamykania elementów UI zgodnie z konwencjami danej platformy.
Dlatego ja z niecierpliwością czekam na czasy, gdy okazywanie zainteresowania w końcu stanie się łatwe.
Komentarze
Przejdź do komentarzy bezpośrednio na Githubie.