JS / 웹개발 경진대회 / 장바구니 기능에 drag & drop 추가

Sangho Dev 💻 회고록·2022년 12월 20일
0

2020 웹개발 경진대회 문제풀이 도중 상품 카드를 장바구니 쪽으로 드래그해서 옮기게 되면 해당 상품이 장바구니에 추가되는 기능 구현이다.
기능 구현을 위해서 js 이벤트리스너 drag & drop 이 필요했는데 처음 써보는 이벤트리스너라 공부가 필요했다.

상품 리스트에서 카드를 장바구니 쪽으로 드래그 하면 기존에 구현했던 장바구니 추가 기능 코드를 실행하도록 구현을 시작했다.

기본적으로 HTML 요소는 다른 요소의 위에 위치할 수 없기 때문에 다른 요소 위에 위치할 수 있도록 만들기 위해서는 놓일 장소에 있는 요소의 기본 동작을 막아야만 한다.
이 작업을 event.preventDefault() 메소드를 호출하는 것만으로 간단히 설정할 수 있다. 그래서 drop이벤트가 정상적으로 작동하게 하기 위해서 card와 cart 요소에 dragover 이벤트 리스너 발생시 e.preventDefault() 메소드를 호출하도록 하였다.

		var cardNumber = 0;
        $(".card").on("dragover", (e) => {
          e.preventDefault();
        });
        $(".card").on("dragstart", (e) => {
          cardNumber = e.originalEvent.dataTransfer.setData(
            "number",
            e.target.dataset.id
          );
        });

먼저 cartNumber라는 변수를 만들어서 상품카드에 dragstart 이벤트가 발생하면 해당카드의 고유 번호를 dataTranfer 객체를 사용하여 담아주었다.

dataTransfer?

데이터 전송기능 객체이며 drag & drop 이벤트를 사용할때 꼭 필요한 객체이다. drag & drop 이 되는 대상의 데이터를 담는 역할을 한다.

e.dataTransfer.setData(format, data) : 첫번째 매개변수로 데이터 포맷을 지정하며 두번째 매개변수로 전송하고자 하는 데이터를 지정한다.(문자열만 가능하다)
e.dataTransfer.getData(format) : 매개변수와 일치하는 포맷에 저장된 데이터를 반환한다.

jquery안에서는 e.originalEvent.dataTransfer로 사용한다.
e.target.dataset.id로 드래그를 시작한 해당 카드의 아이디를 number라는 포맷에 전송해주었다.

		$(".card").on("drop", (e) => {
          e.preventDefault();
          console.log("드래그요소 카드에 도달");
        });
        $(".cart").on("drop", (e) => {
          e.preventDefault();
          var num = e.originalEvent.dataTransfer.getData("number");
          let itemCheck = cart.findIndex((a) => {
            return a.id == num;
          });
          console.log(itemCheck);
          if (itemCheck == -1) {
            products[num].count = 1;
            cart.push(products[num]);
          } else {
            products[num].count++;
          }

cart에 drop이벤트가 발생할 경우 dataTranfer 객체를 이용하여 저장해두었던 number 포맷을 새로운 변수 num에 저장하고, num을 이용하여 cart에 이미 해당카드가 있는지 검사하기로 하였다. findIndex 메소드를 사용하여 cart에 해당 상품이 없다면 -1을 반환하여 itemCheck라는 변수에 저장한다. 이후 drop 발생시에 itemCheck를 확인하여 -1이라면(상품이 cart에 없다면) cart에 해당 상품을 push하고 해당 카드 객체에 count 변수를 생성시켜준다. 상품이 cart에 있다면 생성했던 count변수를 1씩 증가시켜준다.

	$(".cart").html("");
          cart.forEach((a, i) => {
            $(".cart").append(`<div class = "card col" >
                    <img src = ${a.photo} class="w-50">
                    <h5>${a.title}</h5>
                    <p>${a.brand}</p>
                    <h6>가격 : ${a.price}</h6>
                    <input type="number" class="item-count" value="${a.count}" placeholder="" aria-label="Example text with two button addons">
                    </div>
                    `);
          });

최종적으로 cart에 들어있는 card만큼 장바구니에 재생성 시켜준다.

profile
빨리 가는 유일한 방법은 제대로 가는 것이다. (로버트 C.마틴, <클린 코드>의 저자)

0개의 댓글