التغييرات التي طرأت على حدث ScrollEvent في Chrome 105

جو ميدلي
جو ميدلي

يقدم Chrome 105 طريقتين جديدتين على NavigateEvent في واجهة برمجة تطبيقات التنقل (التي تم تقديمها في الإصدار 102) لتحسين الأساليب التي أثبتت وجود مشكلات من الناحية العملية. intercept()، التي تسمح للمطوّرين بالتحكّم في الحالة التي تظهر بعد التنقّل، ستحلّ محلّ سياسة transitionWhile() التي ثبت أنّها صعبة الاستخدام. وتحلّ الطريقة scroll() التي يتم تمريرها إلى علامة ارتساء محدّدة في عنوان URL محلّ طريقة restoreScroll() التي لا تعمل مع جميع أنواع التنقّل.

وسوف أشرح في هذه المقالة المشاكل المتعلقة بكليهما وكيف تعمل الطرق الجديدة على حل تلك المشكلات.

تعترض طريقة NavigateEvent.trasitionWhile()، التي تم تقديمها مع واجهة برمجة تطبيقات التنقل في Chrome 102، التنقل في عمليات النقل من جهة العميل في تطبيقات الصفحة الواحدة. وسيطته الأولى هي وعد يرسل إشارة إلى المتصفح وإلى أجزاء أخرى من تطبيق الويب تفيد باكتماله.

وقد كان هذا الأمر سيئًا من الناحية العملية. ضع في اعتبارك نمط الترميز الشائع هذا:

event.transitionWhile((async () => {
  doSyncStuff();
  await doAsyncStuff();
})());

هذا يعادل عمليًا التعليمة البرمجية أدناه. حيث يتسبب في تشغيل جزء من التنقل قبل أن تدرك واجهة برمجة التطبيقات أن مطوّر البرامج ينوي اعتراض التنقل.

doSyncStuff();
event.transitionWhile((async () => {
  await doAsyncStuff();
})());

أحد الأمثلة على تلف تطبيق ما هو في منطق استعادة التمرير حيث يلتقط مواضع التمرير بعد تغيير DOM، بدلاً من ذي قبل.

التغييرات التي أُجريت

لاستبدال transitionWhile()، تقدم المواصفات الحالية NavigateEvent.intercept(). تستخدم الطريقة الجديدة معالجًا بالإضافة إلى السمتَين focusReset وscrollRestoration المتوافقة مع السمة transitionWhile(). يتم تشغيل المعالج الجديد دائمًا بعد إتمام الانتقال، ويتم اختيار مواضع التمرير، ما يؤدي إلى تجنُّب المشاكل في transitionWhile().

لا تزال طريقة transitionWhile() متاحة، ولكن تم إيقافها نهائيًا وستتم إزالتها في الإصدار 108 من Chrome.

استخدام تقاطع()

يخضع NavigateEvent.intercept() للقيود نفسها المفروضة على transitionWhile()، لأنّه لا يمكن استدعاؤه في جميع أحداث التنقّل. لا يمكن اعتراض عمليات التنقل المشتركة المصدر ولا يمكن إجراء عمليات اجتياز المستندات عبر المستندات نفسها. سيؤدي ذلك إلى إنشاء DOMException من النوع "SecurityError".

لاستخدام intercept()، ما عليك سوى ضبط المعالج المخصّص عند طلبه.

navigation.addEventListener("navigate", event => {
  event.intercept({
    async handler() {
      doSyncStuff();
      await doAsyncStuff();
    }
  });
});

يعالج المتصفِّح بشكلٍ كامل عملية التنقّل، مثل الانتقال من أعلى الصفحة إلى علامة ارتساء (اسمه عند الانتقال من /a إلى /a#id)، حتى في تطبيق من صفحة واحدة. أمّا الانتقال إلى موضع ثابت في "صفحة" أخرى (من /a إلى /b#id)، وهو أمر بسيط للتطبيقات المتعدّدة الصفحات، فهو أكثر تعقيدًا بالنسبة إلى التطبيقات من صفحة واحدة. يجب أن يعترض التطبيق الانتقال إلى /b#id باستخدام NavigateEvent.transitionWhile()، ثم يتصل NavigateEvent.restoreScroll() لعرض الإعلان الثابت. وكما ذكرنا أعلاه، من الصعب إجراء ذلك في الوقت الحالي.

التغييرات التي أُجريت

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

استخدام Scroll()

وسيحاول المتصفّح تلقائيًا معالجة عملية التمرير، وذلك بعد تنفيذ جهة الاعتراض. إذا أردت إجراء عملية الانتقال بنفسك، اضبط scroll على "manual"، ثم استدعِ NavigateEvent.scroll() عندما يحاول المتصفّح ضبط موضع التمرير.

navigation.addEventListener("manual", event => {
  scroll: "manual",
  event.intercept({
    async handler() {
      doSyncStuff();
      // Handle scrolling earlier than by default:
      event.scroll();
      await doAsyncStuff();
    }
  });
});

لا تزال طريقة restoreScroll() متاحة، ولكن تم إيقافها نهائيًا وستتم إزالتها في الإصدار 108 من Chrome.

الخاتمة

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

تصوير تيم غاو على قناة Unsplash