التدريب العملي على البوابات: التنقل السلس على الويب

تعرَّف على كيفية تحسين واجهة برمجة التطبيقات Portals API المقترَحة لتجربة التنقّل.

إنّ التأكّد من تحميل صفحاتك بسرعة هو مفتاح تقديم تجربة مستخدم جيدة. ولكن هناك جانبًا غالبًا ما نغفل عنه، وهو عمليات انتقال الصفحة، أي ما يظهر للمستخدمين عند تنقلهم بين الصفحات.

يهدف اقتراح جديد لواجهة برمجة تطبيقات منصّة الويب يُطلق عليه بوابات إلى المساعدة في ذلك من خلال تبسيط التجربة أثناء تنقّل المستخدمين في موقعك الإلكتروني.

إليك أمثلة على استخدام البوابات:

عمليات دمج وتنقّل سلسة باستخدام بوابات أنشأ هذه المقالة آدم أرجيل.

الميزات التي تتيحها البوابات

توفّر تطبيقات الصفحة الواحدة انتقالات رائعة، ولكنّها تتطلّب مزيدًا من التعقيد في عملية الإنشاء. إنّ التطبيقات المتعدّدة الصفحات (MPA) أسهل بكثير في الإنشاء، ولكنّك تنتهي بظهور شاشات فارغة بين الصفحات.

توفّر البوابات أفضل ما في الحالتَين: انخفاض تعقيد تطبيقات MPA مع الانتقالات السلسة لتطبيقات SPA. يمكنك اعتبارها مثل <iframe> من حيث أنّها تتيح التضمين، ولكن على عكس <iframe>، تتضمّن أيضًا ميزات للانتقال إلى المحتوى.

الاطّلاع على المحتوى هو أفضل طريقة للتعرّف عليه: يُرجى الاطّلاع أولاً على ما عرضناه في قمة مطوّري Chrome لعام 2018:

باستخدام عمليات التنقّل الكلاسيكية، على المستخدمين الانتظار أمام شاشة فارغة إلى أن ينتهي المتصفّح من عرض الوجهة. من خلال بوابات الواقع المعزّز، يحصل المستخدمون على تجربة متحركة، بينما يُعدّل <portal> المحتوى مسبقًا ويوفّر تجربة تنقّل سلسة.

قبل ظهور بوابات Chrome، كان بإمكاننا عرض صفحة أخرى باستخدام <iframe>. كان بإمكاننا أيضًا إضافة صور متحركة لنقل الإطار حول الصفحة. ولن تتمكن من التنقّل في محتوى <iframe>. تُغلق البوابات هذه الفجوة، ما يتيح حالات استخدام مثيرة للاهتمام.

تجربة "المواقع الإلكترونية"

التفعيل من خلال about://flags

يمكنك تجربة ميزة "المنافذ" في الإصدار 85 من Chrome والإصدارات الأحدث من خلال تفعيل علامة تجريبية:

  • فعِّل العلامة about://flags/#enable-portals لعمليات التنقّل من المصدر نفسه.
  • لاختبار عمليات التنقّل بين المواقع الإلكترونية، فعِّل العلامة about://flags/#enable-portals-cross-origin بالإضافة إلى ذلك.

خلال هذه المرحلة المبكرة من تجربة "المنافذ"، ننصح أيضًا باستخدام دليل بيانات مستخدمين منفصل تمامًا لاختباراتك من خلال ضبط علامة سطر الأوامر --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 والذي يعمل بالطريقة نفسها الموضّحة في العرض التقديمي أعلاه، قد تهمّك المقتطفة التالية.

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

إذا أردت تجربة بوابات Google بسرعة، جرِّب استخدام uskay-portals-demo.glitch.me. احرص على استخدام الإصدار 85 من Chrome أو الإصدارات الأحدث وتفعيل الميزة التجريبية.

  1. أدخِل عنوان URL الذي تريد معاينته.
  2. وسيتم بعد ذلك تضمين الصفحة كعنصر <portal>.
  3. انقر على المعاينة.
  4. سيتم تفعيل المعاينة بعد عرض صورة متحركة.

ملف GIF لعرض تجريبي يتضمّن خللًا في استخدام &quot;بوابات Google&quot;

الاطّلاع على المواصفات

نحن نناقش بنشاط مواصفات البوابات في مجموعة Web Incubation Community Group (WICG). للتعرّف بسرعة على هذه الميزات، اطّلِع على بعض السيناريوهات الرئيسية. في ما يلي الميزات الثلاث المهمة التي يجب التعرّف عليها:

  • عنصر <portal>: عنصر HTML نفسه. واجهة برمجة التطبيقات بسيطة جدًا. يتألّف من سمة 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
    });
  }
});

من خلال الجمع بين جميع الميزات المتوافقة مع "المَعلمات"، يمكنك إنشاء تجارب رائعة للمستخدمين. على سبيل المثال، يوضّح العرض الترويجي أدناه كيف يمكن أن توفّر بوابات تجربة مستخدم سلسة بين موقع إلكتروني ومحتوى مضمّن تابع لجهة خارجية.

حالات الاستخدام والخطط

نأمل أن تكون قد استمتعت بهذه الجولة الموجزة حول "المنافذ". نحن في انتظار رؤية ما لديكم من أفكار جديدة. على سبيل المثال، قد تحتاج إلى بدء استخدام بوابات للتنقّل غير البسيط، مثل: التقديم المُسبَق لصفحة المنتج الأكثر مبيعًا من صفحة بيانات فئة المنتج.

من المعلومات المهمة الأخرى التي يجب معرفتها أنّه يمكن استخدام البوابات في عمليات التنقّل بين مصادر مختلفة، تمامًا مثل <iframe>. وبالتالي، إذا كانت لديك مواقع إلكترونية متعددة تشير إلى بعضها، يمكنك أيضًا استخدام البوابات لإنشاء عمليات انتقال سلسة بين موقعَين إلكترونيَين مختلفَين. إنّ حالة الاستخدام هذه التي تتضمن مصادر متعددة فريدة جدًا لبوابات التطبيقات، ويمكن أن تحسّن أيضًا تجربة المستخدم في تطبيقات SPA.

نرحّب بالملاحظات والآراء

أصبحت البوابات جاهزة للتجربة في الإصدار 85 من Chrome والإصدارات الأحدث. إنّ الملاحظات الواردة من المنتدى مهمة جدًا لتصميم واجهات برمجة التطبيقات الجديدة، لذا يُرجى تجربتها وإعلامنا برأيك. إذا كان لديك أي طلبات ميزات أو ملاحظات، يُرجى الانتقال إلى مستودع GitHub الخاص بمبادرة Web Interoperability Consortium (WICG).