오랜만에 제작글을 쓴다. 그 이유는 바로 장바구니를 만드는데 생각할 것이 너무 많았기 때문이다.
메뉴를 눌렀을때 해당 메뉴에 맞는 이름과 가격을 추가해 줘야 했고
장바구니에 추가된 메뉴들에게는 각각의 수량을 변경할 수 있는 버튼과 메뉴 삭제 버튼이 필요했다.
이 모든 것을 생각하니 멘붕이 왔다. 그래서 약 2주가 걸렸다...
저번에 메뉴를 추가하는 것 까지 했으나 그 이후에 좀 변한것이 있어서 다시 설명하겠다.
1. 플로팅 바 변화하기
원래의 플로팅 바는 원형이다. 나는 사용자가 인원을 눌렀을 때 플로팅바가 직사각형으로 변하게 할 것이다.
그렇게 하기 위해선 어떤 인원태그가 눌러도 플로팅 바 모양이 변해야 한다.
const number = document.querySelectorAll(".number span");
number.forEach((item,index)=>{
item.addEventListener("click",function(e){
bar.style.borderRadius = "20px";
bar.style.justifyContent= 'flex-Start';
bar.style.marginLeft = ""
bar.style.width = "220px";
bar.style.right = "-35%";
bar.style.flexDirection = "column";
bar.style.height = "none"
bar.style.alignItems = "normal";
bar.innerHTML = `<div class="member">
<p>인원: ${e.target.innerText}</p>
</div>
<div class="bottomline"></div>
<div class="menuBoxOuter"></div>
<div class="costHap"></div>
<div class="count" onclick="sent()"</div>`;
});
});
1. querySelecorAll을 이용해서 모든 인원태그를 활성화 시켜준다.
2. forEach 반복문을 사용해서 어떤 인원태그가 눌러도 click 이벤트가 발생한다.
3. 인원태그가 눌렸을때 플로팅바의 모양을 바꿔준다.
4. 바뀐 플로팅바 안에는 사용자가 누른 인원이 text로 들어간다.
5. 인원박스가 만들어졌다면 그 아래에는 메뉴박스,총합박스,주문박스를 차례대로 만들어준다. 아직 나머지 박스들은 빈공간이다.
2. 메뉴 추가하기
각각의 메뉴를 누르면 해당메뉴의 이름과 수량이 플로팅 바에 추가된다. 여기서는 메뉴를 클릭했을때의 그 메뉴가 추가되도록하는 것이 중요하다. 또 클릭되면 각각의 메뉴마다 메뉴이름,수량,가격을 저장하는 객체를 만들어서 빈 배열에 추가 한다. 그 이유는 좀 이따 수량을 늘리고 줄일텐데 그때 이 객체값을 계속 업데이트 해줘야 하기 때문이다.
const menu = document.querySelectorAll(".SubItem");
let cart =[]; // 장바구니 배열
menu.forEach((item)=>{
item.addEventListener("click",function(e){
const line = document.querySelector(".bottomline");
const menuBoxOuter = document.querySelector(".menuBoxOuter"); // 총합DIV을 맨 아래 넣기 위해 각각의 메뉴태그들을 감싸는 부모 태그를 만들었다.
menuBoxOuter.innerHTML += `
<div class="menuBox">
<div class="menuName">${e.target.firstElementChild.firstElementChild.innerText}</div>
<div class="menuCost">
<div class="menuCost_left">
<button class="delete" onclick="del(this)">X</button>
<div class="cost" value="${e.target.firstElementChild.children[1].innerText}">${e.target.firstElementChild.children[1].innerText}</div>
<div>원</div>
</div>
<div class="menuCost_right">
<button class="minus" onclick="minus(this)">-</button>
<div class="su">1</div>
<button class="plus" onclick="plus(this)">+</button>
</div>
</div>`;
const product = {
name:`${e.target.firstElementChild.firstElementChild.innerText}`,
quantity: 1,
price: Number(e.target.firstElementChild.children[1].innerText)
};
// 새로 추가될때마다 총합 태그는 가장 아래 위치됨
cart.push(product);
line.style.visibility = "visible";
const costhap = document.querySelector(".costHap");
const count = document.querySelector(".count");
costhap.style.display="flex"; // 합계 DIV 보이게 하기
count.style.display="block";
costhap.innerHTML = `
<div class="hapDiv">
<div class="hapname">합계: </div>
<div class="hap"></div>
<div>원</div>
</div>
`
count.innerHTML = `
<button>주문하기</button>`
hap();
},{once:true}) // once:true 한번만 클릭하게 하기
})
1. forEach문을 사용하여 각각의 메뉴를 순환하면서 클릭되면 innerHtml로 메뉴의 이름,가격,증가버튼,감소버튼,삭제버튼을 추가하여 하나의 태그를 만들어준다.
2. 배열에도 해당메뉴의 이름,수량,가격등을 넣어줘야 해서 product라는 객체를 만들고 배열에 추가를 해준다.
3. 메뉴가 추가되면 합계 태그랑 주문하기 버튼도 같이 생성을 해줘야 하기때문에 display:none을 해줬던것을 풀어준다.
3. 인원추가, 감소, 삭제 기능
각각의 메뉴태그를 만들때마다 증가,감소,삭제 버튼을 만들어서 사용자가 이용하기 쉽도록 만들었다.
1) 인원 추가기능
function plus(el){
let uni = el.parentNode.parentNode.parentNode.childNodes[1].innerText;
const result = el.parentNode.parentNode.childNodes[3].childNodes[3]; //총 인원태그
let cost = el.parentNode.parentNode.firstElementChild.childNodes[3]; //총 가격태그
let total = el.parentNode.parentNode.firstElementChild.childNodes[3].innerText; //총 가격
let number = el.parentNode.parentNode.childNodes[3].childNodes[3].innerText; //총 수
const realcost = el.parentNode.parentNode.firstElementChild.childNodes[3].getAttribute("value"); //메뉴 하나당 가격(불변)
number = parseInt(number)+1;
total = parseInt(total)+parseInt(realcost);
result.innerText = number;
cost.innerText = `${total}`;
for(let i=0;i<cart.length;i++){
if(cart[i].name===uni){
cart[i].price = total; // 변화된 가격을 각각의 요소에 맞는 객체를 찾아서 바꿔준다.
cart[i].quantity = number;
}
}
hap();
}
자바스크립트의 this 바인딩 방법을 이용했다. 여기서 el은 '누가 나를 불렀나'를 알려주는 개념이다.
1. plus 함수가 실행되면 눌린 메뉴의 가격과 인원을 변수로 가져온다.
2. 메뉴 하나당 가격을 상수로 설정한 후 함수가 실행될 때마다 '인원은 +1', '가격은 원래가격 += 메뉴 하나당 가격'을 해줬다.
3. 값이 바뀔때마다 배열안의 값들도 업데이트가 되야 하기 때문에 배열의 길이만큼 반복문을 돌려서 내가 누른 메뉴의 이름과 배열안의 이름이 같으면 그 객체안의 가격과 수량이 업데이트 되도록 하였다.
2) 인원 감소기능
function minus(el){
let uni = el.parentNode.parentNode.parentNode.childNodes[1].innerText;
const result = el.parentNode.parentNode.childNodes[3].childNodes[3]; //총 인원태그
let cost = el.parentNode.parentNode.firstElementChild.childNodes[3]; //총 가격태그
let total = el.parentNode.parentNode.firstElementChild.childNodes[3].innerText; //총 가격
let number = el.parentNode.parentNode.childNodes[3].childNodes[3].innerText; //총 수
const realcost = el.parentNode.parentNode.firstElementChild.childNodes[3].getAttribute("value"); //메뉴 하나당 가격(불변)
if(number>1){ // 수량이 1 이상일때마 작동
number = parseInt(number) -1;
total = parseInt(total)-parseInt(realcost);
}
result.innerText = number;
cost.innerText = `${total}`;
for(let i=0;i<cart.length;i++){
if(cart[i].name===uni){
cart[i].price = total;
cart[i].quantity = number;
}
}
hap();
}
plus함수를 만들었던 것과 비슷하게 변수들을 선언해준다, 특이한 점은 수량이 1이하로 떨어지면 안되기 떄문에 조건문을 써줘서 적용해 줬다.
3) 메뉴삭제 기능
function del(el){ //박스 삭제
let uni = el.parentNode.parentNode.parentNode.childNodes[1].innerText;
let menuBox = el.parentNode.parentNode.parentNode;
menuBox.remove();
for(let i=0;i<cart.length;i++){
if(cart[i].name===uni){
cart.splice(i,1)
}
}
hap();
}
클릭된 메뉴박스만 지운다. 특이한 점은 삭제버튼을 누르면 배열안의 값도 삭제가 되어야 하기 때문에 splice라는 자바스크립트 내장 함수를 써서 지운다.
4. 총가격 구하는 기능
function hap(){
var hapcost = 0;
const hapdiv = document.querySelector(".hap");
for(let i=0;i<cart.length;i++){
hapcost +=Number(cart[i].price);
}
hapdiv.innerText=hapcost;
}
총가격을 구하려면 배열안의 모든 가격들을 더해줘야 한다. for문을 통해 배열의 길이만큼 반복문을 돌려서 배열안의 가격 요소들만 다 더해준다.
그 후 innerText로 총합태그에 값을 넣어준다.
이 함수는 메뉴가 추가되거나 수량이 바뀌거나 하면 무조건 실행 해줘야 하기 때문에 지금까지 만든 모든 함수의 마지막에 실행시켜줘야 한다.
지금까지 만든 기능들을 백엔드로 보내줘야 하기 때문에 주문하기 버튼을 만들어서 내보내줄 계획이다. 그래서 일단은 주문하기 버튼을 누르면 현재 주문하고자 하는 메뉴들의 이름이나 수량, 총가격등을 보여주는 함수를 만들어봤다.
function sent(){
console.log(cart)
}
생각했던 것보다 고려해야 할 점이 많아서 맨붕이 왔다. 그래도 다 구현을 하니깐 장바구니가 어떤 원리로 작동이 되는지 확인 할 수 있어서 좋은 경험이였다. 분명 여기서도 수정할 부분이 있을 것이다. 그건 그 때가서 다시 수정하겠다. (너무 한 기능을 오래하다보니 지친다...)
'졸업작품' 카테고리의 다른 글
[작품] - REST API를 사용해서 동적 페이지 만들기 (0) | 2023.04.01 |
---|---|
[버그 수정] - 실시간으로 변하는 장바구니 만들기 (0) | 2023.03.18 |
[작품] - 플로팅 버튼(2) (0) | 2023.02.26 |
[작품] - JS로 스크롤 따라오는 플로팅 버튼 만들기 (0) | 2023.02.19 |
[작품] - 마우스로 가로 스크롤 제어하기 (0) | 2023.02.18 |