https://ko.javascript.info/mouse-drag-and-drop
보통 vanilla JavaScript로 dom을 드래그 시키려고 할 때 top,left 값을 수정한다.
킹치만 그렇게 하면 layout 단계까지 전부 건들기 때문에 느려질 수 있다...
그러므로
- paint 단에서 전부 처리 가능한 transform값으로 dom을 드래그 시켜보자
- onmousedown 이런 직접 할당 방식이 아니라, addEventListener 이벤트 핸들러 방식으로 작성할것이다.
- ! 재사용 ! 이 가능하도록 특정 함수 안에 dom만 넣어주면 모든것이 처리되게끔 만들어볼거다.
HTML
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
<!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>drag</title>
<link href="./style.css" rel="stylesheet" type="text/css"/>
<script src="main.js" defer></script>
</head>
<body>
<!-- https://ko.javascript.info/mouse-drag-and-drop -->
<section id="test_1" class="draggable" data-x="0" data-y="0">
<article class="drag__head"><p>001</p></article>
<article class="drag__body">
<p>Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet.</p>
</article>
</section>
<section id="test_2" class="draggable" data-x="0" data-y="0">
<article class="drag__head"><p>002</p></article>
<article class="drag__body">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quod ut a, at eaque voluptate autem!
</article>
</section>
<section id="test_3" class="draggable" data-x="0" data-y="0">
<article class="drag__head"><p>003</p></article>
<article class="drag__body">
<p>Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam, harum!</p>
</article>
</section>
</body>
</html>
|
cs |
CSS
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
30
31
32
33
34
35
36
37
38
39
40
|
@charset "utf-8";
*{margin:0;padding:0;box-sizing:border-box;}
html,body{
overflow:hidden;
width:100%;height:100vh;
background:#eee;
}
.draggable{
position:fixed;
top:0;left:0;
}
.drag__head{
position:relative;
width:100%;
padding:2rem 0;
}
.drag__head > p{
position:relative;
padding:1rem;
background:black;
color:#fff;
cursor:move;
user-select:none;}
.drag__head > p::after{
content:'';display:block;position:absolute;
top:100%;left:0;
width:calc(100% - 2px);height:2rem;
background:#fff;
border:1px solid #d2d2d2;
}
.drag__body{
position:relative;
padding:2rem; padding-top:0;
background:#fff;
border:1px solid #d2d2d2; border-top:none;
}
|
cs |
JS
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
let dragAble = false;
function make_drag(dom){
const dragHead = dom.querySelector('.drag__head');
dragHead.addEventListener('mousedown',(e)=>{start_drag(e,dom)});
dragHead.addEventListener('mousemove',(e)=>{on_drag(e,dom)});
dragHead.addEventListener('mouseup', ()=>{stop_drag(dom)});
dom.addEventListener('mouseleave', ()=>{stop_drag(dom)});
}//make_drag
function start_drag(e,dom){
dragAble = true;
dom.style.zIndex = 1000;
dom.dataset.x = e.clientX - dom.getBoundingClientRect().left;
dom.dataset.y = e.clientY - dom.getBoundingClientRect().top;
// console.log(e.clientX, dom.getBoundingClientRect().left, dom.dataset.x);
}//start_drag
function stop_drag(dom){
dragAble = false;
dom.style.zIndex = "auto";
dom.dataset.x = dom.getBoundingClientRect().left;
dom.dataset.y = dom.getBoundingClientRect().top;
}//stop_drag
function on_drag(e,dom){
if(!dragAble){return;}
e = e || window.event;
const posX = e.clientX - dom.dataset.x;
const posY = e.clientY - dom.dataset.y;
const nowX = posX >= 0 ? posX : 0;
const nowY = posY >= 0 ? posY : 0;
// console.log(e.clientX, dom.dataset.x, nowX);
dom.style.transform = `translate(${nowX}px,${nowY}px)`;
}//on_drag
/* 실행 */
const test_1 = document.getElementById('test_1');
const test_2 = document.getElementById('test_2');
const test_3 = document.getElementById('test_3');
make_drag(test_1);
make_drag(test_2);
make_drag(test_3);
|
cs |
그간 나온 예제들이 대부분 onmouseup = null 식으로 처리를 하는데 이렇게 하다보면 너무 복잡해져서 대체 어떻게 해야 이벤트핸들러로 드래그를 처리할 수 있을까 실패를 겁나 많이 했다 ㅎ...
그러던 와중 노마드코더(니코 쌤)의 바닐라자바스크립트와 canvas로 그림판 만들기 예제 강의를 들으면서 flag 값의 참/거짓 상태에 따라 ok하는것에서 결정적인 힌트를 얻었다. 힌트도 아니지 그냥 그방식으로 짰습니다 ㅋㅋㅋ ㅠ.ㅠ 고마워요 니코쌤....
제이쿼리 공식 플러그인에도 drag을 제공한다.
만일 바닐라자바스크립트가 골치가 썩는다면 제이쿼리 draggable을 사용해도 좋다...
'CSS&JS > ⚡Thinkers' 카테고리의 다른 글
[vanilla JS] json 값으로 html fetch이후 table 만들어서 뿌리기 (0) | 2021.09.29 |
---|---|
[vanilla JS] 위 아래 버튼으로 list의 순서 바꾸기 (0) | 2021.09.27 |
밑에서 떠오르는 텍스트 (잘려보이고, 밑에서 떠오름) (0) | 2021.08.30 |
[vanilla JS] 터치 슬라이더, 그랩 슬라이더 (0) | 2021.08.02 |
[JS] 트위터 이미지 불러오기 효과 (0) | 2021.07.13 |