본문 바로가기

JavaScript30 Challenge

[JavaScript30] Day 27

Click and Drag

 

const slider = document.querySelector('.items');
let isDown = false;
let startX;
let scrollLeft;

slider.addEventListener('mousedown', () => {
  isDown = true;
});
slider.addEventListener('mouseleave', () => {
  isDown = false;
});
slider.addEventListener('mouseup', () => {
  isDown = false;  
});
slider.addEventListener('mousemove', () => {
  console.log(isDown);
  console.log('Do Work!!')
});

마우스가 영역 안에 들어가게 되면 false, Do Work가 찍히게 되고,

그 영역 안에서 mousedown이 발생하면 true, Do Work가 찍히게 됩니다.

 

영역 안에서 물체를 잡은 상태로 이동하는것을 갑자할때 true로 감지할수 있습니다.

 

 

const slider = document.querySelector('.items');
let isDown = false;
let startX;
let scrollLeft;

slider.addEventListener('mousedown', () => {
  isDown = true;
});
slider.addEventListener('mouseleave', () => {
  isDown = false;
});
slider.addEventListener('mouseup', () => {
  isDown = false;  
});
slider.addEventListener('mousemove', () => {
  if(!isDown) return; // stop the fn from running
  console.log(isDown);
  console.log('Do Work!!');
});

이번에는 영역안에서 마우스가 클릭된 상태로 움직일 때만 출력되도록 합니다.

이제 false는 나오지 않고 true인 경우만 출력됩니다.

 

const slider = document.querySelector('.items');
let isDown = false;
let startX;
let scrollLeft;

slider.addEventListener('mousedown', () => {
  isDown = true;
});
slider.addEventListener('mouseleave', () => {
  isDown = false;
});
slider.addEventListener('mouseup', () => {
  isDown = false;  
});
slider.addEventListener('mousemove', () => {
  if(!isDown) return; // stop the fn from running
  console.count(isDown);
});

console.log를 console.count로 바꿔줍니다.

이제 드래그하면 몇 번이나 이동했는지 숫자로 확인할 수 있습니다.

 

const slider = document.querySelector('.items');
let isDown = false;
let startX;
let scrollLeft;

slider.addEventListener('mousedown', (e) => {
  isDown = true;
  slider.classList.add('active');
  console.log(e);
});
slider.addEventListener('mouseleave', () => {
  isDown = false;
  slider.classList.remove('active');
});
slider.addEventListener('mouseup', () => {
  isDown = false;  
  slider.classList.remove('active');
});
slider.addEventListener('mousemove', () => {
  if(!isDown) return; // stop the fn from running
  console.count(isDown);
});

이번에는 mousedown일때 e에 대한 정보를 출력해봅니다.

확인해보면 많은 정보가 담겨있음을 알 수 있습니다.

이중에 필요한 정보들만을 사용해 봅니다.

 

 

const slider = document.querySelector('.items');
let isDown = false;
let startX;
let scrollLeft;

slider.addEventListener('mousedown', (e) => {
  isDown = true;
  slider.classList.add('active');
  console.log(e.pageX);
});
slider.addEventListener('mouseleave', () => {
  isDown = false;
  slider.classList.remove('active');
});
slider.addEventListener('mouseup', () => {
  isDown = false;  
  slider.classList.remove('active');
});
slider.addEventListener('mousemove', () => {
  if(!isDown) return; // stop the fn from running
  console.count(isDown);
});

pageX에 대해 출력해보면,

mousedown이 시작되는 시점의 page에서의 X 좌표값을 출력해 줍니다.

 

하지만 우리가 알고 싶은 것을 영역 안에서의 위치이기 때문에, 

이것이 영역 안에서의 위치가 맞는지 확인해볼 필요가 있습니다.

 

const slider = document.querySelector('.items');
let isDown = false;
let startX;
let scrollLeft;

slider.addEventListener('mousedown', (e) => {
  isDown = true;
  slider.classList.add('active');
  startX = e.pageX - slider.offsetLeft;
  console.log(startX);
});
slider.addEventListener('mouseleave', () => {
  isDown = false;
  slider.classList.remove('active');
});
slider.addEventListener('mouseup', () => {
  isDown = false;  
  slider.classList.remove('active');
});
slider.addEventListener('mousemove', () => {
  if(!isDown) return; // stop the fn from running
  console.count(isDown);
});

영역의 margin을 50px로 지정한 후

왼쪽 가까이 클릭해보니 18px이라는 50보다 작은 값이 출력되었습니다.

이렇게 영역 안의 값임을 확인할 수 있습니다.

 

 * 제일 왼쪽을 클릭했음에도 18px이 나오는 이유는 .items에 css로 transform: scale(0.98)가 들어있기 때문이다.

이를 제거해주면 제일 왼쪽을 클릭했을 때 0px이 나온다.

 

const slider = document.querySelector('.items');
let isDown = false;
let startX;
let scrollLeft;

slider.addEventListener('mousedown', (e) => {
  isDown = true;
  slider.classList.add('active');
  startX = e.pageX - slider.offsetLeft;
  console.log(startX);
});
slider.addEventListener('mouseleave', () => {
  isDown = false;
  slider.classList.remove('active');
});
slider.addEventListener('mouseup', () => {
  isDown = false;  
  slider.classList.remove('active');
});
slider.addEventListener('mousemove', () => {
  if(!isDown) return; // stop the fn from running
  console.count(isDown);
  console.log(startX)
});

이번엔 mousemove에 대해서 체크해봅니다.

잡고 드래그를 하게 되면 아까 했던 것과 같이 처음 시작하는 좌표가 찍히게 됩니다. 780px은 움직이면서도 이 숫자는 바뀌지 않고 끝까지 유지됩니다.

다시 놓았다가 잡고 드래그를 합니다. 591px에서 시작해서 이 숫자는 움직이면서도 바뀌지 않습니다.

 

 

const slider = document.querySelector('.items');
let isDown = false;
let startX;
let scrollLeft;

slider.addEventListener('mousedown', (e) => {
  isDown = true;
  slider.classList.add('active');
  startX = e.pageX - slider.offsetLeft;
  scrollLeft = slider.scrollLeft;
});
slider.addEventListener('mouseleave', () => {
  isDown = false;
  slider.classList.remove('active');
});
slider.addEventListener('mouseup', () => {
  isDown = false;  
  slider.classList.remove('active');
});
slider.addEventListener('mousemove', (e) => {
  if(!isDown) return; // stop the fn from running
  e.preventDefault();
  const x = e.pageX - slider.offsetLeft;
  console.log({x, startX});
});

드래그를 할 때 커서가 어디에 있는지 알아봅니다.

mousemove에서 x라는 좌표를 만들어서  startX와 같이 출력해봅니다.

startX는 처음 숫자가 계속 반복되지만, x는 계속 반복되는 것을 확인할 수 있습니다.

 

이제 두 값의 차를 구해서 실질적으로 움직인 거리를 나타내 줍니다.

 

const slider = document.querySelector('.items');
let isDown = false;
let startX;
let scrollLeft;

slider.addEventListener('mousedown', (e) => {
  isDown = true;
  slider.classList.add('active');
  startX = e.pageX - slider.offsetLeft;
  scrollLeft = slider.scrollLeft;
});
slider.addEventListener('mouseleave', () => {
  isDown = false;
  slider.classList.remove('active');
});
slider.addEventListener('mouseup', () => {
  isDown = false;  
  slider.classList.remove('active');
});
slider.addEventListener('mousemove', (e) => {
  if(!isDown) return; // stop the fn from running
  e.preventDefault();
  const x = e.pageX - slider.offsetLeft;
  const walk = x - startX;
  console.log(walk)
});

움직인 거리는 처음 시작점인 0을 기준으로 왼쪽으로 가면 -값이 나오고 오른쪽으로 가면 +값이 나오게 됩니다.

 

const slider = document.querySelector('.items');
let isDown = false;
let startX;
let scrollLeft;

slider.addEventListener('mousedown', (e) => {
  isDown = true;
  slider.classList.add('active');
  startX = e.pageX - slider.offsetLeft;
  scrollLeft = slider.scrollLeft;
});
slider.addEventListener('mouseleave', () => {
  isDown = false;
  slider.classList.remove('active');
});
slider.addEventListener('mouseup', () => {
  isDown = false;  
  slider.classList.remove('active');
});
slider.addEventListener('mousemove', (e) => {
  if(!isDown) return; // stop the fn from running
  e.preventDefault();
  const x = e.pageX - slider.offsetLeft;
  const walk = x - startX;
  slider.scrollLeft = walk;
});

그렇게 계산된 값만큼 이동하게 만들고 테스트를 해보니,

잡고 드래 그 한 후 놓은 후, 두번째로 이동하려고 하면 다시 제일 왼쪽으로 이미지가 이동하게 됩니다.

그래서 내가 드래그해서 이동한만큼은 뺀 나머지 길이가 필요합니다.

 

const slider = document.querySelector('.items');
let isDown = false;
let startX;
let scrollLeft;

slider.addEventListener('mousedown', (e) => {
  isDown = true;
  slider.classList.add('active');
  startX = e.pageX - slider.offsetLeft;
  scrollLeft = slider.scrollLeft;
});
slider.addEventListener('mouseleave', () => {
  isDown = false;
  slider.classList.remove('active');
});
slider.addEventListener('mouseup', () => {
  isDown = false;  
  slider.classList.remove('active');
});
slider.addEventListener('mousemove', (e) => {
  if(!isDown) return; // stop the fn from running
  e.preventDefault();
  const x = e.pageX - slider.offsetLeft;
  const walk = (x - startX) * 3;
  slider.scrollLeft = scrollLeft - walk;
});

const walk = (x - startX) * 3; 로 약간의 움직임만으로 많은 이동이 있게 해 주고,

슬라이더는 내가 마우스로 움직인 만큼 이동할 수 있으며 다시 왼쪽으로 돌아가는 일도 없게 되었습니다. 

이렇게 해서 드래그로 페이지를 이동할 수 있도록해주는 코드가 완성되었습니다.

 

 

JavaScript30 강의를 보고 공부한 글입니다. (https://javascript30.com/)

'JavaScript30 Challenge' 카테고리의 다른 글

[JavaScript30] Day 29  (0) 2020.08.29
[JavaScript30] Day 28  (0) 2020.08.28
[JavaScript30] Day 26  (0) 2020.08.20
[JavaScript30] Day 25  (0) 2020.08.19
[JavaScript30] Day 24  (0) 2020.08.18