Snap 이벤트 스크롤

Adam Argyle
Adam Argyle

Chrome 129부터 JavaScript의 scrollSnapChangescrollSnapChanging 이벤트를 사용할 수 있습니다. 내장된 스냅 이벤트를 구현하면 이전에는 보이지 않던 스냅 상태가 적절한 시점에 항상 올바르게 조치할 수 있게 됩니다. 이러한 이벤트가 없었다면 불편했을 것입니다.

브라우저 지원

  • Chrome: 129
  • Edge: 129
  • Firefox: 지원되지 않음
  • Safari: 지원되지 않음

소스

브라우저 지원

  • Chrome: 129
  • Edge: 129
  • Firefox: 지원되지 않음
  • Safari: 지원되지 않음

소스

scrollSnapChange 이전에는 교차 관찰자를 사용하여 스크롤 포트를 교차하는 요소를 찾을 수 있었지만, 스냅된 요소를 결정하는 것은 몇 가지 상황에만 제한되었습니다. 예를 들어 스냅 항목이 스크롤 포트를 채우는지 또는 스크롤 포트의 대부분을 채우는지 감지할 수 있습니다. 이렇게 하려면 스크롤 영역의 교차하는 요소를 관찰한 다음 스크롤 영역의 대부분을 차지하는 항목을 기반으로 이 항목이 스냅 타겟이라고 가정하고 scrollend를 기다린 후 스냅된 항목 (스냅 타겟)에 대해 작업합니다.

그러나 scrollSnapChanging 이전에는 스냅 타겟이 언제 변경되는지 또는 무엇으로 변경되는지 (예: 스크롤 플링이 주어짐) 알 수 없었습니다.

가로 스크롤러가 스냅 타겟으로 번호가 매겨진 상자와 함께 표시됩니다. 왼쪽은 scrollSnapChange 이벤트의 실시간 로그로, snapTargetInline이 파란색으로 강조 표시되어 있습니다. 오른쪽은 scrollSnapChanging 이벤트의 실시간 로그로, snapTargetInline이 회색으로 강조 표시되어 있습니다.

사용해 보기
https://codepen.io/web-dot-dev/pen/jOjaaEP

좋은 소식은 이러한 새로운 이벤트를 통해 이 정보를 쉽고 빠르게 이용할 수 있다는 것입니다. 이를 통해 스크롤 스냅 상호작용이 현재 기능을 넘어서고 스크롤 스냅 관계와 새로운 UI 의견 시나리오를 조정할 수 있습니다.

scrollSnapChange

이 이벤트는 스크롤 동작으로 인해 새 스냅 타겟이 멈춘 경우에만 다음 순서로 실행됩니다.

  1. 스크롤이 멈춘 후
  2. scrollend 이전

이 이벤트는 스크롤이 완료될 때 scrollend 바로 전에, 그리고 새 스냅 타겟이 멈춘 경우에만 발생합니다. 이렇게 하면 스크롤 동작이 완료될 때 이벤트가 지연되거나 적시에 실행되는 것처럼 느껴집니다.

scroller.addEventListener('scrollsnapchange', event => {
  console.log(event.snapTargetBlock);
  console.log(event.snapTargetInline);
})

scroller.onscrollsnapchange = event => {
  console.log(event.snapTargetBlock);
  console.log(event.snapTargetInline);
}

이 이벤트는 이벤트 객체에서 snapTargetBlocksnapTargetInline로 스냅된 항목을 노출합니다. 스크롤러가 가로 모드 전용인 경우 snapTargetBlock 속성은 null입니다. 속성 값은 요소 노드입니다.

scrollSnapChange의 고유한 세부정보

사용자가 동작을 해제할 때까지 실행되지 않음

화면에 손가락이 있거나 트랙패드에 손가락이 있으면 사용자의 동작이 스크롤을 완료하지 않았음을 나타냅니다. 즉, 스크롤이 종료되지 않았으며, 이는 스냅 타겟이 아직 변경되지 않았음을 의미합니다. 즉, 사용자 동작이 완료될 때까지 대기 중입니다.

스냅 타겟이 변경되지 않은 경우 실행되지 않음

이 이벤트는 스냅 변경을 위한 이벤트이며 스냅 타겟이 변경되지 않은 경우 스크롤러와 사용자가 상호작용하더라도 이벤트가 실행되지 않습니다. 하지만 사용자는 실제로 스크롤했으므로 스크롤 완료 시 scrollend 이벤트가 계속 실행됩니다.

scrollSnapChanging

이 이벤트는 브라우저가 스크롤 동작으로 인해 새 스냅 타겟이 생겼거나 생길 것으로 판단하는 즉시 실행됩니다. 스크롤 중에 즉시 실행됩니다.

scroller.addEventListener('scrollsnapchanging', event => {
  console.log(event.snapTargetBlock);
  console.log(event.snapTargetInline);
})

scroller.onscrollsnapchanging = event => {
  console.log(event.snapTargetBlock);
  console.log(event.snapTargetInline);
}

이 이벤트는 이벤트 객체에서 snapTargetBlocksnapTargetInline로 스냅된 항목을 노출합니다. 스크롤러가 세로 모드 전용인 경우 snapTargetInline 속성은 null입니다. 속성 값은 요소 노드입니다.

scrollSnapChanging의 고유한 세부정보

스크롤 동작 중에 일찍 자주 실행됨

완전한 사용자 스크롤 동작을 기다리는 scrollSnapChange와 달리 이 이벤트는 사용자가 손가락으로 스크롤하거나 트랙패드를 사용하는 동안 즉시 실행됩니다. 손가락을 들지 않고 천천히 스크롤하는 사용자를 생각해 보세요. 사용자가 여러 개의 잠재적 스냅 타겟 위로 화면 이동을 하는 동안 동작 중에 scrollSnapChanging가 여러 번 실행됩니다. 사용자가 스크롤할 때마다 브라우저에서 릴리스 시 새 스냅 타겟에 머무를 것으로 판단하면 이벤트가 발생하여 해당 요소를 알려줍니다.

새 스냅 타겟으로 이동하는 과정에서 모든 스냅 타겟을 실행하지 않음

또한 사용자가 한 번에 여러 스냅 타겟에 걸쳐 스크롤 던지기 동작을 하는 플링을 고려해 보세요. 이 이벤트는 멈출 타겟과 함께 한 번 실행됩니다. 따라서 최대한 빨리 스냅 타겟을 제공하면서도 낭비하지는 않습니다.

사용 사례 및 예시

이러한 이벤트를 사용하면 다양한 새로운 사용 사례를 지원할 수 있으며 현재 패턴을 훨씬 더 쉽게 구현할 수 있습니다. 그중 하나는 스냅 트리거 애니메이션을 사용 설정하는 것입니다. 스냅 타겟인 경우 스냅 항목, 스냅 항목의 하위 요소 또는 관련 정보를 문맥에 따라 표시합니다.

다음 패턴은 즉시 생산성을 높이는 데 도움이 되는 몇 가지 사용 사례를 보여줍니다.

추천사 강조 표시

이 예에서는 찍은 후 텍스트를 강조 표시하거나 시각적으로 포커스를 맞춥니다.

scroller.onscrollsnapchange = event => {
  scroller.querySelector(':scope .snapped')?.classList.remove('snapped')
  event.snapTargetInline.classList.add('snapped')
}
https://codepen.io/web-dot-dev/pen/dyBZZPe

캡처된 항목의 자막 표시

이 예에서는 스냅된 항목의 자막을 보여줍니다. 이 데모에는 두 이벤트가 모두 포함되어 있으므로 scrollSnapChangescrollSnapChanging의 시점과 사용자 환경 차이를 확인할 수 있습니다.

스냅 변경
https://codepen.io/web-dot-dev/pen/wvLPPBL

Snap 변경
https://codepen.io/web-dot-dev/pen/QWXOObw

스냅된 프레젠테이션 슬라이드의 하위 요소를 한 번 애니메이션 처리합니다.

이 예에서는 새 슬라이드가 표시되고 정지된 시점을 알 수 있으므로 콘텐츠에 애니메이션을 한 번 적용하기에 적합합니다.

document.addEventListener('scrollsnapchange', event => {
  event.snapTargetBlock.classList.add('seen')
})
https://codepen.io/web-dot-dev/pen/rNEYYVj

스크롤러에서 x와 y 모두에 맞추기

스크롤 스냅은 가로 및 세로 스크롤을 허용하는 스크롤러에서 작동합니다. 이 데모에서는 그리드를 스크롤할 때 scrollSnapChangingscrollSnapChange 타겟이 모두 표시됩니다. 이 데모에서는 브라우저가 스냅하는 요소가 항상 내가 생각하는 요소가 아닐 수 있는 방법을 보여줍니다.

가로 및 세로 스크롤러의 정사각형 그리드가 표시됩니다. 점선 테두리는 scrollSnapChanging 타겟을 나타내고 실선 테두리는 scrollSnapChange 타겟입니다. 빨간색은 snapTargetInline을 나타내고 파란색은 snapTargetBlock을 나타냅니다.

https://codepen.io/web-dot-dev/pen/qBzVVdp

연결된 두 개의 스크롤러

이 데모에는 두 개의 스크롤 스냅 컨테이너가 있습니다. 하나는 링크의 대략적인 목록이고 다른 하나는 실제 페이지로 나뉜 콘텐츠입니다. 새 scrollSnapChanging 이벤트를 사용하면 이러한 스냅 상태를 양방향으로 간편하게 연결하여 항상 동기화할 수 있습니다.

https://codepen.io/web-dot-dev/pen/YzoEEXj

OKLCH 색상 선택 도구

이 데모에는 각각 OKLCH의 서로 다른 색상 채널을 나타내는 스크롤러가 3개 있습니다. 스냅된 항목은 관련 라디오 그룹과 동기화되며 데이터는 입력을 래핑하는 양식에서 가져올 수 있습니다. 마우스 또는 터치 사용자의 경우 원하는 값으로 스크롤할 수 있습니다. 키보드 사용자의 경우 Tab 키를 누르고 화살표 키를 사용할 수 있습니다. 스크린 리더에게는 단지 양식일 뿐입니다.

scrollSnapChanging은 스냅된 항목을 상태와 조기에 동기화하는 데 사용되고 scrollSnapChange는 사용자 입력이 적용된 영향을 받는 색상 채널 헤더에 애니메이션을 적용하는 데 사용됩니다.

https://codepen.io/web-dot-dev/pen/OJeOOVG

애니메이션이 적용된 허브의 비정상적인 움직임

이 데모에서는 scrollsnapchange를 사용하여 스냅 트리거 전환으로 스크롤 스냅 환경을 점진적으로 개선합니다.

다음 JavaScript로 이벤트 지원을 확인합니다.

if ('onscrollsnapchange' in window) {
  // ok to use snap change
}
https://codepen.io/web-dot-dev/pen/MWMOOae

스크롤 가능한 눈금자 입력

이 데모에서는 숫자 입력의 길이를 선택하는 대체 방법으로 스크롤 가능한 자를 보여줍니다. 숫자 입력란에 값을 직접 입력하거나 크기로 스크롤합니다. changing 이벤트는 사용자의 동작 중에 선택을 지우는 데 사용되며, change 이벤트는 상태를 업데이트하고 사용자의 선택을 강화하는 데 사용됩니다.

https://codepen.io/web-dot-dev/pen/LYKOOpd

표지 흐름

이 데모는 유명한 macOS 커버 플로우 (동영상 튜토리얼도 있음)를 Bramus Van Damme의 훌륭한 스크롤 기반 애니메이션 재현을 기반으로 합니다. scrollSnapChanging는 앨범 제목을 숨기고 scrollSnapChange는 제목을 표시하는 데 사용됩니다. 이 이벤트는 이전 제목을 조기에 숨기고 새 제목을 지연해서 표시하는 데 도움이 됩니다.

https://codepen.io/web-dot-dev/pen/Bagmmog

창의성을 자극하는 아이디어 더보기

이제 어떤 요소가 스냅될지, 어떤 요소가 실제로 스냅되었는지 쉽게 알 수 있으므로 다양한 새로운 가능성이 열립니다. 다음은 창의력과 추가 사용 사례를 위한 아이디어 목록입니다.

  • 스냅 변경 트리거 렌더링 또는 데이터 가져오기라고 하는 지연 로드 트리거
  • 더 큰 이미지에 연결된 필름 스트립 썸네일
  • 스냅된 동영상 썸네일의 동영상 트레일러 재생/일시중지 전환
  • 애널리틱스 추적
  • 스크롤리텔링
  • Wheel of Fortune UI/UX
  • 스냅 타겟에 고정된 도움말이 표시됩니다.
  • 탭하여 스냅
  • 탭하여 확인
  • 스냅 시 소리 재생
  • 스와이프 UI
  • 스와이프 가능한 탭 또는 캐러셀

추가 연구

Chrome팀은 개발자 여러분이 이 새로운 API로 어떤 앱을 빌드하시는지 궁금하며 스크롤 가능한 환경을 간소화하는 데 도움이 되기를 바랍니다.

리소스: