Kullanıcı arayüzü durumunu kaydırılabilir bir kapsayıcının tutturma konumuyla senkronize etmek için geleneksel olarak karmaşık kaydırma etkinliği işleyiciler, kaydırma ofsetlerinin manuel hesaplamaları ve kesişim gözlemcileri gerekiyordu. scrollsnapchange etkinliği, kaydırıcının yeni bir yakalama hedefine ne zaman yerleştiğini algılamanın yerel ve verimli bir yolunu sunar. Bu sayede, kenar çubuklarını senkronize etmek veya içindekiler tablosundaki etkin bölümü vurgulamak için kullanışlıdır.
Uygulama
1. CSS'de kaydırarak tutturmayı yapılandırma
Tarayıcının kaydırma hedeflerini izleyebilmesi için kapsayıcıda scroll-snap-type tanımlanmış olmalı ve scroll-snap-align içeren alt öğeler bulunmalıdır. İçindekiler tablosu içeren uzun bir makalede, bölüm başlıklarını görüntü alanının üst kısmına sabitlemek için bu özelliği kullanabilirsiniz.
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. Snap değişikliklerini dinleme
Kullanıcı kaydırmayı bitirdiğinde ve tarayıcı yeni bir öğeye geçtiğinde tepki vermek için kaydırma kapsayıcısında scrollsnapchange etkinliğini kullanın. İçindekiler tablosu demomuzda, kenar çubuğundaki etkin bağlantıyı vurgulamak için bu özelliği kullanıyoruz.
<!-- 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);
}
});
Erişilebilirlik
İçindekiler tablosu için kenar çubuğu bağlantılarının etkin olduklarında aria-current="true" veya aria-current="location" kullandığından emin olun.
Ayrıca, scroll-snap-type için mandatory değerini kullanırken dikkatli olun. Bu değer, ekrandan daha uzun olduğunda tutturma noktaları arasındaki içeriğin erişilemez hale gelmesine neden olabilir.
Yedek stratejiler
scrollsnapchange desteklenmiyorsa kaydırıcının en üstünde hangi öğenin bulunduğunu tespit etmek için IntersectionObserver kullanın. Bu, scrollsnapchange'ten farklı bir davranıştır. Çünkü bu, yalnızca kaydırma işlemi tamamlandığında değil, kaydırma işlemi gerçekleşirken tetiklenir.
// 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));
}