본문 바로가기
웹 개발자 준비 과정🐳

day06: 드래그 앤 드롭(drag and drop)😮‍💨

by @ENFJ 2022. 7. 26.

출력결과1

수정1

 

소스코드1

 

<!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>Document</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css">
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.slim.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js"></script>
    <style>
        div.box {
            border: 1px solid red;
            background-color: yellow;
            width: 100px;
            height: 100px;
            position: absolute;
            left: 30;
            top: 30;
            line-height:100px;
        }
    </style>
</head>
<body>
    <h2>자바스크립트 function 예제3</h2>
    <div class="box">Box01</div>

    <script>
        var box = document.querySelector('div.box');
      
        // 화살표 함수에서 this는 window
        // function에서 this는 이벤트가 발생한 객체.
        // on으로 시작하는 속성에 이벤트 핸들러 사용 가능.
    

        box.addEventListener('mousedown',function(e){
            //console.dir(this);
            //console.log(e.currentTarget);
            //console.log(e.clientX,e.clientY)
            function moveHandler(e2){
            // 클릭한 좌표와 박스 와의 간격 x,y
            var gapX = e.clientX - box.offsetLeft; 
            var gapY = e.clientY - box.offsetTop;
            
            function moveHandler(e2){
                let X = e2.clientX - gapX;
                let Y = e2.clientY - gapY;

                box.style.left = X +"px";
                box.style.top = Y +"px";
                //2가지 방법이 있다. 한가지 방법은 주석처리 해두었음. 
                //https://ko.javascript.info/mouse-drag-and-drop <---참고
                // 1번째 방법 : 원래 기본값 (0,0)박스의 가로 길이를 절반으로 나눈값을 - 해줌으로써 중앙으로 이동
                // 2번째 방법 : 원래 기본값이 (0,0) 인데 여기서 직접 50 px 50px 빼줌으로써 중앙으로 이동

                //box.style.left = e2.clientX - box.offsetWidth / 2 + 'px';;
                //box.style.top = e2.clientY - box.offsetHeight / 2 + 'px';
               // box.style.left = e2.clientX - 50 +'px';
                //box.style.top = e2.clientY - 50 +'px';
            }
            window.addEventListener('mousemove',moveHandler);     
            box.addEventListener('mouseup',function(){
            window.removeEventListener('mousemove',moveHandler);
           
            });
        });
    </script>
</body>
</html>

 

출력결과 2

 

소스코드2

 

<!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>Document</title>
</head>
<style>
    div.box1{
        font-size: 25px;
        margin: 30px;
        box-sizing: border-box;
        float: left;
        width: 300px;
        height: 300px;
        background-color: rgb(176, 232, 252);
        font-family: 'Times New Roman', Times, serif;
        margin-right: 0px;
    }
    div.box2{
        font-size: 25px;
        margin: 30px;
        box-sizing: border-box;
        float: left;
        width: 300px;
        height: 300px;
        background-color: rgb(176, 232, 252);
        font-family: 'Times New Roman', Times, serif;
        margin-left: 15px;
    }
    div.item1{
        clear: both;
        background-color: red;
        width: 200px;
        height: 40px;
        line-height: 40px;
        text-align: left;
        position: absolute;
        left: 17px;
        top: 420px;
        
        font-family: 'Times New Roman', Times, serif;
    }
    div.item2{
        background-color: yellow;
        width: 200px;
        height: 40px;
        line-height: 40px;
        text-align: left;
        position: absolute;
        left: 17px;
        top: 470px;
        font-family: 'Times New Roman', Times, serif;
    }
    div.item3{
        background-color: green;
        width: 200px;
        height: 40px;
        line-height: 40px;
        text-align: left;
        position: absolute;
        left: 17px;
        top: 520px;
        font-family: 'Times New Roman', Times, serif;
    }
    div.box {
            width: 100px;
            height: 100px;
            border: 1px solid red;
            background-color: yellow;
            position: absolute;
            transition: left 0.1s linear;
            text-align: center;
            top: 600px;
            font-family: 'Times New Roman', Times, serif;
            
        }

</style>
<body>
    <div class="box1">
        <strong>Drag target 1</strong> 
    </div>
    <div class="box2">
        <strong>Drag target 2</strong> 
    </div>
    
    <div class="item1"><strong>Drag item 1</strong></div>
    <div class="item2"><strong>Drag item 2</strong></div>
    <div class="item3"><strong>Drag item 3</strong></div>
    <div class="box"><strong>test</strong></div>

    <script>
        var box1 = document.querySelector('div.item1');
        var box2 = document.querySelector('div.item2');
        var box3 = document.querySelector('div.item3');
        var box4 = document.querySelector('div.item4');
        // 화살표 함수에서 this는 window
        // function에서 this는 이벤트가 발생한 객체.
        // on으로 시작하는 속성에 이벤트 핸들러 사용 가능.
        
        box1.addEventListener('mousedown', function(e){
            box1.gapX = e.clientX - box1.offsetLeft;
            box1.gapY = e.clientY - box1.offsetTop;
            //console.log(e.currentTarget);
            //console.log(e.clientX, e.clientY);
            function moveHandler(e2) {
                box1.style.left = e2.clientX-box1.gapX + "px";
                box1.style.top = e2.clientY-box1.gapY + "px";
            }
            window.addEventListener('mousemove', moveHandler);
            box1.addEventListener('mouseup', function() {
                window.removeEventListener('mousemove', moveHandler);
            });
        });
        box2.addEventListener('mousedown', function(e){
            box2.gapX = e.clientX - box2.offsetLeft;
            box2.gapY = e.clientY - box2.offsetTop;
            //console.log(e.currentTarget);
            //console.log(e.clientX, e.clientY);
            function moveHandler(e2) {
                box2.style.left = e2.clientX-box2.gapX + "px";
                box2.style.top = e2.clientY-box2.gapY + "px";
            }
            window.addEventListener('mousemove', moveHandler);
            box2.addEventListener('mouseup', function() {
                window.removeEventListener('mousemove', moveHandler);
            });
        });

        box3.addEventListener('mousedown', function(e){
            box3.gapX = e.clientX - box3.offsetLeft;
            box3.gapY = e.clientY - box3.offsetTop;
            //console.log(e.currentTarget);
            //console.log(e.clientX, e.clientY);
            function moveHandler(e2) {
                box3.style.left = e2.clientX-box3.gapX + "px";
                box3.style.top = e2.clientY-box3.gapY + "px";
            }
            window.addEventListener('mousemove', moveHandler);
            box3.addEventListener('mouseup', function() {
                window.removeEventListener('mousemove', moveHandler);
            });
        });
  

    function moveBox(selector, callback) {
        var box = document.querySelector(selector);
        var x = box.offsetLeft;
        var step = 20;
        var interval = setInterval(function() {
            x += step;
            if (x>=500) {
                step *=-1;
                callback(box);
            }
            if( x<=0){
               step *=-1;
               callback(box);
               box.style.backgroundColor="Yellow";
               
               
            }

            box.style.left = x + "px";
        },100);
    }


    moveBox("div.box", function(target) {
        target.style.backgroundColor = "Red";
        
    });
    </script>
</body>
</html>

출력결과 3

 

소스코드3

 

<!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>DragnDrop</title>
    <style>
        body {
  background: darksalmon;
}
/* 내부 박스(사진) 스타일 설정*/
.fill {
  background-image: url('https://source.unsplash.com/random/150x150');
  position: relative;
  height: 150px;
  width: 150px;
  top: 5px;
  left: 5px;
  cursor: pointer; /*해당 영역에 커서를 두면 모양이 바뀐다.*/
}

.hold {
  border: solid 5px #ccc;
}

.empty {
  display: inline-block;
  height: 160px;
  width: 160px;
  margin: 10px;
  border: solid 3px salmon;
  background: white;
}

/*테두리 모양 */
.hovered {
  background: #f4f4f4;
  border-style: dashed;
}

    </style>
</head>

<body>
  <!--HTML : 빈 박스 5개를 생성 -->
    <div class="empty">
      <!--첫번째 박스 안에 한개의 박스를 더 만들어준다.-->
        <div class="fill" draggable="true"> </div> <!--draggable: 단어 뜻 대로 대상을 드래그 할 수 있도록 한다.-->
      </div>
    
      
      <div class="empty">
      </div>
    
      <div class="empty">
      </div>
    
      <div class="empty">
      </div>
    
      <div class="empty">
      </div>

<!--자바스크립트 JS -->
    <script>
      
    const fill = document.querySelector('.fill'); //fill 박스 셀렉트
    const empties = document.querySelectorAll('.empty'); // empty 클래스는 다수이기 때문에 selectorAll 사용

    // Fill listeners
    fill.addEventListener('dragstart', dragStart); //dragevent에 dragstart : 사용자가 요소나 선택한 요소를 드래그하기 시작할 때 발생합니다.     
    fill.addEventListener('dragend', dragEnd); //dragend: 마우스 버튼을 놓거나 이스케이프 키를 눌러 드래그 작업이 끝나게 되면 발생합니다.

// Loop through empty boxes and add listeners
// ondragover 속성: 드래그되는 대상 객체가 어느 요소 위에 놓일 수 있는지를 설정
for (const empty of empties) {
  empty.addEventListener('dragover', dragOver); //dragover: 드래그하면서 마우스가 대상 객체의 위에 자리 잡고 있을 때 발생함
  empty.addEventListener('dragenter', dragEnter); //dragEnter: 마우스가 대상 객체의 위로 처음 진입할 때 발생함.
  empty.addEventListener('dragleave', dragLeave); //dragLeave: 드래그가 끝나서 마우스가 대상 객체의 위에서 벗어날 때 발생함. 
  empty.addEventListener('drop', dragDrop); //drop: 드래그가 끝나서 드래그하던 객체를 놓는 장소에 위치한 객체에서 발생함
}

// Drag Functions

//dragstart  '회색 테두리가 생김' 동작
function dragStart() {
  this.className += ' hold';
  setTimeout(() => (this.className = 'invisible'), 0);
}
//드래그 하다가 마우스 버튼을 놓는 순간 fill 박스가 발생
function dragEnd() {
  this.className = 'fill';
}

function dragOver(e) {
  e.preventDefault();
}

//drag enter 시 테두리가 dashed로 변함
function dragEnter(e) {
  e.preventDefault();
  this.className += ' hovered';
}
// 드래그요소가 객체를 위를 벗어나면 empty 박스가 됨.
function dragLeave() {
  this.className = 'empty';
}
// dragdrop : 드래그를 드랍할때 빈 박스안에 fill 이 추가됨.==채워짐
function dragDrop() {
  this.className = 'empty';
  this.append(fill);
}

      </script>
</body>
</html>