Praktyczna obsługa portali: łatwa nawigacja w internecie

Dowiedz się, jak proponowany interfejs Portals API może poprawić wrażenia użytkownika związane z nawigacją.

Yusuke Utsunomiya
Yusuke Utsunomiya

Szybkie wczytywanie stron to klucz do zapewnienia użytkownikom wygodnej obsługi. Często pomijamy jednak obszar przejścia między stronami – to, co użytkownicy widzą, gdy poruszają się po stronach.

Nowa propozycja interfejsu API platformy internetowej, czyli Portale, ma na celu usprawnienie korzystania z witryny przez użytkowników.

Jak działają Portals:

Płynne umieszczanie i przechodzenie do Portali. Utworzone przez Adama Argyle.

Co umożliwiają portale

Aplikacje jednostronicowe (SPA) zapewniają ładne przejścia, ale ich tworzenie jest bardziej skomplikowane. Aplikacje wielostronicowe (MPA) są znacznie łatwiejsze do tworzenia, ale w efekcie kończy się to pustymi ekranami między stronami.

Portale łączą zalety obu formatów: niską złożoność MPA z płynnymi przejściami SPA. Są one podobne do <iframe>, ponieważ umożliwiają umieszczanie, ale w przeciwieństwie do <iframe> mają też funkcje umożliwiające nawigację po treściach.

Widzieć, to wiedzieć: najpierw sprawdź, co prezentowaliśmy na konferencji Chrome Dev Summit 2018:

W przypadku klasycznej nawigacji użytkownicy muszą czekać na pustym ekranie, aż przeglądarka zakończy renderowanie miejsca docelowego. Portale pozwalają użytkownikom obejrzeć animację, a <portal> wstępnie renderuje treści i zapewnia płynną nawigację.

Przed Portalami można było renderować inną stronę za pomocą <iframe>. Mogliśmy też dodać animacje, aby przesuwać ramkę po stronie. Nie możesz jednak przeglądać treści w takim <iframe>. Portale wypełniają tę lukę, oferując ciekawe przypadki użycia.

Wypróbuj portale

Włączanie za pomocą about://flags

Wypróbuj Portals w Chrome 85 i nowszych wersjach, włączając flagę eksperymentalną:

  • Włącz flagę about://flags/#enable-portals w przypadku nawigacji z tej samej domeny.
  • Aby przetestować nawigację między domenami, włącz dodatkowo flagę about://flags/#enable-portals-cross-origin.

W tej wczesnej fazie eksperymentu dotyczącego Portals zalecamy też używanie całkowicie oddzielnego katalogu danych użytkownika do testów. Aby to zrobić, ustaw flagę wiersza poleceń --user-data-dir. Po włączeniu Portali sprawdź w Narzędziach deweloperskich, czy masz nową błyszczącą ikonę HTMLPortalElement.

Zrzut ekranu konsoli DevTools z elementem HTMLPortalElement

Wdrażanie portali

Przyjrzyjmy się podstawowemu przykładowi implementacji.

// Create a portal with the wikipedia page, and embed it
// (like an iframe). You can also use the <portal> tag instead.
portal = document.createElement('portal');
portal.src = 'https://en.wikipedia.org/wiki/World_Wide_Web';
portal.style = '...';
document.body.appendChild(portal);

// When the user touches the preview (embedded portal):
// do fancy animation, e.g. expand …
// and finish by doing the actual transition.
// For the sake of simplicity, this snippet will navigate
// on the `onload` event of the Portals element.
portal.addEventListener('load', (evt) => {
   portal.activate();
});

To bardzo proste. Spróbuj wpisać ten kod w konsoli Narzędzi deweloperskich. Otworzy się strona w Wikipedii.

GIF z demonstracją stylu portalu

Jeśli chcesz stworzyć coś podobnego do tego, co pokazaliśmy na konferencji Chrome Dev Summit, czyli coś, co działa tak samo jak w powyższym demonstracyjnym pliku, ten fragment kodu może Cię zainteresować.

// Adding some styles with transitions
const style = document.createElement('style');
style.innerHTML = `
  portal {
    position:fixed;
    width: 100%;
    height: 100%;
    opacity: 0;
    box-shadow: 0 0 20px 10px #999;
    transform: scale(0.4);
    transform-origin: bottom left;
    bottom: 20px;
    left: 20px;
    animation-name: fade-in;
    animation-duration: 1s;
    animation-delay: 2s;
    animation-fill-mode: forwards;
  }
  .portal-transition {
    transition: transform 0.4s;
  }
  @media (prefers-reduced-motion: reduce) {
    .portal-transition {
      transition: transform 0.001s;
    }
  }
  .portal-reveal {
    transform: scale(1.0) translateX(-20px) translateY(20px);
  }
  @keyframes fade-in {
    0%   { opacity: 0; }
    100% { opacity: 1; }
  }
`;
const portal = document.createElement('portal');
// Let's navigate into the WICG Portals spec page
portal.src = 'https://wicg.github.io/portals/';
// Add a class that defines the transition. Consider using
// `prefers-reduced-motion` media query to control the animation.
// https://developers.google.com/web/updates/2019/03/prefers-reduced-motion
portal.classList.add('portal-transition');
portal.addEventListener('click', (evt) => {
  // Animate the portal once user interacts
  portal.classList.add('portal-reveal');
});
portal.addEventListener('transitionend', (evt) => {
  if (evt.propertyName == 'transform') {
    // Activate the portal once the transition has completed
    portal.activate();
  }
});
document.body.append(style, portal);

Możesz też łatwo wykrywać funkcje, aby stopniowo ulepszać witrynę za pomocą Portals.

if ('HTMLPortalElement' in window) {
  // If this is a platform that have Portals...
  const portal = document.createElement('portal');
  ...
}

Jeśli chcesz szybko sprawdzić, jak działa Portals, skorzystaj z uskay-portals-demo.glitch.me. Upewnij się, że korzystasz z Chrome w wersji 85 lub nowszej i włącz opcję eksperymentalną.

  1. Wpisz adres URL, którego podgląd chcesz wyświetlić.
  2. Strona zostanie wtedy umieszczona jako element <portal>.
  3. Kliknij podgląd.
  4. Podgląd zostanie aktywowany po animacji.

GIF pokazujący używanie demo glitcha w Portalach

Sprawdź specyfikację

W ramach grupy społeczności Web Incubation Community Group (WICG) aktywnie omawiamy specyfikację Portals. Aby szybko się zapoznać z tą funkcją, zapoznaj się z kilkoma kluczowymi scenariuszami. Oto 3 ważne funkcje, które warto poznać:

  • Element <portal>: sam element HTML. Interfejs API jest bardzo prosty. Składa się z atrybutu src, funkcji activate i interfejsu do przesyłania wiadomości (postMessage). Funkcja activate przyjmuje opcjonalny argument, który służy do przekazywania danych do funkcji <portal> po jej aktywacji.
  • Interfejs portalHost: dodaje obiekt portalHost do obiektu window. Dzięki temu możesz sprawdzić, czy strona jest umieszczona jako element <portal>. Zapewnia też interfejs do wysyłania wiadomości (postMessage) do gospodarza.
  • Interfejs PortalActivateEvent: zdarzenie, które uruchamia się, gdy aktywowane jest <portal>. Istnieje przydatna funkcja adoptPredecessor, która umożliwia pobranie poprzedniej strony jako elementu <portal>. Dzięki temu możesz tworzyć płynną nawigację i kompozycje między 2 stronami.

Przyjrzyjmy się bliżej podstawowym wzorcom użytkowania. Oto niepełna lista tego, co możesz osiągnąć dzięki portom, wraz z przykładowym kodem.

Dostosuj styl, gdy jest umieszczony jako element <portal>

// Detect whether this page is hosted in a portal
if (window.portalHost) {
  // Customize the UI when being embedded as a portal
}

Komunikaty między elementem <portal>portalHost

// Send message to the portal element
const portal = document.querySelector('portal');
portal.postMessage({someKey: someValue}, ORIGIN);

// Receive message via window.portalHost
window.portalHost.addEventListener('message', (evt) => {
  const data = evt.data.someKey;
  // handle the event
});

Aktywowanie elementu <portal> i odbieranie zdarzenia portalactivate

// You can optionally add data to the argument of the activate function
portal.activate({data: {somekey: 'somevalue'}});

// The portal content will receive the portalactivate event
// when the activate happens
window.addEventListener('portalactivate', (evt) => {
  // Data available as evt.data
  const data = evt.data;
});

Pobieram poprzednią wersję

// Listen to the portalactivate event
window.addEventListener('portalactivate', (evt) => {
  // ... and creatively use the predecessor
  const portal = evt.adoptPredecessor();
  document.querySelector('someElm').appendChild(portal);
});

Fakt, że strona została traktowana jako poprzednika

// The activate function returns a Promise.
// When the promise resolves, it means that the portal has been activated.
// If this document was adopted by it, then window.portalHost will exist.
portal.activate().then(() => {
  // Check if this document was adopted into a portal element.
  if (window.portalHost) {
    // You can start communicating with the portal element
    // i.e. listen to messages
    window.portalHost.addEventListener('message', (evt) => {
      // handle the event
    });
  }
});

Łącząc wszystkie funkcje obsługiwane przez portale, możesz stworzyć atrakcyjne wrażenia dla użytkowników. Na przykład w tym filmie pokazujemy, jak Portale mogą zapewnić użytkownikom płynne wrażenia podczas korzystania z witryny i osadzonych treści innych firm.

Przypadki użycia i plany

Mamy nadzieję, że spodobała Ci się ta krótka prezentacja Portals. Nie możemy się doczekać, żeby zobaczyć, co wymyślisz. Możesz na przykład zacząć używać portali do skomplikowanych działań nawigacyjnych, takich jak wstępna renderyzacja strony bestsellerowego produktu na stronie kategorii produktów.

Kolejną ważną rzeczą jest to, że portali można używać w przeglądaniu między domenami, tak jak w przypadku <iframe>. Jeśli więc masz wiele witryn, które się wzajemnie odnoszą, możesz korzystać z portali, by płynnie przechodzić między nimi. Ten przypadek użycia w wielu domenach jest bardzo charakterystyczny dla Portals i może nawet poprawić wrażenia użytkowników korzystających z aplikacji SPA.

Czekamy na Twoją opinię

Portale są gotowe do eksperymentowania w Chrome 85 i nowszych wersjach. Opinie społeczności są kluczowe dla projektowania nowych interfejsów API, dlatego wypróbuj je i powiedz nam, co o nich myślisz. Jeśli chcesz zasugerować nową funkcję lub podzielić się opinią, odwiedź repozytorium WICG na GitHubie.