whatisthis?
practice - js ) 슬라이드 페이지 (2) 터치형(드래그) 본문
슬라이드 페이지
(2) 터치형(드래그)
- 📃 실습하면서 알게된 점 기록
📌touch 이벤트
changedTouches
The TouchEvent.changedTouches property is a TouchList object that contains one Touch object for each touch point which contributed to the event.
>> 즉, touchList 객체이므로 첫번째 아이템인 [0]을 가져온것.
(터치가 여러군데 되면 여러 값 존재)
+) 그 외에도
TouchEvent.targetTouches
TouchEvent.touches
등의 프로퍼티가 존재함.
++) 터치 이벤트에는 (event)
touchstart, touchmove, touchend, touchcancel이 존재.
https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/changedTouches
index.html (style 내장)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Slide Banner</title>
<style>
* {
box-sizing: border-box;
}
/* 드래그 방지 */
body {
-ms-user-select: none;
-moz-user-select: none;
-webkit-user-select: none;
-khtml-user-select: none;
user-select: none;
}
.outer {
border: 6px solid #525252;
width: 300px;
height: 200px;
margin: 0 auto;
overflow-x: hidden;
}
.inner-grp {
display: flex;
transition: all 0.3s ease-out;
height: 100%;
}
.inner {
padding: 0 16px;
color: #fff;
text-align: center;
}
.inner:nth-of-type(1) {
background-color: rgb(209, 0, 0);
}
.inner:nth-of-type(2) {
background-color: rgb(255, 248, 49);
}
.inner:nth-of-type(3) {
background-color: rgb(60, 0, 255);
}
</style>
</head>
<body>
<div class="outer">
<div class="inner-grp">
<div class="inner">
<h2>First</h2>
</div>
<div class="inner">
<h2>Second</h2>
</div>
<div class="inner">
<h2>Third</h2>
</div>
</div>
</div>
<script src="app.js"></script>
</body>
</html>
app.js
// Div 사이즈 js로 조절하기
const outer = document.querySelector(".outer");
const innerGrp = document.querySelector(".inner-grp");
const inners = document.querySelectorAll(".inner");
let currentIndex = 0;
let currentTransition;
inners.forEach(inner => {
inner.style.width = `${outer.clientWidth}px`;
console.log(outer.clientWidth);
});
innerGrp.style.width = `${outer.clientWidth * inners.length}px`;
// Event Listener
let isSlide = false;
let slideStartX = 0;
let slideGab = 0;
const flipGab = 80;
// 🔺 gab이 80이상이여야 넘어가게
// 📌 slide시작시 - transition 저장해놓고 잠시 삭제함 (느려지니까)
const slideStart = clientX => {
slideStartX = clientX;
isSlide = true;
currentTransition = window.getComputedStyle(innerGrp).transition;
innerGrp.style.transition = "initial";
};
// 📌 slide 하는동안(마우스 누르는동안) - gab에 따라서 margin-left 달라지게
const slideMove = clientX => {
if (isSlide) {
slideGab = slideStartX - clientX;
if (currentIndex >= inners.length - 1 && slideGab > 0) {
slideGab = 0;
// 마지막슬라이드에서는 gab을 0으로 설정
}
// 🔻 margin-left 줌 (gab에 따라서 달라지게)
innerGrp.style.marginLeft = `-${
outer.clientWidth * currentIndex + slideGab
}px`;
}
};
// 📌 slide 끝 (마우스 뗌) - 좌우 드래그 판단후 인덱스 올리기 + margin-left주기
const slideEnd = () => {
// slidegab이 80보다 클때 - 우로 드래그함 (인덱스 증가)
if (slideGab >= flipGab) {
currentIndex++;
currentIndex =
currentIndex >= inners.length ? inners.length - 1 : currentIndex;
} else if (slideGab <= -flipGab) {
// slidegab이 -80보다 작음 - 좌로 드래그함 (인덱스 감소)
currentIndex--;
currentIndex = currentIndex < 0 ? 0 : currentIndex;
}
// margin-left 줌
innerGrp.style.marginLeft = `-${outer.clientWidth * currentIndex}px`;
// 변수들 초기화
slideGab = 0;
isSlide = false;
// 트랜지션도 초기화 (다시 적용)
innerGrp.style.transition = currentTransition;
};
// 데스크탑 전용
innerGrp.addEventListener("mousedown", e => {
slideStart(e.clientX);
});
innerGrp.addEventListener("mousemove", e => {
slideMove(e.clientX);
});
innerGrp.addEventListener("mouseup", e => {
slideEnd();
});
// 터치 - 모바일 전용
innerGrp.addEventListener("touchstart", e => {
slideStart(e.changedTouches[0].clientX);
});
innerGrp.addEventListener("touchmove", e => {
slideMove(e.changedTouches[0].clientX);
});
innerGrp.addEventListener("touchend", e => {
slideEnd();
});
result
사담 👻
처음엔 왜 굳이 width를 js로 주지? 했는데
따지고보면 ... 나중에 페이지가 늘어나거나 하면 이게 더 확실하기도 하고,
DOM객체의 clientWidth를 받아오니까 하나가 변해도 계속 유지되고.. 등등 장점이 있다.
그래도 역시 js로 CSS 변경하는건 생소하긴 하네.
클래스 넣고빼고 하는 방법을 생각했는데 이보다 더 나은 방법은 못찾겠음..
암튼! js 재밌다.
(진짜임)
'PRACTICE > SELF' 카테고리의 다른 글
practice - css ) BookStore UI (0) | 2022.03.12 |
---|---|
practice - css ) 슬라이드 페이지 - CSS only (JS❌) (0) | 2022.03.11 |
practice - js ) 슬라이드 페이지 (1) 버튼형 (0) | 2022.03.11 |
practice - css / js ) Tab Menu (0) | 2022.03.11 |
practice - css / jquery ) j쿼리로 아코디언메뉴 만들기 + 추가 (1) | 2022.03.10 |