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

الملخّص

تتيح سمة 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.

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