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

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

Yusuke Utsunomiya
Yusuke Utsunomiya

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

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

הדגמה של פורטלים:

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

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

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

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

ראייה היא אמונה: כדאי לכם לראות קודם מה הצגנו בכנס Chrome Dev Summit 2018:

בניווטים קלאסיים, המשתמשים צריכים להמתין עם מסך ריק עד שהדפדפן מסיים את העיבוד של היעד. כשמשתמשים ב-Portals, הם נהנים מאנימציה, בזמן ש-<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. חשוב לוודא שאתם ניגשים אליו עם Chrome מגרסה 85 ואילך, ומפעילים את הדגל הניסיוני.

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

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

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

אנחנו מדברים רבות על מפרט הפורטלים בקבוצת הקהילה Web Incubation 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 חדשים, לכן אנחנו מזמינים אותך לנסות את ה-API ולספר לנו מה דעתך. אם יש לכם משוב או בקשות להוספת תכונות, אתם יכולים להיכנס למאגר GitHub של WICG.