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

الملخّص

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

الخلفية

حدود التمرير وتسلسل التمرير

تسلسل التمرير على Chrome Android:

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

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

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

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

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

بالنسبة إلى مواقف مثل PWA في Twitter، قد يكون من المنطقي إيقاف إجراء السحب لإعادة التحميل المحلي. لماذا؟ في هذا التطبيق، ربما لا تريد أن يحدّث المستخدم الصفحة عن طريق الخطأ. وهناك أيضًا إمكانية مشاهدة رسم متحرك للتحديث المزدوج! بدلاً من ذلك، قد يكون من الأفضل تخصيص إجراء المتصفح، لكي تتم محاذاته بشكل وثيق مع العلامة التجارية للموقع. أما الجزء المؤسف، فهو أنّ هذا النوع من التخصيص أصبح معقدًا، فانتهى الأمر بالمطوّرين بكتابة 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. لا شيء - مثل 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.

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