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

TL;DR

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

الخلفية

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

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

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

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

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

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

عملية إعادة تحميل مخصّصة من Twitter
عند إعادة تحميل خلاصة في تطبيق الويب التقدّمي (PWA)
يؤدي إجراء السحب إلى التحديث الأصلي في 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.

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