타임아웃 함수를 삭제하고 버그를 없애세요. 실제로 필요한 이벤트는 scrollend입니다.
scrollend 이벤트 전에는 스크롤이 완료되었는지 감지하는 신뢰할 수 있는 방법이 없었습니다. 이는 이벤트가 늦게 발생하거나 사용자의 손가락이 화면에 아직 내려간 상태에서 발생한다는 의미입니다. 스크롤이 실제로 언제 종료되었는지 알 수 없기 때문에 버그가 발생하고 사용자 환경이 저하되었습니다.
document.onscroll = event => { clearTimeout(window.scrollEndTimer) window.scrollEndTimer = setTimeout(callback, 100) }
이 setTimeout() 전략이 할 수 있는 최선은 100ms의 스크롤이 중지되었는지 아는 것입니다. 따라서 스크롤이 종료된 이벤트가 아닌 스크롤이 일시중지된 이벤트와 더 유사합니다.
scrollend 이벤트가 발생하면 브라우저가 이 모든 어려운 평가를 대신 실행합니다.
document.onscrollend = event => {…}
이게 좋은 거야. 완벽하게 타이밍이 지정되고 의미 있는 조건으로 가득 차 있습니다.
사용해 보기
이벤트 세부정보
scrollend 이벤트는 다음의 경우에 발생합니다.
- 브라우저에서 더 이상 스크롤을 애니메이션으로 처리하거나 변환하지 않습니다.
- 사용자의 터치가 해제되었습니다.
- 사용자의 포인터가 스크롤 썸을 놓았습니다.
- 사용자의 키 누름이 해제되었습니다.
- 프래그먼트로 스크롤이 완료되었습니다.
- 스크롤 스냅이 완료되었습니다.
- scrollTo()이 완료되었습니다.
- 사용자가 시각적 표시 영역을 스크롤했습니다.
다음과 같은 경우 scrollend 이벤트가 발생하지 않습니다.
- 사용자의 동작으로 인해 스크롤 위치가 변경되지 않았습니다 (변환이 발생하지 않음).
- scrollTo()에서 번역이 생성되지 않았습니다.
이 이벤트가 웹 플랫폼에 적용되는 데 시간이 오래 걸린 이유는 사양 세부정보가 필요한 작은 세부정보가 많았기 때문입니다. 가장 복잡한 영역 중 하나는 문서와 비교하여 시각적 뷰포트의 scrollend 세부정보를 명확하게 설명하는 것이었습니다. 확대한 웹페이지를 생각해 보세요. 이 확대 상태에서는 스크롤할 수 있으며 문서가 반드시 스크롤되는 것은 아닙니다. 이 시각적 뷰포트 사용자 주도 스크롤 상호작용이 완료되면 scrollend 이벤트가 발생합니다.
이벤트 사용
다른 스크롤 이벤트와 마찬가지로 여러 방법으로 리스너를 등록할 수 있습니다.
addEventListener("scrollend", (event) => {
// scroll ended
});
aScrollingElement.addEventListener("scrollend", (event) => {
// scroll ended
});
또는 이벤트 속성을 사용합니다.
document.onscrollend = (event) => {
// scroll ended
};
aScrollingElement.onscrollend = (event) => {
// scroll ended
};
폴리필 및 점진적 개선
지금 이 새로운 이벤트를 사용하려면 다음 권장사항을 참고하세요. 현재 스크롤 종료 전략 (있는 경우)을 계속 사용하고 시작 부분에서 다음을 사용하여 지원을 확인할 수 있습니다.
'onscrollend' in window
// true, if available
브라우저에서 이 이벤트를 제공하는지에 따라 true 또는 false가 보고됩니다. 이 검사를 사용하면 코드를 분기할 수 있습니다.
if ('onscrollend' in window) {
document.onscrollend = callback
}
else {
document.onscroll = event => {
clearTimeout(window.scrollEndTimer)
window.scrollEndTimer = setTimeout(callback, 100)
}
}
scrollend 이벤트를 사용할 수 있을 때 점진적으로 개선하는 데 도움이 됩니다. 브라우저에서 할 수 있는 최선을 다하는 제가 만든 polyfill(NPM)을 사용해 볼 수도 있습니다.
import {scrollend} from "scrollyfills"
// then use scrollend as if it's existed this whole time
document.onscrollend = callback
폴리필은 사용 가능한 경우 브라우저 내장 scrollend 이벤트를 사용하도록 점진적으로 향상됩니다. 사용할 수 없는 경우 스크립트는 포인터 이벤트와 스크롤을 감시하여 이벤트 종료를 최대한 정확하게 추정합니다.
사용 사례
스크롤이 진행되는 동안에는 계산량이 많은 작업을 피하는 것이 좋습니다. 이 방법을 사용하면 스크롤이 원활한 환경을 유지하기 위해 최대한 많은 메모리와 처리를 자유롭게 사용할 수 있습니다. scrollend 이벤트를 사용하면 스크롤이 더 이상 발생하지 않으므로 호출하고 어려운 작업을 실행하기에 완벽한 시간을 제공합니다.
scrollend 이벤트를 사용하여 다양한 작업을 트리거할 수 있습니다. 일반적인 사용 사례는 스크롤이 멈춘 위치와 연결된 UI 요소를 동기화하는 것입니다. 예를 들면 다음과 같습니다.
- 캐러셀 스크롤 위치를 점 표시기와 동기화
- 갤러리 항목을 메타데이터와 동기화
- 사용자가 새 탭으로 스크롤한 후 데이터를 가져옵니다.
사용자가 이메일을 스와이프하여 닫는 시나리오를 생각해 보세요. 사용자가 스와이프를 완료하면 스크롤한 위치에 따라 작업을 실행할 수 있습니다.
프로그래매틱 또는 사용자 스크롤 후 동기화하거나 애널리틱스 로깅과 같은 작업에도 이 이벤트를 사용할 수 있습니다.
다음은 스크롤 위치에 따라 화살표, 점, 포커스와 같은 여러 요소를 업데이트해야 하는 좋은 예입니다. YouTube에서 이 캐러셀을 만든 방법 알아보기 실시간 데모를 사용해 보세요.
이 문제에 관한 엔지니어링 작업을 진행한 메디 카제미와 API 및 구현 가이드를 제공한 로버트 플랙에게 감사드립니다.