내가 디스트리 프로젝트에서 꽤나 애먹었던 기능이다. 여러 웹사이트에서 볼 수 있는 드래그가 가능한 이미지 슬라이더를 구현 해보는 챕터다.
로직
const와 addEventListener 선언
mousedown이 true
일 때만 mousemove function 실행되도록 설정
마우스가 클릭 후 시작점 & 드래그된 이동값 출력하기
마우스가 드래그 된 만큼 item들 움직이기
(부가적 기능) CSS적용해서 시각적 효과 더 입히기
const와 addEventListener 선언
💡 mousedown
, mouseup
, mousemove
, mouseleave
를 사용하면 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 const slider = document .querySelector('.items' );slider.addEventListener('mousedown' , () => { console .log('Down!' ); }); slider.addEventListener('mouseup' , () => { console .log('up!' ); }); slider.addEventListener('mousemove' , () => { console .log("It's moving!" ); }); slider.addEventListener('mouseleave' , () => { console .log('Leaved!' ); });
mousedown이 true일 때만 mousemove 함수 실행!
💡 드래그의 기본 동작 방식은 “클릭 → 마우스움직이기” 이므로 mousedown
이 발생하지 않았을 때에는 mousemove
에 대한 함수가 실행돼선 안된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 let isDown = false ;slider.addEventListener('mousedown' , () => { isDown = true ; console .log('Down!' ); }); slider.addEventListener('mouseup' , () => { isDown = false ; console .log('up!' ); }); slider.addEventListener('mousemove' , () => { if (!isDown) return ; console .log("It's moving!" ); });
mousedown 후 마우스 위치와 이동된 값 출력하기
💡 pageX,Y
= 브라우저 내에서의 XY좌표를 반환하지만, 스크롤 화면을 포함해 계산 한다.offsetX,Y
= 이벤트 대상 객체가 기준 이 되어 상대적 마우스 XY좌표를 반환
1 2 3 4 5 6 slider.addEventListener('mousedown' , (e ) => { isDown = true ; console .log(e.pageX); console .log(slider.offsetLeft); console .log(slider.scrollLeft); });
이러한 첫 클릭 시의 마우스 위치 와 마우스를 움직인 만큼의 값 을 변수화 하여 저장!
1 2 3 4 5 6 7 8 9 10 11 let startX;let scrollLeft;slider.addEventListener('mousedown' , (e ) => { isDown = true ; startX = e.pageX - slider.offsetLeft; scrollLeft = slider.scrollLeft; console .log(startX); console .log(scrollLeft); });
마우스가 드래그 된 만큼 스크롤
💡 scrollLeft
= 오른쪽 또는 왼쪽으로 스크롤된 만큼의 값을 반환하거나, 이동하도록 명령할 수 있음
1 2 3 4 5 6 7 8 slider.addEventListener('mousemove' , (e ) => { if (!isDown) return ; e.preventDefault(); const moved = e.pageX - slider.offsetLeft; const walk = (moved - startX) * 2 ; slider.scrollLeft = scrollLeft - walk; });
(부가적) CSS로 시각적 효과 넣어주기 1 2 slider.classList.add('active' ); slider.classList.remove('active' );
최종 완성 코드 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 const slider = document .querySelector('.items' );let isDown = false ;let startX;let scrollLeft;slider.addEventListener('mousedown' , (e ) => { isDown = true ; startX = e.pageX - slider.offsetLeft; scrollLeft = slider.scrollLeft; slider.classList.add('active' ); }); slider.addEventListener('mouseup' , () => { isDown = false ; slider.classList.remove('active' ); }); slider.addEventListener('mousemove' , (e ) => { if (!isDown) return ; e.preventDefault(); const moved = e.pageX - slider.offsetLeft; const walk = (moved - startX) * 2 ; slider.scrollLeft = scrollLeft - walk; }); slider.addEventListener('mouseleave' , () => { isDown = false ; slider.classList.remove('active' ); });