ปฏิบัติจริงกับพอร์ทัล: ไปยังส่วนต่างๆ บนเว็บได้อย่างราบรื่น

ดูวิธีที่ Portals API นำเสนอจะช่วยปรับปรุง UX การนำทางของคุณ

การตรวจสอบว่าหน้าเว็บโหลดเร็วเป็นกุญแจสำคัญในการมอบประสบการณ์การใช้งานที่ดีแก่ผู้ใช้ แต่สิ่งหนึ่งที่มักถูกมองข้ามคือการเปลี่ยนหน้าเว็บ ซึ่งเป็นสิ่งที่ผู้ใช้เห็นเมื่อเลื่อนไปมาระหว่างหน้าต่างๆ

ข้อเสนอ API แพลตฟอร์มเว็บใหม่ที่เรียกว่า Portals มีจุดมุ่งหมายเพื่อช่วยแก้ปัญหานี้ด้วยการปรับให้ประสบการณ์การใช้งานมีประสิทธิภาพมากขึ้นเมื่อผู้ใช้ไปยังส่วนต่างๆในเว็บไซต์

ดูการทำงานของพอร์ทัล

การฝังและการนำทางที่ราบรื่นด้วยพอร์ทัล สร้างโดย Adam Argyle

สิ่งที่พอร์ทัลเปิดใช้

แอปพลิเคชันหน้าเดียว (SPA) ทำให้การเปลี่ยนผ่านเป็นไปได้ แต่กลับมีค่าใช้จ่ายที่มีความซับซ้อนในการสร้างมากกว่า แอปพลิเคชันหลายหน้า (MPA) สร้างได้ง่ายกว่ามาก แต่คุณจะเห็นหน้าจอว่างระหว่างหน้า

พอร์ทัลเป็นแพลตฟอร์มที่รวมข้อดีของทั้ง 2 แพลตฟอร์มเข้าด้วยกัน นั่นคือความซับซ้อนต่ำของ MPA กับการเปลี่ยนผ่านที่ราบรื่นของ SPA เปรียบเสมือน <iframe> ในแง่ที่จะอนุญาตให้ฝังได้ แต่ต่างจาก <iframe> ตรงที่มีฟีเจอร์ต่างๆ ไปยังเนื้อหาของตนด้วย

ดีกว่าเห็นภาพตัวอย่าง โปรดดูสิ่งที่เราแสดงในงาน Chrome Dev Summit 2018 ต่อไปนี้

เมื่อใช้การนําทางแบบคลาสสิก ผู้ใช้ต้องรอดูหน้าจอว่างเปล่าจนกว่าเบราว์เซอร์จะแสดงผลปลายทางเสร็จ การใช้พอร์ทัลช่วยให้ผู้ใช้เห็นภาพเคลื่อนไหวขณะที่ <portal> แสดงผลเนื้อหาล่วงหน้าและสร้างประสบการณ์การไปยังส่วนต่างๆ ที่ราบรื่น

ก่อนพอร์ทัล เราสามารถแสดงหน้าเว็บอื่นโดยใช้ <iframe> เรายังเพิ่มภาพเคลื่อนไหวเพื่อย้ายเฟรมไปรอบๆ หน้าได้ด้วย แต่ <iframe> จะไม่อนุญาตให้คุณไปยังส่วนเนื้อหา พอร์ทัลจะปิดช่องว่างนี้ ซึ่งจะทำให้เกิดกรณีการใช้งานที่น่าสนใจ

ลองใช้พอร์ทัล

การเปิดใช้ผ่าน about://flags

ลองใช้พอร์ทัลใน Chrome เวอร์ชัน 85 ขึ้นไปโดยเปิดใช้ Flag ทดลอง ดังนี้

  • เปิดใช้ Flag about://flags/#enable-portals สําหรับการนําทางจากต้นทางเดียวกัน
  • หากต้องการทดสอบการไปยังส่วนต่างๆ แบบข้ามแหล่งที่มา ให้เปิดใช้ Flag about://flags/#enable-portals-cross-origin เพิ่มเติม

ในระยะเริ่มต้นของการทดสอบพอร์ทัลนี้ เราขอแนะนำให้ใช้ไดเรกทอรีข้อมูลผู้ใช้แยกต่างหากสําหรับการทดสอบโดยการตั้งค่า Flag บรรทัดคําสั่ง --user-data-dir เมื่อเปิดใช้พอร์ทัลแล้ว ให้ตรวจสอบในเครื่องมือสำหรับนักพัฒนาเว็บว่าคุณมี 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();
});

ง่ายๆ เท่านี้เอง ลองใช้โค้ดนี้ในคอนโซลเครื่องมือสำหรับนักพัฒนาเว็บ หน้า 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 ขึ้นไปและเปิดFlag ทดลอง

  1. ป้อน URL ที่ต้องการดูตัวอย่าง
  2. จากนั้นระบบจะฝังหน้าเว็บเป็นองค์ประกอบ <portal>
  3. คลิกที่ตัวอย่าง
  4. โดยการแสดงตัวอย่างจะเปิดใช้งานหลังจากภาพเคลื่อนไหว

GIF ของการใช้เดโมข้อบกพร่องของการใช้พอร์ทัล

ดูข้อมูลจำเพาะ

เรากำลังพูดคุยเกี่ยวกับข้อกำหนดของพอร์ทัลใน Web Incubation Community Group (WICG) มาดูสถานการณ์หลักบางส่วนเพื่อให้เข้าใจได้อย่างรวดเร็ว ฟีเจอร์สำคัญ 3 อย่างที่คุณควรทำความคุ้นเคยมีดังนี้

  • องค์ประกอบ <portal>: องค์ประกอบ HTML เอง API นี้ใช้งานง่ายมาก ซึ่งประกอบด้วยแอตทริบิวต์ src, ฟังก์ชัน activate และอินเทอร์เฟซสำหรับการรับส่งข้อความ (postMessage) activate จะใช้อาร์กิวเมนต์ที่ไม่บังคับเพื่อส่งข้อมูลไปยัง <portal> เมื่อเปิดใช้งาน
  • อินเทอร์เฟซ portalHost: เพิ่มออบเจ็กต์ portalHost ลงในออบเจ็กต์ window วิธีนี้จะช่วยให้คุณตรวจสอบว่าหน้าเว็บฝังเป็นองค์ประกอบ <portal> หรือไม่ รวมถึงมีอินเทอร์เฟซสำหรับการส่งข้อความ (postMessage) กลับไปยังโฮสต์ด้วย
  • อินเทอร์เฟซ PortalActivateEvent: เหตุการณ์ที่เริ่มทํางานเมื่อเปิดใช้งาน <portal> มีฟังก์ชันที่ยอดเยี่ยมชื่อ adoptPredecessor ซึ่งคุณใช้เรียกข้อมูลหน้าก่อนหน้าเป็นองค์ประกอบ <portal> ได้ วิธีนี้ช่วยให้คุณสร้างการนำทางที่ราบรื่นและประสบการณ์การเขียนระหว่างหน้า 2 หน้าได้

เราลองมาดูให้ไกลกว่ารูปแบบการใช้งานพื้นฐานกัน ต่อไปนี้เป็นรายการสิ่งที่คุณทําได้โดยใช้พอร์ทัลโดยสังเขปพร้อมตัวอย่างโค้ด

ปรับแต่งสไตล์เมื่อฝังเป็นองค์ประกอบ <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> ดังนั้น หากคุณมีเว็บไซต์หลายแห่งที่อ้างอิงถึงกัน คุณสามารถใช้พอร์ทัลเพื่อสร้างการนําทางที่ราบรื่นระหว่างเว็บไซต์ 2 แห่งที่แตกต่างกันได้ Use Case แบบข้ามแหล่งที่มานี้มีความเฉพาะเจาะจงมากสำหรับพอร์ทัล และยังสามารถปรับปรุงประสบการณ์ของผู้ใช้ SPA ได้อีกด้วย

ยินดีรับฟังความคิดเห็นจากคุณ

พอร์ทัลพร้อมให้ทดลองใช้แล้วใน Chrome เวอร์ชัน 85 ขึ้นไป ความคิดเห็นจากชุมชนมีความสําคัญอย่างยิ่งต่อการออกแบบ API ใหม่ ดังนั้นโปรดลองใช้และบอกเราว่าคุณคิดอย่างไร หากมีคำขอฟีเจอร์หรือความคิดเห็น โปรดไปที่ที่เก็บ GitHub ของ WICG