티스토리 뷰

JAVA

드래그앤드롭 이벤트

wldnjd2 2022. 12. 13. 17:09

드래그앤드롭 이벤트 기능을 구현해보았다.

 

 

첫번째 시행착오

1. 처음 내가 인터넷을 통해 스스로 구현한것

 

아래는 index.jsp

<div class="drop-box">
    <table id = "uploadModal_table" class="table">
        <caption>동영상 업로드 예정 목록</caption>
        <thead>
            <tr>
                <th>선택</th>
                <th>하수관로 IDN</th>
                <th>진행 방향</th>
                <th>파일명</th>
                <th>크기</th>
                <th>업로드 진행률</th>
            </tr>
        </thead>
    </table>
</div>

 

javascript

//업로드모달창 on Event
function uploadModalOpen(parent){

    var modalFooter = document.getElementById("upload_modal_footer");
    modalFooter.style.display="block";

    $('#upload_modal').modal('show');

    if(parent._SewageQueryResultListDialog !== undefined && parent._SewageQueryResultListDialog !== null) {
        resultDialog = parent._SewageQueryResultListDialog;
    }else {
        resultDialog = null;
    }


    var dropbox = document.querySelector('.drop-box');
    dropbox.addEventListener('drop', function (e) {
        console.log("drop");
        var filename = event.dataTransfer.files;     
        filename.dragdrop = "dragdrop";
        tableAddRowEvent(filename);
        e.preventDefault();
    });
}

- dropbox div칸을 범위로 잡고 이벤트를 가져와서 넣어주었다

근데 위에대로 하니 실행이 안됨

 

- 자료를 전달할시 dataTransfer  객체를 사용합니당.

 

이유

//업로드모달창 on Event
function uploadModalOpen(parent){

    var modalFooter = document.getElementById("upload_modal_footer");
    modalFooter.style.display="block";

    $('#upload_modal').modal('show');

    if(parent._SewageQueryResultListDialog !== undefined && parent._SewageQueryResultListDialog !== null) {
        resultDialog = parent._SewageQueryResultListDialog;
    }else {
        resultDialog = null;
    }

//drag&drop 구현
    var dropbox = document.querySelector('.drop-box');
    dropbox.addEventListener('drop', function (e) {
        console.log("drop");
        var filename = event.dataTransfer.files;     
        filename.dragdrop = "dragdrop";
        tableAddRowEvent(filename);
        e.preventDefault();
    });

    dropbox.addEventListener('dragover', function (e) {
        e.preventDefault();
    });

    dropbox.addEventListener('dragleave', function (e) {
        e.preventDefault();
    });
    
    
}

 

dragover과 dragleave 이벤트가 없어서..

크롬에 이미지를 드래그 하면 아래와 같이 이미지가 웹에 들어가게 된다.

 

 

 

 

두번째 시행착오

2. 이벤트의 누적

dropbox.addEventListener('drop', function(e)){}

를 통해서 해당 div에 이벤트를 넣었었다.

 

index.jsp에서 창을 만들어줄때마다 해당 div에 이벤트를 부여하게 되어서  

로직상 이벤트가 쌓여서  console.log("test"); 가 창을 클릭할때마다 불어나버림

 

 

해결법

그래서 function 밖에구현해서 불러오는 방식으로 다시 구현하였다.

 

var dropEvent = function (e) {
    console.log("drop");
    var filename = event.dataTransfer.files;     
    filename.dragdrop = "dragdrop";
    tableAddRowEvent(filename);
    dropbox.style.border = "unset";
    e.preventDefault();
}

var dragOverEvent = function(e) {
    e.preventDefault();
	console.log("dragOverEvent")
    dropbox.style.border = "dashed gainsboro";
}	

var dragEnterEvent = function(e) {
    e.preventDefault();
	console.log("dragEnterEvent")
}

var dragLeaveEvent = function(e) {
    e.preventDefault();
	console.log("dragLeaveEvent")

    }
}


function uploadModalOpen(parent){

    var modalFooter = document.getElementById("upload_modal_footer");
    modalFooter.style.display="block";

    $('#upload_modal').modal('show');

    if(parent._SewageQueryResultListDialog !== undefined && parent._SewageQueryResultListDialog !== null) {
        resultDialog = parent._SewageQueryResultListDialog;
    }else {
        resultDialog = null;
    }
    
    //drag&drop
    var dropbox = document.querySelector('.drop-box');
    dropbox.addEventListener('drop', dropEvent);
    dropbox.addEventListener('dragenter', dragEnterEvent);
    dropbox.addEventListener('dragover', dragOverEvent);
    dropbox.addEventListener('dragleave', dragLeaveEvent);
}

 

 

 

세번째 시행착오

위에서 

dropbox = document.querySelector('.drop-box') 의 선언이 

uploadModalOpen 안에 선언이 되었는데,

dropbox라는 변수를 위의 함수 선언부분에서 읽어오지 못해서 오류가 생긴다.

 

따라서 아래와 같이 맨 위에 미리 선언을 해놓을수 있는데 이렇게 되면

index.jsp에서 script를 불러오는 코드에서 문제가 생긴다

<script src="./scripts/biz/CCTVManage.js?v=<%=nocache%>"></script>

-> div를 생성하기 전에 script를 읽어오기 때문에, 위의 코드를 밑으로 내리는 방법이 있긴함

    하지만 별로 좋은 방법은 아닌것같다.

 

var dropbox = document.querySelector('.drop-box');
var dropEvent = function (e) {
    console.log("drop");
    var filename = event.dataTransfer.files;     
    filename.dragdrop = "dragdrop";
    tableAddRowEvent(filename);
    dropbox.style.border = "unset";
    e.preventDefault();
}

var dragOverEvent = function(e) {
    e.preventDefault();
	console.log("dragOverEvent")
    dropbox.style.border = "dashed gainsboro";
}	

var dragEnterEvent = function(e) {
    e.preventDefault();
	console.log("dragEnterEvent")
}

var dragLeaveEvent = function(e) {
    e.preventDefault();
	console.log("dragLeaveEvent")

    }
}


function uploadModalOpen(parent){

    var modalFooter = document.getElementById("upload_modal_footer");
    modalFooter.style.display="block";

    $('#upload_modal').modal('show');

    if(parent._SewageQueryResultListDialog !== undefined && parent._SewageQueryResultListDialog !== null) {
        resultDialog = parent._SewageQueryResultListDialog;
    }else {
        resultDialog = null;
    }
    
    //drag&drop
    dropbox.addEventListener('drop', dropEvent);
    dropbox.addEventListener('dragenter', dragEnterEvent);
    dropbox.addEventListener('dragover', dragOverEvent);
    dropbox.addEventListener('dragleave', dragLeaveEvent);
}

 

 

 

해결법

var dopbox = null로 해줌

var dropbox = null;
var dropEvent = function(e) {
    console.log("drop");
    var filename = event.dataTransfer.files;     
    filename.dragdrop = "dragdrop";
    tableAddRowEvent(filename);
    dropbox.style.border = "unset";
    e.preventDefault();
}

var dragOverEvent = function(e) {
    e.preventDefault();
	console.log("dragOverEvent")
    dropbox.style.border = "dashed gainsboro";
}	

var dragEnterEvent = function(e) {
    e.preventDefault();
	console.log("dragEnterEvent")
}

var dragLeaveEvent = function(e) {
    e.preventDefault();
	console.log("dragLeaveEvent")

    }
}


function uploadModalOpen(parent){
    var modalFooter = document.getElementById("upload_modal_footer");
    modalFooter.style.display="block";

    $('#upload_modal').modal('show');

    if(parent._SewageQueryResultListDialog !== undefined && parent._SewageQueryResultListDialog !== null) {
        resultDialog = parent._SewageQueryResultListDialog;
    }else {
        resultDialog = null;
    }
    
    //drag&drop
    dropbox = document.querySelector('.drop-box');
    dropbox.addEventListener('drop', dropEvent);
    dropbox.addEventListener('dragenter', dragEnterEvent);
    dropbox.addEventListener('dragover', dragOverEvent);
    dropbox.addEventListener('dragleave', dragLeaveEvent);
}

 

 

 

네번째 시행착오

막상 위에 구현한 드래그 이벤트를 테스트 할때면

드래그 할때 드래그 영역을 표시해주는 border 라인이 꿀렁 거리는 현상이 일어남

그 이유는 아래의 블로그에서 설명해 준다.

 

https://velog.io/@tlatjdgh3778/%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%B2%84%EB%B8%94%EB%A7%81%EA%B3%BC-%EC%BA%A1%EC%B2%98%EB%A7%81%EC%97%90-%EB%8C%80%ED%95%9C-%EC%A0%95%EB%A6%AC

 

이벤트 버블링과 캡처링에 대한 정리

이벤트 버블링과 이벤트 캡처링에 대해서 알아보자.이벤트 버블링이란 한 요소에 이벤트가 발생하면 이 요소에 할당된 핸들러가 동작하고, 이어서 부모 요소의 핸들러가 동작하고 최상단의 부

velog.io

 

 

 

이를 방지하기 위한 해결책으로는 var enterchk 라는 변수를 선언함으로서 해결하였다.

	var enterchk = 0;
	var dropbox = null;
	
	var dropEvent = function(e) {
    	console.log("drop");
		var filename = event.dataTransfer.files;     
		filename.dragdrop = "dragdrop";
		tableAddRowEvent(filename);
		dropbox.style.border = "unset";
	  	e.preventDefault();
	}
	
	var dragOverEvent = function(e) {
	    e.preventDefault();
		console.log("dragOverEvent")
		dropbox.style.border = "dashed gainsboro";
//		dropbox.style.backgroundColor = "gray";
//		dropbox.style.opacity = "0.2";
//		dropbox.innerHTML = "안녕하세용";
	}	

	var dragEnterEvent = function(e) {
		enterchk++;
	    e.preventDefault();
//		console.log("dragEnterEvent")
	}
	
	var dragLeaveEvent = function(e) {
		enterchk--;
	    e.preventDefault();
//		console.log("dragLeaveEvent")
		
		if(enterchk === 0){
			dropbox.style.border = "unset";
		}
	}

	
	//업로드모달창 on Event
	function uploadModalOpen(parent){
		
		var modalFooter = document.getElementById("upload_modal_footer");
		modalFooter.style.display="block";
		
		$('#upload_modal').modal('show');
		
		if(parent._SewageQueryResultListDialog !== undefined && parent._SewageQueryResultListDialog !== null) {
			resultDialog = parent._SewageQueryResultListDialog;
		}else {
			resultDialog = null;
		}
		//drag&drop
		dropbox = document.querySelector('.drop-box');
		dropbox.addEventListener('drop', dropEvent);
		dropbox.addEventListener('dragenter', dragEnterEvent);
  		dropbox.addEventListener('dragover', dragOverEvent);
   	 	dropbox.addEventListener('dragleave', dragLeaveEvent);
	}

 

 

 

 

 

 

 

 

 

Ref.

https://programming119.tistory.com/100

 

[JS] event.preventDefault() 간단 설명 😊/ preventDefault란?

preventDefault 란? a 태그나 submit 태그는 누르게 되면 href 를 통해 이동하거나 , 창이 새로고침하여 실행됩니다. preventDefault 를 통해 이러한 동작을 막아줄 수 있습니다. 주로 사용되는 경우는 1. a 태

programming119.tistory.com

https://mber.tistory.com/19

 

[javascript] 자바스크립트 Drag&Drop 구현하기

서론Html 드래그 앤 드롭 api는 돔 이벤트 모델에서 정보를 가져와 정보를 업데이트 하는 방식으로 이루어진다. 드래그 앤 드롭을 구현하는데는 여러 방법이 있는데 드래그 된 아이템의 CSS 스타일

mber.tistory.com

https://sisiblog.tistory.com/265

 

[javascript] 자바스크립트 드래그 앤 드롭 draggable

참고: https://www.javascripttutorial.net/web-apis/javascript-drag-and-drop/ 이 튜토리얼에서는 자바스크립트 드래그 앤 드롭 api와 간단한 드래그 앤 드롭 앱을 구현하는 방법에 대해 알아보겠습니다. 자바스크

sisiblog.tistory.com

https://developer.mozilla.org/ko/docs/Web/API/DataTransfer

 

댓글