Zarządzanie interakcją SVG z właściwością zdarzeń wskaźnika
Opublikowany: 2022-03-10pointer-events
.Spróbuj kliknąć lub dotknąć obraz SVG poniżej. Jeśli umieścisz wskaźnik we właściwym miejscu (ścieżka zacieniona), strona główna Smashing Magazine powinna być otwarta w nowej karcie przeglądarki. Jeśli próbowałeś kliknąć jakąś białą przestrzeń, zamiast tego możesz być naprawdę zdezorientowany.
Zobacz Pen Amethyst autorstwa Tiffany Brown (@webinista) na CodePen.
To jest dylemat, przed którym stanąłem podczas ostatniego projektu, który zawierał linki w obrazach SVG. Czasami, gdy kliknąłem obraz, link działał. Innym razem tak się nie stało. Mylące, prawda?
Sięgnąłem do specyfikacji SVG, aby dowiedzieć się więcej o tym, co może się wydarzyć i czy SVG oferuje poprawkę. Odpowiedź: pointer-events
.
Nie mylić ze zdarzeniami wskaźnika DOM ( Document Object Model), pointer pointer-events
jest zarówno właściwością CSS, jak i atrybutem elementu SVG. Dzięki niemu możemy zarządzać, które części dokumentu lub elementu SVG mogą odbierać zdarzenia z urządzenia wskazującego, takiego jak mysz, gładzik lub palec.
Uwaga dotycząca terminologii: „zdarzenia wskaźnika” to także nazwa funkcji platformy internetowej niezależnej od urządzenia, która umożliwia wprowadzanie danych przez użytkownika. Jednak w tym artykule — i na potrzeby właściwości pointer-events
— wyrażenie „zdarzenia wskaźnika” obejmuje również zdarzenia myszy i dotyku.
Poza pudełkiem: „Model kształtu” SVG
Używanie CSS z HTML narzuca model układu pudełka na HTML. W modelu układu pudełkowego każdy element generuje prostokąt wokół swojej zawartości. Ten prostokąt może być śródliniowy, śródliniowy, atomowy śródliniowy lub blokowy, ale nadal jest prostokątem z czterema kątami prostymi i czterema krawędziami. Kiedy dodajemy łącze lub detektor zdarzeń do elementu, obszar interaktywny dopasowuje wymiary prostokąta.
Uwaga : Dodanie clip-path
do elementu interaktywnego zmienia jego interaktywne granice. Innymi słowy, jeśli dodasz sześciokątną clip-path
przycinającą a
elementu, tylko punkty znajdujące się na ścieżce przycinającej będą dostępne do kliknięcia. Podobnie, dodanie transformacji skośnej zmieni prostokąty w romboidy.
SVG nie ma modelu układu pudełka. Widzisz, kiedy dokument SVG jest zawarty w dokumencie HTML, w układzie CSS, główny element SVG jest zgodny z modelem układu pudełkowego. Jego elementy podrzędne nie. W rezultacie większość właściwości związanych z układem CSS nie ma zastosowania do SVG.
Zamiast tego SVG ma coś, co nazywam „modelem kształtu”. Kiedy dodamy łącze lub detektor zdarzeń do dokumentu lub elementu SVG, obszar interaktywny niekoniecznie będzie prostokątem. Elementy SVG mają obwiednię. Obwiednia jest zdefiniowana jako: najbardziej dopasowany prostokąt wyrównany z osiami układu współrzędnych użytkownika tego elementu, który całkowicie otacza go i jego elementy potomne.
Ale początkowo to, które części dokumentu SVG są interaktywne, zależy od tego, które części są widoczne i/lub pomalowane .
Malowane a widoczne elementy
Elementy SVG można „wypełnić”, ale można je również „głaskać”. Wypełnienie odnosi się do wnętrza kształtu. Skok odnosi się do jego zarysu.
Razem „wypełnianie” i „obrysowanie” to operacje malowania, które renderują elementy na ekranie lub stronie (znane również jako canvas ). Kiedy mówimy o elementach malowanych , mamy na myśli to, że element ma wypełnienie i/lub obrys. Zwykle oznacza to, że element jest również widoczny.
Jednak element SVG można pomalować, nie będąc widocznym. Może się to zdarzyć, jeśli visible
wartość atrybutu lub właściwość CSS jest hidden
lub gdy display
none
ma wartości. Element jest tam i zajmuje teoretyczną przestrzeń. Po prostu tego nie widzimy (a technologia wspomagająca może jej nie wykryć).
Być może bardziej mylące jest to, że element może być również widoczny — to znaczy mieć obliczoną wartość visibility
jako visible
— bez malowania. Dzieje się tak, gdy elementom brakuje zarówno obrysu, jak i wypełnienia.
Uwaga : Wartości kolorów z przezroczystością alfa (np rgba(0,0,0,0)
) nie mają wpływu na to, czy element jest pomalowany, czy widoczny. Innymi słowy, jeśli element ma wypełnienie lub obrys przezroczystość alfa, jest on malowany, nawet jeśli jest niewidoczny.
Wiedza o tym, kiedy element jest pomalowany, widoczny lub nie jest widoczny, ma kluczowe znaczenie dla zrozumienia wpływu każdej wartości pointer-events
.
Wszystko albo nic albo coś pomiędzy: wartości
pointer-events
jest zarówno własnością CSS, jak i atrybutem elementu SVG. Jego początkową wartością jest auto
, co oznacza, że tylko pomalowane i widoczne fragmenty będą otrzymywać zdarzenia wskaźnika. Większość innych wartości można podzielić na dwie grupy:
- Wartości, które wymagają, aby element był widoczny; oraz
- Wartości, które nie.
painted
, fill
, stroke
i all
należą do tej drugiej kategorii. Ich zależne od widoczności odpowiedniki — visiblePainted
, visibleFill
, visibleStroke
i visible
— należą do tych pierwszych.
Specyfikacja SVG 2.0 definiuje również wartość bounding-box
. Gdy wartość pointer-events
to bounding-box
, prostokątny obszar wokół elementu może również otrzymywać zdarzenia wskaźnika. W chwili pisania tego tekstu tylko Chrome 65+ obsługuje wartość bounding-box
.

none
jest również prawidłową wartością. Uniemożliwia elementowi i jego dzieciom odbieranie jakichkolwiek zdarzeń wskaźnika. Właściwość CSS pointer-events
może być również używana z elementami HTML. Ale gdy jest używany z HTML, tylko auto
i none
są prawidłowymi wartościami.
Ponieważ wartości pointer-events
są lepiej zademonstrowane niż wyjaśnione, spójrzmy na kilka demonstracji.
Tutaj mamy okrąg z zastosowanym wypełnieniem i obrysem. Jest zarówno namalowany , jak i widoczny . Cały okrąg może otrzymywać zdarzenia wskazujące, ale obszar poza okręgiem nie.
Zobacz pióro widoczne a namalowane w SVG autorstwa Tiffany Brown (@webinista) na CodePen.
Wyłącz wypełnienie, aby jego wartość none
. Teraz, jeśli spróbujesz najechać, kliknąć lub dotknąć wnętrza okręgu, nic się nie dzieje. Ale jeśli zrobisz to samo dla obszaru obrysu, zdarzenia wskaźnika nadal będą wywoływane. Zmiana wartości fill
na none
oznacza, że ten obszar jest widoczny , ale nie zamalowany .
Zróbmy małą zmianę w naszych znacznikach. Dodamy pointer-events="visible"
do naszego elementu circle
, zachowując fill=none
.
Zobacz Pen How dodawanie wskaźników-zdarzeń: wszystko wpływa na interaktywność autorstwa Tiffany Brown (@webinista) w CodePen.
Teraz niepomalowany obszar otoczony obrysem może otrzymywać zdarzenia wskaźnika.
Powiększanie klikalnego obszaru obrazu SVG
Wróćmy do obrazu z początku tego artykułu. Nasz „ametyst” to element path
, w przeciwieństwie do grupy wielokątów, z których każdy ma stroke
i fill
. Oznacza to, że nie możemy po prostu dodać pointer-events="all"
i nazwać tego dniem.
Zamiast tego musimy powiększyć obszar kliknięcia. Wykorzystajmy to, co wiemy o elementach malowanych i widocznych. W poniższym przykładzie dodałem prostokąt do naszego znacznika obrazu.
Zobacz Pen Augmenting the click area of the SVG image autorstwa Tiffany Brown (@webinista) w CodePen.
Mimo że ten prostokąt jest niewidoczny, nadal jest widoczny technicznie (tj visibility: visible
). Brak wypełnienia oznacza jednak, że nie jest malowany . Nasz wizerunek wygląda tak samo. Rzeczywiście, to nadal działa tak samo — kliknięcie białego miejsca nadal nie uruchamia operacji nawigacji. Nadal musimy dodać atrybut pointer-events
do naszego a
. Tutaj będzie działać użycie visible
lub all
wartości.
Zobacz Pen Augmenting the click area of the SVG image autorstwa Tiffany Brown (@webinista) w CodePen.
Teraz cały obraz może odbierać zdarzenia wskaźnika.
Użycie bounding-box
wyeliminowałoby potrzebę elementu fantomowego. Wszystkie punkty w ramce ograniczającej otrzymałyby zdarzenia wskaźnika, w tym biały znak zawarty w ścieżce. Ale znowu: pointer-events="bounding-box"
nie jest powszechnie obsługiwany. Dopóki tak się nie stanie, możemy używać elementów niepomalowanych.
Używanie pointer-events
podczas miksowania SVG i HTML
Inny przypadek, w którym pointer-events
mogą być pomocne: użycie SVG wewnątrz przycisku HTML.
Zobacz Pen Ovxmmy autorstwa Tiffany Brown (@webinista) na CodePen.
W większości przeglądarek — Firefox i Internet Explorer 11 są tu wyjątkami — wartością event.target
będzie element SVG zamiast naszego przycisku HTML. Dodajmy pointer-events="none"
do naszego otwierającego tagu SVG.
Zobacz zdarzenia wskaźnika Pen How: żaden nie może być używany z SVG i HTML autorstwa Tiffany Brown (@webinista) w CodePen.
Teraz, gdy użytkownicy klikną lub nacisną nasz przycisk, event.target
będzie odnosić się do naszego button
.
Osoby dobrze zorientowane w DOM i JavaScript zauważą, że użycie słowa kluczowego function
zamiast funkcji strzałki i this
zamiast event.target
rozwiązuje ten problem. Użycie pointer-events="none"
(lub pointer-events: none;
w twoim CSS) oznacza, że nie musisz zapisywać tego szczególnego dziwactwa JavaScript w pamięci.
Wniosek
SVG obsługuje ten sam rodzaj interaktywności, do którego przywykliśmy z HTML. Możemy go wykorzystać do tworzenia wykresów, które reagują na kliknięcia lub stuknięcia. Możemy tworzyć połączone obszary, które nie są zgodne z modelem pola CSS i HTML. A dzięki dodaniu pointer-events
możemy poprawić sposób, w jaki nasze dokumenty SVG zachowują się w odpowiedzi na interakcję użytkownika.
Wsparcie przeglądarki dla pointer-events
SVG jest solidne. Każda przeglądarka obsługująca SVG obsługuje właściwość dokumentów i elementów SVG. W przypadku użycia z elementami HTML wsparcie jest nieco mniej niezawodne. Nie jest dostępny w przeglądarce Internet Explorer 10 ani w jej poprzednikach, ani w żadnej wersji Opery Mini.
Właśnie zarysowaliśmy powierzchnię pointer-events
w tym artykule. Aby uzyskać bardziej szczegółowe informacje techniczne, zapoznaj się ze specyfikacją SVG. Dokumentacja internetowa MDN (Mozilla Developer Network) oferuje bardziej przyjazną dla programistów dokumentację dotyczącą pointer-events
, wraz z przykładami.