تحكَّم في عملية التمرير - تخصيص تأثيرات السحب لإعادة التحميل والتجاوز

TL;DR

تسمح سمة overscroll-behavior في CSS للمطوّرين بتجاوز سلوك التمرير التلقائي للمحتوى عند الوصول إلى أعلى/أسفل المحتوى في المتصفّح. تشمل حالات الاستخدام إيقاف ميزة "السحب للتحديث" على الأجهزة الجوّالة، وإزالة تأثيرات التوهج عند التمرير السريع والتأثير المطاطي، ومنع التمرير في محتوى الصفحة عندما يكون أسفل نافذة مشروطة/عنصر تراكبي.

الخلفية

حدود الانتقال إلى الأعلى والأسفل وتسلسل الانتقال إلى الأعلى والأسفل

سلسلة الانتقال للأعلى أو للأسفل في Chrome على Android

يُعدّ الانتقال للأعلى أو للأسفل من أكثر الطرق الأساسية للتفاعل مع الصفحة، ولكن قد يكون من الصعب التعامل مع أنماط تجربة المستخدم المعيّنة بسبب السلوكيات الملتوية التلقائية للمتصفّح. على سبيل المثال، خذ درج تطبيقات يحتوي على عدد كبير من العناصر التي قد يحتاج المستخدم إلى الانتقال بينها. عند الوصول إلى أسفل الصفحة، تتوقف حاوية overflow عن التمرير لأنّه لم يعُد هناك محتوى آخر للعرض. بعبارة أخرى، يصل المستخدِم إلى "حدود الانتقال للأعلى أو للأسفل". ولكن لاحِظ ما يحدث إذا واصل المستخدم التمرير. يبدأ المحتوى خلف الدرج بالانتقال للأسفل. يتم التحكّم في عملية التمرير من خلال الحاوية الرئيسية، أي الصفحة الرئيسية نفسها في المثال.

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

تأثير السحب لإعادة التحميل

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

الميزة المخصّصة لإعادة التحميل من خلال التمرير للأعلى في Twitter
عند إعادة تحميل خلاصة في تطبيق الويب التقدّمي
يؤدي الإجراء الأصلي "السحب لإعادة التحميل" في Chrome على Android
إلى إعادة تحميل الصفحة بأكملها.

في حالات مثل PWA، قد يكون من المنطقي إيقاف الإجراء الأصلي "السحب لإعادة التحميل". لماذا؟ في هذا التطبيق، من المحتمل أنّك لا تريد أن يُعيد المستخدم تحميل الصفحة عن طريق الخطأ. هناك احتمال أيضًا أن تظهر لك صورة متحركة لإعادة التحميل مرّتين. بدلاً من ذلك، قد يكون من المفيد تخصيص إجراء المتصفّح، بما يتوافق بشكلٍ أكبر مع هوية الموقع الإلكتروني. يُعدّ هذا النوع من التخصيص صعب التنفيذ. وينتهي الأمر بالمطوّرين بكتابة رمز JavaScript غير ضروري، أو إضافة مستمعي لمس غير السلبيين (الذين يحظرون الانتقال للأعلى أو للأسفل)، أو تثبيت الصفحة بأكملها في 100vw/vh <div> (لمنع الصفحة من تجاوز المساحة المتوفّرة). إنّ لهذه الحلول البديلة تأثيرات سلبية ثبتت صحتهابشكل جيد في أداء الانتقال للأعلى أو للأسفل.

يمكننا تحسين الأداء.

سنعرّفك على overscroll-behavior

السمةoverscroll-behavior هي ميزة جديدة في CSS تتحكّم في سلوك ما يحدث عند الانتقال سريعًا إلى أعلى أو أسفل حاوية (بما في ذلك الصفحة نفسها). يمكنك استخدامها لإلغاء ربط التنقّل وإيقاف/تخصيص الإجراء "السحب لإعادة التحميل" وإيقاف تأثيرات التمديد/التقصير على نظام التشغيل iOS (عندما ينفِّذ Safari overscroll-behavior) وغير ذلك. والأفضل من ذلك هو أنّ استخدام overscroll-behavior لا يؤثّر سلبًا في أداء الصفحة مثل الأساليب غير المشروعة المذكورة في المقدّمة.

يمكن أن تأخذ السمة ثلاث قيم محتملة:

  1. auto: الإعداد التلقائي. قد تنتقل عمليات التمرير التي تبدأ من العنصر إلى العناصر الأصل.
  2. contain: لمنع تسلسل الانتقالات إلى الأسفل لا تنتقل عمليات التمرير إلى العناصر السابقة ولكن يتم عرض التأثيرات المحلية داخل العقدة. على سبيل المثال، تأثير التمييز بين المحتوى المعروض في أعلى الشاشة والمحتوى المعروض في أسفل الشاشة عند التمرير على Android أو تأثير التمرير المرن على iOS الذي يُعلم المستخدم عند بلوغه حدود التمرير. ملاحظة: يؤدي استخدام overscroll-behavior: contain في عنصر html إلى منع إجراءات التنقّل باستخدام التمرير السريع للأسفل أو للأعلى.
  3. none: القيمة نفسها المُستخدَمة في contain، ولكنّها تمنع أيضًا تأثيرات التمرير السريع ضمن العقدة نفسها (مثل تأثير التمرير السريع في Android أو تأثير التمرير المطاطي في iOS).

لنطّلِع على بعض الأمثلة لمعرفة كيفية استخدام overscroll-behavior.

منع الانتقال إلى أعلى أو أسفل الصفحة من الخروج من عنصر في موضع ثابت

سيناريو مربّع المحادثة

يتم أيضًا التمرير للأسفل في المحتوى أسفل نافذة المحادثة :(

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

بالنسبة إلى هذا التطبيق، من الأفضل أن تبقى لفات الشاشة التي تبدأ في مربّع المحادثة ضمن المحادثة. يمكننا إجراء ذلك عن طريق إضافة overscroll-behavior: contain إلى العنصر الذي يحتوي على رسائل المحادثة:

#chat .msgs {
  overflow: auto;
  overscroll-behavior: contain;
  height: 300px;
}

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

سيناريو الظهور فوق المحتوى على الصفحة

هناك شكل آخر من أشكال سيناريو "التمرير للأسفل"، وهو عندما يظهر لك محتوى يتم التمرير فيه للأسفل خلف عنصر مركّب في موضع ثابت. إليك هدية مجانية overscroll-behavior. يحاول المتصفّح تقديم المساعدة، ولكنه ينتهي به الأمر بجعل الموقع الإلكتروني يبدو يتضمّن أخطاء.

مثال: نافذة مشروطة مع overscroll-behavior: contain وبدونها:

قبل: يتم تمرير محتوى الصفحة أسفل الصورة المركبة.
بعد: لا يتم تمرير محتوى الصفحة أسفل العنصر المتراكب.

إيقاف ميزة "السحب لإعادة التحميل"

يمكن إيقاف إجراء السحب لإعادة التحميل من خلال سطر واحد من CSS. ما عليك سوى منع تسلسل الانتقال إلى أعلى أو أسفل الصفحة في العنصر الكامل الذي يحدّد مساحة العرض. في معظم الحالات، يكون ذلك <html> أو <body>:

body {
  /* Disables pull-to-refresh but allows overscroll glow effects. */
  overscroll-behavior-y: contain;
}

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

قبل
بعد

في ما يلي مقتطف من الرمز البرمجي الكامل:

<style>
  body.refreshing #inbox {
    filter: blur(1px);
    touch-action: none; /* prevent scrolling */
  }
  body.refreshing .refresher {
    transform: translate3d(0,150%,0) scale(1);
    z-index: 1;
  }
  .refresher {
    --refresh-width: 55px;
    pointer-events: none;
    width: var(--refresh-width);
    height: var(--refresh-width);
    border-radius: 50%;
    position: absolute;
    transition: all 300ms cubic-bezier(0,0,0.2,1);
    will-change: transform, opacity;
    ...
  }
</style>

<div class="refresher">
  <div class="loading-bar"></div>
  <div class="loading-bar"></div>
  <div class="loading-bar"></div>
  <div class="loading-bar"></div>
</div>

<section id="inbox"><!-- msgs --></section>

<script>
  let _startY;
  const inbox = document.querySelector('#inbox');

  inbox.addEventListener('touchstart', e => {
    _startY = e.touches[0].pageY;
  }, {passive: true});

  inbox.addEventListener('touchmove', e => {
    const y = e.touches[0].pageY;
    // Activate custom pull-to-refresh effects when at the top of the container
    // and user is scrolling up.
    if (document.scrollingElement.scrollTop === 0 && y > _startY &&
        !document.body.classList.contains('refreshing')) {
      // refresh inbox.
    }
  }, {passive: true});
</script>

إيقاف تأثيرَي "توهج التمرير السريع" و"الارتداد"

لإيقاف تأثير الارتداد عند الوصول إلى حدود الانتقال، استخدِم overscroll-behavior-y: none:

body {
  /* Disables pull-to-refresh and overscroll glow effect.
     Still keeps swipe navigations. */
  overscroll-behavior-y: none;
}
قبل: عند الوصول إلى حدود الانتقال، يظهر توهج.
بعد: تم إيقاف ميزة "الإضاءة".

العرض التوضيحي الكامل

باختصار، يستخدم الإصدار الكامل من الإصدار التجريبي من مربّع المحادثة overscroll-behavior لإنشاء صورة متحركة مخصّصة لميزة "السحب لإعادة التحميل" وإيقاف الانتقالات من عنصر مربّع المحادثة المصغّر. ويؤدي ذلك إلى توفير تجربة استخدام مثالية كان من الصعب تحقيقها بدون CSS overscroll-behavior.

عرض العرض التوضيحي | المصدر