שליטה בגלילה – התאמה אישית של אפקטים של 'משיכה לרענון' ו'אפשרויות נוספות'

אמ;לק

המאפיין שירות CSS overscroll-behavior מאפשר למפתחים לבטל את התנהגות ברירת המחדל של גלילת גלישה כשמגיעים לחלק העליון/התחתון של הדפדפן תוכן. התרחישים לדוגמה כוללים השבתה של האפשרות 'משיכה לרענון' בנייד, הסרת אפקטים של זוהר יתר ואפקטים של גומייה, ומונעת גלילה של תוכן הדף כשהוא מופיע מתחת לחלון או לשכבת-על.

רקע

גבולות גלילה ושרשורי גלילה

גלילה בשרשורים ב-Chrome Android.

גלילה היא אחת מהדרכים הבסיסיות ביותר לבצע אינטראקציה בדף, אבל לפעמים קשה להתמודד עם דפוסי חוויית משתמש מסוימים בגלל המאפיינים המוזרים של הדפדפן כברירת מחדל. לדוגמה, ניקח חלונית הזזה לאפליקציות שמכילה מספר גדול של פריטים שהמשתמש צריך לגלול בהם. כשהם מגיעים לתחתית, עודף גלילה מפסיק לגלול כי אין עוד תוכן לצריכה. במילים אחרות, המשתמש מגיע ל'גבול גלילה'. אבל כדאי לשים לב מה קורה אם המשתמש ממשיך לגלול. התוכן מאחורי חלונית ההזזה מתחיל לגלול! הגלילה היא השתלט על מאגר ההורה; את הדף הראשי עצמו בדוגמה.

מתברר שההתנהגות הזו נקראת שרשור גלילה. ברירת המחדל של הדפדפן ההתנהגות בזמן גלילה בתוכן. פעמים רבות ברירת המחדל היא די נחמדה, ולפעמים זה לא רצוי או אפילו בלתי צפוי. ייתכן שאפליקציות מסוימות ירצו לספק חוויית משתמש שונה כשהמשתמש מגיע לגבול גלילה.

אפקט המשיכה לרענון

'משיכה לרענון' היא תנועה אינטואיטיבית שפופולרית על ידי אפליקציות לנייד, כגון Facebook ו-Twitter. משיכה למטה של פיד ברשתות חברתיות והפצת מודעות מייצרות כדי לטעון פוסטים חדשים יותר. למעשה, חוויית המשתמש הספציפית הזו כל כך פופולריות שדפדפנים לנייד כמו Chrome ב-Android אימצו את אותו אפקט. החלקה למטה בחלק העליון של הדף מרעננת את הדף כולו:

משיכה לרענון מותאמת אישית של Twitter
כשמרעננים פיד אפליקציית ה-PWA שלהם.
פעולת המשיכה לרענון המקורית של Chrome Android
מרעננת את כל התוכן הדף הזה.

במצבים כמו PWA של Twitter, אולי כדאי להשבית את פעולת המשיכה לרענון המקורית. למה? כאן כנראה שאתם לא רוצים שהמשתמש ירענן את הדף בטעות. יש יש גם את הפוטנציאל לראות אנימציה של רענון כפול! לחלופין, ייתכן להתאים אישית את פעולת הדפדפן, ולהציג אותה באופן קרוב יותר מיתוג. החבל הוא שהתאמה אישית כזו וקשה למשוך. בסופו של דבר המפתחים כותבים JavaScript מיותר, לא פסיבי Touch Listeners (שחוסמים גלילה), או מדביקים את כל הדף ב-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

לצפייה בהדגמה | מקור