स्क्रोल स्नैप स्टेट सिंक

यूज़र इंटरफ़ेस (यूआई) की स्थिति को स्क्रोल किए जा सकने वाले कंटेनर की स्नैप पोज़िशन के साथ सिंक करने के लिए, पहले जटिल स्क्रोल इवेंट लिसनर, स्क्रोल ऑफ़सेट की मैन्युअल कैलकुलेशन, और इंटरसेक्शन ऑब्ज़र्वर की ज़रूरत होती थी. scrollsnapchange इवेंट, यह पता लगाने का एक नेटिव और असरदार तरीका है कि स्क्रोलर कब किसी नए स्नैप टारगेट पर सेटल हुआ है. इससे साइडबार को सिंक करने या विषय सूची में ऐक्टिव सेक्शन को हाइलाइट करने में मदद मिलती है.

लागू करना

1. सीएसएस में स्क्रोल स्नैप को कॉन्फ़िगर करना

कंटेनर में scroll-snap-type तय होना चाहिए. साथ ही, ब्राउज़र के लिए स्नैप टारगेट ट्रैक करने के लिए, चाइल्ड एलिमेंट में scroll-snap-align होना चाहिए. विषय सूची वाले किसी लंबे लेख में, सेक्शन हेडर को व्यूपोर्ट के सबसे ऊपर स्नैप करने के लिए, इसका इस्तेमाल किया जा सकता है.

main {
    /* Enable scroll snapping on the container */  
  scroll-snap-type: y proximity;
  overflow-y: auto;
}

h2 {
  /* Define how headers align when snapped */
  scroll-snap-align: start;
}

2. स्नैप में होने वाले बदलावों को सुनें

जब उपयोगकर्ता स्क्रोल करना बंद कर दे और ब्राउज़र किसी नए एलिमेंट पर स्नैप करे, तब प्रतिक्रिया देने के लिए स्क्रोल कंटेनर पर scrollsnapchange इवेंट का इस्तेमाल करें. टीओसी के डेमो में, हम इसका इस्तेमाल साइडबार में मौजूद ऐक्टिव लिंक को हाइलाइट करने के लिए करते हैं.

<!-- MANDATORY: Wrap table of contents links inside a proper navigation landmark -->
<nav aria-label="Table of contents">
  <ul>
    <li><a href="#section-1" aria-current="location">Section 1</a></li>
    <li><a href="#section-2">Section 2</a></li>
  </ul>
</nav>
const main = document.getElementById('main');
const links = document.querySelectorAll('nav a');

// The event fires when the scroller settles on a new snap target
main.addEventListener('scrollsnapchange', (event) => {
  // Use snapTargetBlock for vertical or snapTargetInline for horizontal
  const snappedHeader = event.snapTargetBlock;
  
  if (snappedHeader) {
    setSelectedParagraph(snappedHeader.id);
  }
});

सुलभता

विषय सूची के लिए, पक्का करें कि साइडबार के लिंक चालू होने पर, aria-current="true" या aria-current="location" का इस्तेमाल करें.

इसके अलावा, scroll-snap-type के लिए mandatory वैल्यू का इस्तेमाल करते समय सावधानी बरतें. ऐसा इसलिए, क्योंकि स्क्रीन से ज़्यादा लंबा होने पर, स्नैप-पॉइंट के बीच का कॉन्टेंट ऐक्सेस नहीं किया जा सकता.

फ़ॉलबैक रणनीतियां

अगर scrollsnapchange काम नहीं करता है, तो IntersectionObserver का इस्तेमाल करके पता लगाएं कि फ़िलहाल स्क्रोलर में सबसे ऊपर कौनसा एलिमेंट है. ध्यान दें कि यह scrollsnapchange से अलग है, क्योंकि यह स्क्रोल होने के दौरान ट्रिगर होगा, न कि स्क्रोल होने के बाद.

// Feature detect support for scroll snap events
if (!('onscrollsnapchange' in HTMLElement.prototype)) {
  const observer = new IntersectionObserver(
    () => {
      // Each time the set of intersecting headers changes, find the top
      // header that is visible.
      const topEntry = [...headers].reduce((currentTop, header) => {
        // Use the bottom to handle scrolling up, when the top is still offscreen
        const {bottom} = header.getBoundingClientRect();
        // Don't match if the header's bottom is above the scrollport
        if (bottom < 0) return;
        if (!currentTop) return header;
        return bottom <
          currentTop.getBoundingClientRect().bottom
          ? header
          : currentTop;
      }, undefined);
      if (topEntry) setSelectedParagraph(topEntry.id);
    },
    { root: main, threshold: 0.9 // Adjust based on your use case },
  );

  // Observe all snap targets (e.g., section headers)
  document.querySelectorAll('h2').forEach(header => observer.observe(header));
}