מעשי עם פורטלים: ניווט חלק באינטרנט

איך ה-Portals API המוצע יכול לשפר את חוויית המשתמש של הניווט

Yusuke Utsunomiya
Yusuke Utsunomiya

כדי לספק חוויית משתמש טובה, חשוב לוודא שהדפים נטענים במהירות. אבל יש תחום אחד שאנחנו לרוב מתעלמים ממנו – מעברים בין דפים – מה המשתמשים שלנו רואים כשהם עוברים בין דפים.

מטרת ההצעה החדשה ל-API של פלטפורמת האינטרנט, שנקראת Portals, תעזור לכם לפשט את החוויה הזו בזמן שהמשתמשים עוברים בכל האתר.

הצגת פורטלים בפעולה:

הטמעה חלקה וניווט באמצעות פורטלים. נוצר על ידי Adam Argyle.

מה הפורטלים מאפשרים

אפליקציות דף יחיד (SPA) מציעות מעברים נעימים, אבל הן מורכבות יותר ליצירה. קל יותר ליצור אפליקציות עם כמה דפים (MPA), אבל בסופו של דבר יהיו מסכים ריקים בין הדפים.

פורטלים משלבים את היתרונות של שני העולמות: המורכבות הנמוכה של MPA עם המעברים החלקים של SPA. צריך לחשוב עליהם כמו <iframe> בכך שהם מאפשרים הטמעה, אבל שלא כמו <iframe>, הם כוללים גם תכונות שמאפשרות לנווט לתוכן שלהם.

אנשים יכולים להאמין: קודם כול, כדאי לראות את מה שהצגנו בכנס המפתחים של Chrome לשנת 2018:

בניווטים קלאסיים, המשתמשים צריכים להמתין עם מסך ריק עד שהדפדפן מסיים את העיבוד של היעד. בפורטלים, המשתמשים יכולים לחוות אנימציה, בזמן ש-<portal> מעבד מראש את התוכן ויוצר חוויית ניווט חלקה.

לפני Portals, היינו יכולים להציג דף אחר באמצעות <iframe>. אפשר גם להוסיף אנימציות כדי להזיז את המסגרת ברחבי הדף. אבל לא תהיה לכם אפשרות לנווט לתוכן של <iframe>. פורטלים פותרים את הבעיה הזו ומאפשרים תרחישים מעניינים לשימוש.

ניסיון בפורטלים

הפעלה דרך about://flags

כדי לנסות את 'פורטלים' ב-Chrome בגרסה 85 ואילך, צריך להפעיל דגל ניסיוני:

  • מפעילים את הדגל about://flags/#enable-portals לניווטים מאותו מקור.
  • כדי לבדוק ניווטים בין מקורות שונים, צריך להפעיל גם את הדגל about://flags/#enable-portals-cross-origin.

במהלך השלב המוקדם של הניסוי בפורטלים, מומלץ גם להשתמש בספריית נתוני משתמשים נפרדת לחלוטין לבדיקות, באמצעות הגדרת דגל שורת הפקודה --user-data-dir. אחרי שמפעילים את 'פורטלים', מוודאים ב-DevTools שמוצגת לכם הגרסה החדשה של HTMLPortalElement.

צילום מסך של מסוף כלי הפיתוח שבו מוצג HTMLPortalElement

הטמעת פורטלים

נסביר בעזרת דוגמה בסיסית להטמעה.

// 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();
});

פשוט ונוח. כדאי לנסות את הקוד הזה במסוף DevTools. דף Wikipedia אמור להיפתח.

קובץ GIF של הדגמה של תצוגה מקדימה בסגנון פורטל

אם אתם רוצים ליצור משהו כמו שראינו בכנס Chrome Dev Summit, שפועל בדיוק כמו הדמו שלמעלה, הקטע הבא יכול לעניין אתכם.

// 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);

באמצעות פורטלים, קל גם לזהות תכונות כדי לשפר את האתר באופן הדרגתי.

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

כדי להתנסות במהירות ב-Portals, תוכלו להשתמש ב-uskay-portals-demo.glitch.me. חשוב להקפיד לפתוח אותו בגרסה 85 ואילך ולהפעיל את הדגל הניסיוני.

  1. מזינים את כתובת ה-URL שרוצים להציג בתצוגה מקדימה.
  2. לאחר מכן הדף יוטמע כרכיב <portal>.
  3. לוחצים על התצוגה המקדימה.
  4. התצוגה המקדימה תופעל לאחר אנימציה.

קובץ GIF של שימוש בהדגמה של הבאג בשימוש בפורטלים

כדאי לעיין במפרט

אנחנו מדברים רבות על מפרט הפורטלים בקבוצת Web Incubation Community Group‏ (WICG). כדי להבין את הנושא מהר, כדאי לעיין בתרחישי המפתח. אלה שלוש התכונות החשובות שכדאי להכיר:

  • הרכיב <portal>: אלמנט ה-HTML עצמו. ה-API פשוט מאוד. הוא מורכב מהמאפיין src, מהפונקציה activate ומממשק להעברת הודעות (postMessage). activate מקבלת ארגומנטים אופציונליים כדי להעביר נתונים ל-<portal> בזמן ההפעלה.
  • הממשק portalHost: הוספת אובייקט portalHost לאובייקט window. כך תוכלו לבדוק אם הדף מוטמע כרכיב <portal>. הוא גם מספק ממשק להעברת הודעות (postMessage) חזרה למארח.
  • הממשק PortalActivateEvent: אירוע שמופעל כשה-<portal> מופעל. יש פונקציה נהדרת שנקראת adoptPredecessor, שאפשר להשתמש בה כדי לאחזר את הדף הקודם כרכיב <portal>. כך תוכלו ליצור ניווט חלק וחוויות מורכבות בין שני דפים.

עכשיו נבחן את דפוס השימוש הבסיסי. ריכזנו כאן רשימה חלקית של הפעולות שאפשר לבצע באמצעות פורטלים, יחד עם קוד לדוגמה.

התאמה אישית של הסגנון כשהרכיב מוטמע כרכיב <portal>

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

העברת הודעות בין הרכיב <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
});

הפעלת הרכיב <portal> וקבלת האירוע 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;
});

אחזור הקודם

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

איך יודעים שהדף שלכם אומץ כקודם

// 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
    });
  }
});

שילוב של כל התכונות הנתמכות ב-Portals מאפשר ליצור חוויות משתמש מעניינות במיוחד. לדוגמה, הדגמה הבאה מראה איך פורטלים יכולים לספק חוויית משתמש חלקה בין אתר לבין תוכן מוטמע של צד שלישי.

תרחישים לדוגמה ותוכניות

אנחנו מקווים שאהבתם את הסיור הקצר הזה בפורטלים. אנחנו כבר סקרנים לראות מה תייצרו. לדוגמה, כדאי להתחיל להשתמש בפורטלים לצורך ניווטים מורכבים, כמו עיבוד מראש של הדף של המוצר הנמכר ביותר מדף הרשימה של קטגוריית המוצרים.

חשוב לדעת גם שאפשר להשתמש בפורטלים בניווטים בין מקורות שונים, בדיוק כמו ב-<iframe>. לכן, אם יש לכם כמה אתרים שמכילים הפניות זה לזה, תוכלו גם להשתמש בפורטלים כדי ליצור ניווט חלק בין שני אתרים שונים. תרחיש לדוגמה של שימוש במקורות שונים הוא ייחודי מאוד לפורטלים, והוא יכול אפילו לשפר את חוויית המשתמש ב-SPA.

נשמח לקבל משוב

אפשר להתנסות בפורטלים ב-Chrome בגרסה 85 ואילך. המשוב מהקהילה הוא חיוני לעיצוב של ממשקי API חדשים, אז אנחנו מזמינים אתכם לנסות אותו ולספר לנו מה דעתכם. אם יש לכם משוב או בקשות להוספת תכונות, אתם יכולים להיכנס למאגר GitHub של WICG.