이번 시간에는 지난번에 만들었던 여행 준비물 체크 리스트에서 '드래그 앤 드롭' 기능을 추가 구현해보았다.

 

 

2024-08-22 :: 022 Java Script 활용 ①

자바 스크립트를 이용하여 나만의 여행 준비물 리스트 목록을 만들어 보았다.생각보다 막히는 부분이 많아서 고생을 좀 했지만...아래는 자바스크립트만 해석하고 기록해보겠다. (CSS는 사용자

hcl-yeon.tistory.com


 

   캡처에는 드래그 부분이 나오지 않지만 준비완료 체크 박스에 아이템이 담긴 것을 확인할 수 있다.

지난시간에 입력하고 추가하는 부분은 작성해두었으니 오늘은 드래그 앤 드롭 부분만 가져와 기록하려고 한다.

 


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 태그
}

+ Recent posts