이번 시간에는 지난번에 만들었던 여행 준비물 체크 리스트에서 '드래그 앤 드롭' 기능을 추가 구현해보았다.
캡처에는 드래그 부분이 나오지 않지만 준비완료 체크 박스에 아이템이 담긴 것을 확인할 수 있다.
지난시간에 입력하고 추가하는 부분은 작성해두었으니 오늘은 드래그 앤 드롭 부분만 가져와 기록하려고 한다.
let dropList = []; //드롭된 요소들이 담길 배열변수를 선언. let dropZone = document.querySelector('#drop_box') //드롭한 아이템들이 담길 div 태그를 들고왔다. function showList() { let list = "<ul id='itemUl' >" //기존의 showList 기능으로 만들었던 ul태그를 선택하기 쉽도록 아이디를 붙여주었다. for (let i = 0; i < itemList.length; i++) { list += `<li>${itemList[i]}<span class='close' id=${i}> X <span></li>` } list += "</ul>" document.querySelector('#itemList').innerHTML = list; let itemUl = document.querySelector('#itemUl') //변수에 해당 ul태그를 담아두었다. //반복문을 사용해 ul태그 안에 생겨날 자식들에게 드래그 효과를 지정해주었다. //자식의 인덱스도 0부터 시작하는 것에 유의하자. for (let i = 0; i < itemUl.children.length; i++) { itemUl.children[i].setAttribute("draggable", "true"); //드래그가 가능한 상태가 되도록 속성을 추가하는 작업이다. itemUl.children[i].addEventListener('dragstart', dragStart) //드래그가 시작될 때 이벤트가 발생한다. itemUl.children[i].addEventListener('dragend', dragEnd) //드래그가 끝날 때 이벤트가 발생한다. } removeEvent() } function dragStart() { this.classList.add('dragging'); //드래그 이벤트가 발생한 요소에 dragging 이라는 클래스를 추가한다. } function dragEnd() { this.classList.remove('dragging'); //드래그 이벤트가 끝난 요소에 dragging 이라는 클래스를 삭제한다. } // e : 이벤트(event)가 발생한 객체 dropZone.addEventListener('dragover', function (e) { e.preventDefault(); //기본 동작 방지, 폼 제출 방지, 링크 클릭 시 페이지 이동 방지 등... 드래그 앤 드롭을 위한 기본 설정이다. dropZone.classList.add('hovered'); //드래그 한 상태로 해당 div 요소에 오버되면 hovered 라는 클래스를 추가한다. }); dropZone.addEventListener('dragleave', function () { dropZone.classList.remove('hovered'); //드래그 한 상태로 해당 div 요소를 떠나면 hovered 라는 클래스를 삭제한다. }); dropZone.addEventListener('drop', function (e) { e.preventDefault(); dropZone.classList.remove('hovered'); //드래그 한 상태로 해당 div 요소 안에서 드롭되면 hovered 라는 클래스를 삭제한다. let item = document.querySelector('.dragging'); //앞서 드래그 이벤트가 시작되면 추가되는 클래스 속성을 가진 요소를 지역변수에 담는다. dropZone.appendChild(item) //해당 요소를 div 태그의 자식으로 붙여넣는다. let text = item.textContent; //들고 온 요소의 텍스트만 지역변수에 담는다. //span으로 삭제 버튼을 만들어 두었기 때문에 그 요소까지 나타난다. let index_str = text.slice(0,text.length-3) //span 부분을 삭제하기 위해 3글자를 빼주었다. let index = itemList.indexOf(index_str) //itemList(input값을 담은 장소)에 담겨있는 글자들과 대조해서 일치하는 값 = 해당 배열의 인덱스가 반환된다. if(index != -1){ itemList.splice(index,1) //찾아낸 인덱스 값에서 부터 하나의 요소를 제거한다. } dropList = this.children //드롭이 일어난 요소의 자식들을 해당 배열변수에 담는다. (덮어쓰기) for(let i=0; i<dropList.length; i++){ dropList[i].children[0].id = `drop${i}` //배열변수의 첫번째 자식들의 아이디를 초기화한다. (기존 input 태그로 생성한 아이디가 그대로 옮겨오기 때문) } showList() removeEvent() //드롭된 이후, itemList들이 가진 id를 재할당하기 위해 기능을 리로드 시킨다. //드롭된 부분의 리무브 이벤트를 재할당하기 위해 기능을 리로드 시킨다. }); function removeEvent() { let delBut = document.querySelectorAll('.close') for (let i = 0; i < delBut.length; i++) { delBut[i].addEventListener("click", delList); } //기존 리무브 이벤트에서 드롭된 아이템들에 한해 삭제 이벤트를 재설정 해준다. for(let i=0; i<dropList.length; i++){ dropList[i].children[0].removeEventListener("click", delList) //먼저 선언되어 있던 기능을 삭제한다. dropList[i].children[0].addEventListener("click", delDrop) //새로운 삭제 이벤트를 추가한다. } } function delDrop(){ dropZone.removeChild(this.parentNode) //해당 div의 자식 요소를 삭제하는데, 선택한 요소의 부모를 삭제함으로써 HTML에서 완전히 삭제가 된다. //부모 = 드롭장소인 div태그, 자식 = 드롭된 li 태그, 선택한 요소(this) = span 태그 } |
'아이티에듀넷' 카테고리의 다른 글
2024-09-04 :: 031 Java 시작하기 (0) | 2024.09.04 |
---|---|
2024-09-03 :: 030 반응형 CSS / typing Java script (0) | 2024.09.03 |
2024-08-30 :: 028 Java Script 활용 평가 (0) | 2024.08.30 |
2024-08-29 :: 027 Java Script 활용 ⑤ (2) | 2024.08.29 |
2024-08-28 :: 026 Java Script 활용 ④ (0) | 2024.08.28 |