Tworzenie komponentu przełącznika

Podstawowe informacje o tworzeniu elastycznego i dostępnego komponentu przełącznika.

W tym poście przedstawię sposoby stworzenia komponentów przełączników. Wypróbuj wersję demonstracyjną

Demonstracja

Jeśli wolisz film, oto wersja tego posta na YouTube:

Przegląd

Przełącznik działa podobnie do pola wyboru, ale jednoznacznie reprezentuje stan włączenia lub wyłączenia wartości logicznej.

W tej wersji demonstracyjnej większość funkcji korzysta z języka <input type="checkbox" role="switch">. Zaletą tej wersji jest to, że do pełnego działania i dostępności CSS nie jest wymagany. Wczytywanie CSS umożliwia obsługę języków z zapisem od prawej do lewej, pionowości, animacji i innych. Wczytywanie JavaScriptu sprawia, że przejście staje się przeciągłe i wymierne.

Właściwości niestandardowe

Podane niżej zmienne reprezentują różne części przełącznika i ich opcje. Jako klasa najwyższego poziomu .gui-switch zawiera właściwości niestandardowe używane we wszystkich elementach podrzędnych komponentu oraz punkty wejścia do scentralizowanego dostosowywania.

Śledź

Długość (--track-size), dopełnienie i 2 kolory:

.gui-switch {
  --track-size: calc(var(--thumb-size) * 2);
  --track-padding: 2px;

  --track-inactive: hsl(80 0% 80%);
  --track-active: hsl(80 60% 45%);

  --track-color-inactive: var(--track-inactive);
  --track-color-active: var(--track-active);

  @media (prefers-color-scheme: dark) {
    --track-inactive: hsl(80 0% 35%);
    --track-active: hsl(80 60% 60%);
  }
}

Szarpnięcie

Rozmiar, kolor tła i kolory wyróżnienia interakcji:

.gui-switch {
  --thumb-size: 2rem;
  --thumb: hsl(0 0% 100%);
  --thumb-highlight: hsl(0 0% 0% / 25%);

  --thumb-color: var(--thumb);
  --thumb-color-highlight: var(--thumb-highlight);

  @media (prefers-color-scheme: dark) {
    --thumb: hsl(0 0% 5%);
    --thumb-highlight: hsl(0 0% 100% / 25%);
  }
}

Ograniczony ruch

Aby dodać jasny alias i zmniejszyć liczbę powtórzeń, można umieścić w niestandardowej właściwości za pomocą wtyczki PostCSS zapytania o multimedia użytkownika z obniżoną preferencją ruchu na podstawie tej specyfikacji wersji roboczej w zapytaniach o multimedia:

@custom-media --motionOK (prefers-reduced-motion: no-preference);

Markup

Zdecydowałam się opakować mój element <input type="checkbox" role="switch"> obiektem <input type="checkbox" role="switch"> w pakiet, aby uniknąć niejasności co do pola wyboru i etykiety, a jednocześnie dać użytkownikowi możliwość interakcji z etykietą i przełączania danych wejściowych.<label>

Naturalna, nietypowa etykieta i pole wyboru.

<label for="switch" class="gui-switch">
  Label text
  <input type="checkbox" role="switch" id="switch">
</label>

<input type="checkbox"> jest wstępnie utworzony z API i state. Przeglądarka zarządza właściwością checked i zdarzeniami wejściowymi takimi jak oninput i onchanged.

Układy

Flexbox, siatka i właściwości niestandardowe są niezbędne do utrzymania stylów tego komponentu. Centralizują wartości, nadają nazwy niejednoznacznym obliczeniom lub obszarom oraz udostępniają niewielki interfejs API właściwości niestandardowych, który ułatwia dostosowywanie komponentów.

.gui-switch

Układ najwyższego poziomu przełącznika to Flexbox. Klasa .gui-switch zawiera prywatne i publiczne właściwości niestandardowe, których dzieci używają do obliczania swoich układów.

Narzędzia deweloperskie Flexbox z nałożonymi poziomą etykietą i przełącznikiem, pokazujące rozmieszczenie miejsca w układzie.

.gui-switch {
  display: flex;
  align-items: center;
  gap: 2ch;
  justify-content: space-between;
}

Rozszerzanie i modyfikowanie układu Flexbox jest jak zmiana w każdym układzie Flexbox. Aby na przykład umieścić etykiety nad lub pod przełącznikiem albo zmienić flex-direction:

Narzędzia deweloperskie Flexbox nałożone na pionową etykietę i przełącznik.

<label for="light-switch" class="gui-switch" style="flex-direction: column">
  Default
  <input type="checkbox" role="switch" id="light-switch">
</label>

Śledź

Dane wejściowe pola wyboru mają styl ścieżki przełączania, przez co usunięcie normalnego parametru appearance: checkbox i określenie własnego rozmiaru:

Narzędzia deweloperskie w siatce nakładające się na ścieżkę przełączania, pokazując nazwane obszary ścieżek siatki o nazwie „track”.

.gui-switch > input {
  appearance: none;

  inline-size: var(--track-size);
  block-size: var(--thumb-size);
  padding: var(--track-padding);

  flex-shrink: 0;
  display: grid;
  align-items: center;
  grid: [track] 1fr / [track] 1fr;
}

Na ścieżce są też tworzone 1 pojedyncze komórki obszaru siatki, do którego można zgłosić kciuk.

Szarpnięcie

Styl appearance: none usuwa też wizualny znacznik wyboru wyświetlany przez przeglądarkę. Zastępuje on w danych wejściowych pseudoelement i :checked pseudoklasę.

Kciuk to pseudoelement podrzędny element powiązany z elementem input[type="checkbox"] i ustawiony nad torem, a nie pod nim, przez zgłoszenie prawa do obszaru siatki track:

Narzędzia deweloperskie pokazujące pseudoelementowy kciuk umieszczony w siatce CSS.

.gui-switch > input::before {
  content: "";
  grid-area: track;
  inline-size: var(--thumb-size);
  block-size: var(--thumb-size);
}

Style

Właściwości niestandardowe to uniwersalny komponent przełącznika, który dostosowuje się do schematów kolorów, języków pisanych od prawej do lewej i preferencji ruchu.

Porównanie jasnego i ciemnego motywu przełącznika oraz jego stanów.

Style interakcji dotykiem

Na urządzeniach mobilnych przeglądarki dodają do etykiet i wprowadzanych tekstu funkcje zaznaczania dotykiem i zaznaczania tekstu. Wpłynęło to negatywnie na styl i sposób interakcji wizualnej potrzebny do tego przejścia. Mogę usunąć te efekty i dodać własny styl cursor: pointer, korzystając z kilku wierszy CSS:

.gui-switch {
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

Nie zawsze warto usuwać te style, ponieważ mogą one być cennym wskaźnikiem interakcji wizualnych. Pamiętaj, aby w razie potrzeby udostępnić niestandardowe wersje alternatywne.

Śledź

Style tego elementu dotyczą głównie jego kształtu i koloru, do których uzyskuje on dostęp z elementu nadrzędnego .gui-switch za pomocą kaskady.

zmienić wersję z niestandardowymi rozmiarami i kolorami ścieżek audio,

.gui-switch > input {
  appearance: none;
  border: none;
  outline-offset: 5px;
  box-sizing: content-box;

  padding: var(--track-padding);
  background: var(--track-color-inactive);
  inline-size: var(--track-size);
  block-size: var(--thumb-size);
  border-radius: var(--track-size);
}

Szeroki wybór opcji dostosowywania ścieżki przejścia pochodzi z 4 właściwości niestandardowych. Dodano border: none, ponieważ appearance: none nie usuwa obramowań z pola wyboru we wszystkich przeglądarkach.

Szarpnięcie

Element kciuka znajduje się już po prawej stronie track, ale wymaga stylów okręgów:

.gui-switch > input::before {
  background: var(--thumb-color);
  border-radius: 50%;
}

Narzędzia deweloperskie z wyróżnionym pseudoelementem kciuka w kształcie okręgu.

Interakcja

Właściwości niestandardowe pozwalają przygotować się do interakcji, które obejmują wyróżnienia po najechaniu kursorem i zmianę pozycji kciuka. Preferencje użytkownika są też sprawdzane przed przeniesieniem stylów ruchu lub zaznaczenia kursorem.

.gui-switch > input::before {
  box-shadow: 0 0 0 var(--highlight-size) var(--thumb-color-highlight);

  @media (--motionOK) { & {
    transition:
      transform var(--thumb-transition-duration) ease,
      box-shadow .25s ease;
  }}
}

Pozycja kciuka

Właściwości niestandardowe udostępniają jeden mechanizm źródłowy do określania pozycji kciuka w ścieżce. Mamy do dyspozycji rozmiary ścieżek i kciuków, których użyjemy do obliczeń, aby zadbać o prawidłowe odsunięcie kciuka i w obrębie utworu: 0% i 100%.

Element input jest właścicielem zmiennej pozycji --thumb-position, a pseudoelement używa jej jako pozycji translateX:

.gui-switch > input {
  --thumb-position: 0%;
}

.gui-switch > input::before {
  transform: translateX(var(--thumb-position));
}

Możemy teraz zmieniać --thumb-position z CSS i pseudoklas występujących w elementach pól wyboru. Ponieważ warunkowo ustawiamy atrybut transition: transform var(--thumb-transition-duration) ease wcześniej w tym elemencie, te zmiany mogą być animowane po modyfikacji:

/* positioned at the end of the track: track length - 100% (thumb width) */
.gui-switch > input:checked {
  --thumb-position: calc(var(--track-size) - 100%);
}

/* positioned in the center of the track: half the track - half the thumb */
.gui-switch > input:indeterminate {
  --thumb-position: calc(
    (var(--track-size) / 2) - (var(--thumb-size) / 2)
  );
}

Ta oddzielona administracja się sprawdziła. Element kciuka dotyczy tylko 1 stylu – pozycji translateX. Dane wejściowe mogą zarządzać złożonością i obliczeniami.

Pionowo

Wspieramy klasę modyfikatora -vertical, która dodaje rotację z przekształceniami CSS do elementu input.

Obrócony element 3D nie zmienia jednak całkowitej wysokości komponentu, co może wyrzucić układ bloków. Uwzględnij to za pomocą zmiennych --track-size i --track-padding. Oblicz minimalną ilość miejsca wymaganą do ułożenia pionowego przycisku w układzie:

.gui-switch.-vertical {
  min-block-size: calc(var(--track-size) + calc(var(--track-padding) * 2));

  & > input {
    transform: rotate(-90deg);
  }
}

(RTL) od prawej do lewej

Wspólnie z zespołem CSS, Elad Schecter, zbudowaliśmy prototyp wysuwanego menu bocznego za pomocą przekształceń CSS obsługujących języki pisane od prawej do lewej przez odwrócenie pojedynczej zmiennej. Zrobiliśmy to, bo w CSS nie ma logicznych przekształceń właściwości, a możliwe, że nigdy ich nie będzie. Elad wpadł na świetny pomysł na wykorzystanie wartości właściwości niestandardowej do odwrócenia wartości procentowych, aby umożliwić zarządzanie naszą własną logiką niestandardową w celu przekształcenia logicznego w jedną lokalizację. W tym przypadku zastosowałam tę metodę i myślę, że w praktyce wszystko działało:

.gui-switch {
  --isLTR: 1;

  &:dir(rtl) {
    --isLTR: -1;
  }
}

Właściwość niestandardowa o nazwie --isLTR początkowo ma wartość 1, czyli true, ponieważ domyślnie układ strony odbywa się od lewej do prawej. Następnie za pomocą pseudoklasy CSS :dir() wartość jest ustawiana na -1, jeśli komponent znajduje się w układzie od prawej do lewej.

Zastosuj wymiar --isLTR w akcji, używając go w obrębie elementu calc() w przekształceniu:

.gui-switch.-vertical > input {
  transform: rotate(-90deg);
  transform: rotate(calc(90deg * var(--isLTR) * -1));
}

Teraz obrót przełącznika pionowego uwzględnia pozycję odwrotnej strony wymaganą w układzie od prawej do lewej.

Przekształcenia translateX w pseudoelemencie kciuka również wymagają aktualizacji, aby uwzględnić wymaganie od strony przeciwnej:

.gui-switch > input:checked {
  --thumb-position: calc(var(--track-size) - 100%);
  --thumb-position: calc((var(--track-size) - 100%) * var(--isLTR));
}

.gui-switch > input:indeterminate {
  --thumb-position: calc(
    (var(--track-size) / 2) - (var(--thumb-size) / 2)
  );
  --thumb-position: calc(
   ((var(--track-size) / 2) - (var(--thumb-size) / 2))
    * var(--isLTR)
  );
}

Takie podejście nie zaspokoi wszystkich potrzeb w zakresie koncepcji takich jak logiczne przekształcenia CSS, ale w wielu przypadkach oferuje pewne zasady DRY.

Stany

Użycie wbudowanej funkcji input[type="checkbox"] nie byłoby kompletne, jeśli nie obsługuje różnych stanów, w których może się znajdować: :checked, :disabled, :indeterminate i :hover. Celowo pozostawiono jedynkę :focus bez zmian. Zmieniliśmy tylko przesunięcie jej; pierścień ostrości wyglądały świetnie w Firefoksie i Safari:

Zrzut ekranu z pierścieniem ostrości z zaznaczonym przełącznikiem w przeglądarkach Firefox i Safari.

Zaznaczono

<label for="switch-checked" class="gui-switch">
  Default
  <input type="checkbox" role="switch" id="switch-checked" checked="true">
</label>

Ten stan reprezentuje stan: on. W tym stanie tło wejściowe „śledź” jest w aktywnym kolorze, a położenie kciuka jest ustawione na koniec.

.gui-switch > input:checked {
  background: var(--track-color-active);
  --thumb-position: calc((var(--track-size) - 100%) * var(--isLTR));
}

Wyłączono

<label for="switch-disabled" class="gui-switch">
  Default
  <input type="checkbox" role="switch" id="switch-disabled" disabled="true">
</label>

Przycisk :disabled nie tylko wygląda inaczej, ale powinien też być niezmienny.Niezmienność interakcji jest wolna od przeglądarki, ale stany wizualne wymagają stylów ze względu na użycie appearance: none.

.gui-switch > input:disabled {
  cursor: not-allowed;
  --thumb-color: transparent;

  &::before {
    cursor: not-allowed;
    box-shadow: inset 0 0 0 2px hsl(0 0% 100% / 50%);

    @media (prefers-color-scheme: dark) { & {
      box-shadow: inset 0 0 0 2px hsl(0 0% 0% / 50%);
    }}
  }
}

Przełącznik z ciemnym stylem w pozycji wyłączonej, zaznaczonej i odznaczonej.

Ten stan jest trudny, ponieważ wymaga ciemnych i jasnych motywów z wyłączonymi i zaznaczonymi elementami. Stylistycznie wybieram dla nich minimalistyczne style, aby nie ograniczać ciężkiej pracy przy łączeniu różnych stylów.

Nieokreślona

Stan często zapomniany to :indeterminate, gdzie pole wyboru nie jest zaznaczone ani odznaczone. Jest to zabawna atmosfera – zapraszająca i niepozorna. Warto zapamiętać, że stany wartości logicznej mogą być niejasne między stanami.

Trudno jest wskazać nieokreślone pole wyboru, ponieważ potrafi je ustawić tylko JavaScript:

<label for="switch-indeterminate" class="gui-switch">
  Indeterminate
  <input type="checkbox" role="switch" id="switch-indeterminate">
  <script>document.getElementById('switch-indeterminate').indeterminate = true</script>
</label>

Stan nieokreślony, w którym miniatura ścieżki znajduje się w środku, co wskazuje na niezdecydowany.

Według mnie obecny stan jest niepozorny i zachęcający, więc dobrze było umieścić kciuk w środku:

.gui-switch > input:indeterminate {
  --thumb-position: calc(
    calc(calc(var(--track-size) / 2) - calc(var(--thumb-size) / 2))
    * var(--isLTR)
  );
}

Najedź

Interakcje po najechaniu kursorem powinny zapewniać wizualną obsługę połączonego interfejsu oraz przekazywać informacje o interfejsie interaktywnym. Ten przełącznik podświetla kciuk półprzezroczystym pierścieniem po najechaniu kursorem na etykietę lub dane wejściowe. Animacja pokazująca kursor myszy pokazuje kierunek w kierunku interaktywnego elementu kciuka.

Efekt „Wyróżnij” jest przeprowadzany za pomocą funkcji box-shadow. Po najechaniu na wyłączone ustawienie zwiększ rozmiar --highlight-size. Jeśli użytkownik nie przeszkadza w ruchu, przenosimy urządzenie box-shadow i obserwujemy, jak się powiększy, a jeśli ruch nie odpowiada, natychmiast pojawi się podświetlenie:

.gui-switch > input::before {
  box-shadow: 0 0 0 var(--highlight-size) var(--thumb-color-highlight);

  @media (--motionOK) { & {
    transition:
      transform var(--thumb-transition-duration) ease,
      box-shadow .25s ease;
  }}
}

.gui-switch > input:not(:disabled):hover::before {
  --highlight-size: .5rem;
}

JavaScript

Próba naśladowania interfejsu fizycznego, szczególnie w przypadku takiego interfejsu z okręgiem wewnątrz ścieżki, jest nietypowa. W systemie iOS ten przełącznik działa jak należy – można przeciągnąć przełącznik na boki, a ta opcja była przyjemna. I na odwrót – element interfejsu może wydawać się nieaktywny, jeśli po wykonaniu gestu przeciągania nic się nie dzieje.

Kciski do przeciągania

Pseudoelement kciuka otrzymuje swoją pozycję z zakresu var(--thumb-position) o zakresie .gui-switch > input. JavaScript może dostarczać wartość stylu wbudowanego w danych wejściowych, aby dynamicznie aktualizować pozycję kciuka, dzięki czemu wydaje się, że podąża za gestem wskazującym. Po zwolnieniu wskaźnika usuń style wbudowane i za pomocą właściwości niestandardowej --thumb-position ustal, czy przeciągnięcie było blisko czy włączone. Jest to szkielet rozwiązania – zdarzenia wskaźnika warunkowo śledzą pozycje wskaźników, aby modyfikować niestandardowe właściwości CSS.

Ponieważ przed wyświetleniem skryptu komponent działał w 100%, utrzymanie obecnego działania wymaga sporo pracy, np. kliknięcia etykiety w celu zmiany danych wejściowych. Nasz kod JavaScript nie powinien dodawać funkcji kosztem istniejących.

touch-action

Przeciąganie to gest niestandardowy, dzięki któremu można uzyskać dzięki temu korzyści w usłudze touch-action. W przypadku tego przełącznika nasz skrypt powinien obsługiwać gest w poziomie lub gest w pionie zarejestrowany dla wariantu przełącznika pionowego. Za pomocą touch-action możemy określić, jakie gesty mają być obsługiwane w odniesieniu do danego elementu, dzięki czemu skrypt może wykonać gest bez rywalizacji.

Ten kod CSS informuje przeglądarkę, że gest wskaźnika zaczyna się od tej ścieżki zmiany, obsługuje gesty pionowe:

.gui-switch > input {
  touch-action: pan-y;
}

Wynik to gest poziomy, który nie przesuwa się ani nie przewija strony. Wskaźnik może przewijać stronę w pionie, zaczynając od danych wejściowych, ale dane poziome są obsługiwane niestandardowo.

Narzędzia do stylu wartości piksela

Podczas konfigurowania i przeciągania z elementów trzeba pobierać różne obliczone wartości liczbowe. Poniższe funkcje JavaScript zwracają obliczone wartości pikseli z podaną właściwością CSS. Jest używany w skrypcie konfiguracji w ten sposób: getStyle(checkbox, 'padding-left').

​​const getStyle = (element, prop) => {
  return parseInt(window.getComputedStyle(element).getPropertyValue(prop));
}

const getPseudoStyle = (element, prop) => {
  return parseInt(window.getComputedStyle(element, ':before').getPropertyValue(prop));
}

export {
  getStyle,
  getPseudoStyle,
}

Zwróć uwagę, że window.getComputedStyle() akceptuje drugi argument – pseudoelement docelowy. JavaScript jest w stanie odczytywać tak wiele wartości z elementów, nawet z pseudoelementów.

dragging

Jest to kluczowy moment dla logiki przeciągania i należy pamiętać o kilku kwestiach z modułu obsługi zdarzeń funkcji:

const dragging = event => {
  if (!state.activethumb) return

  let {thumbsize, bounds, padding} = switches.get(state.activethumb.parentElement)
  let directionality = getStyle(state.activethumb, '--isLTR')

  let track = (directionality === -1)
    ? (state.activethumb.clientWidth * -1) + thumbsize + padding
    : 0

  let pos = Math.round(event.offsetX - thumbsize / 2)

  if (pos < bounds.lower) pos = 0
  if (pos > bounds.upper) pos = bounds.upper

  state.activethumb.style.setProperty('--thumb-position', `${track + pos}px`)
}

Głównym elementem skryptu jest state.activethumb, czyli małe kółko, które znajduje się dla tego skryptu wraz ze wskaźnikiem. Obiekt switches to obiekt typu Map(), gdzie klucze mają wartość .gui-switch, a wartości są zapisane w pamięci podręcznej i zapewniają wydajność skryptu. Tekst od prawej do lewej jest obsługiwany za pomocą tej samej niestandardowej właściwości co język CSS --isLTR. Za jego pomocą można odwrócić logikę i dalej obsługiwać kierunek RTL. Wartość event.offsetX także jest przydatna, ponieważ zawiera wartość delta przydatną do umiejscowienia kciuka.

state.activethumb.style.setProperty('--thumb-position', `${track + pos}px`)

Ten ostatni wiersz kodu CSS ustawia właściwość niestandardową używaną przez element kciuka. W przeciwnym razie to przypisanie wartości zmieniłoby się w czasie, ale poprzednie zdarzenie wskaźnika tymczasowo ustawiło --thumb-transition-duration na 0s, przez co udałoby się uniknąć powolnej interakcji.

dragEnd

Aby użytkownik mógł przeciągnąć daleko poza przełącznik i puścić, trzeba było zarejestrować globalne zdarzenie okna:

window.addEventListener('pointerup', event => {
  if (!state.activethumb) return

  dragEnd(event)
})

Uważam, że użytkownik powinien mieć swobodę swobodnego przeciągania treści i mieć wystarczająco inteligentny interfejs, by uwzględniać to, co się dzieje. Wdrożenie tej strategii nie wymagało zbyt wiele czasu, ale trzeba było go dokładnie przeanalizować podczas programowania.

const dragEnd = event => {
  if (!state.activethumb) return

  state.activethumb.checked = determineChecked()

  if (state.activethumb.indeterminate)
    state.activethumb.indeterminate = false

  state.activethumb.style.removeProperty('--thumb-transition-duration')
  state.activethumb.style.removeProperty('--thumb-position')
  state.activethumb.removeEventListener('pointermove', dragging)
  state.activethumb = null

  padRelease()
}

Interakcja z elementem została zakończona. Czas ustawić pole zaznaczonej właściwości wejściowej i usunąć wszystkie zdarzenia gestów. Pole wyboru zostanie zmienione na state.activethumb.checked = determineChecked().

determineChecked()

Ta funkcja, wywoływana przez dragEnd, określa, gdzie bieżący ruch mieści się w granicach ścieżki, i zwraca wartość prawda, jeśli jest równy lub ponad połowy ścieżki:

const determineChecked = () => {
  let {bounds} = switches.get(state.activethumb.parentElement)

  let curpos =
    Math.abs(
      parseInt(
        state.activethumb.style.getPropertyValue('--thumb-position')))

  if (!curpos) {
    curpos = state.activethumb.checked
      ? bounds.lower
      : bounds.upper
  }

  return curpos >= bounds.middle
}

Dodatkowe uwagi

Gest przeciągania spowodował duże zadłużenie kodu z powodu wybranej początkowej struktury HTML, a zwłaszcza obpisania danych wejściowych etykietą. Będąc elementem nadrzędnym, etykieta będzie odbierać interakcje kliknięcia po danych wejściowych. Po zakończeniu zdarzenia dragEnd zauważysz, że padRelease() to dziwnie brzmiąca funkcja.

const padRelease = () => {
  state.recentlyDragged = true

  setTimeout(_ => {
    state.recentlyDragged = false
  }, 300)
}

Ma to na celu uwzględnienie etykiety, która powoduje późniejsze kliknięcie, ponieważ odznacza lub zaznacza interakcję użytkownika.

Gdybym zdecydował się to zrobić jeszcze raz, podczas uaktualniania UX mogę zastanowić się nad dostosowaniem DOM za pomocą JavaScriptu, aby utworzyć element, który samodzielnie obsługuje kliknięcia etykiet i nie walczy z wbudowanym zachowaniem.

Najbardziej lubię pisać ten rodzaj JavaScriptu, więc nie chcę zarządzać warunkowym dymkiem zdarzeń:

const preventBubbles = event => {
  if (state.recentlyDragged)
    event.preventDefault() && event.stopPropagation()
}

Podsumowanie

Ten mały element przejścia okazał się do tej pory największą pracą ze wszystkich Wyzwań GUI! Wiesz już, jak to zrobiłem, więc jak to zrobisz 🙂

Stwórzmy różne metody i nauczmy się wszystkiego, jak rozwijać się w internecie. Utwórz demonstrację i udostępnię mi linki na Twitterze, a dodam ją do sekcji remiksów w ramach społeczności poniżej.

Remiksy społeczności

Zasoby

Poszukaj kodu źródłowego aplikacji .gui-switch na GitHubie.