인터넷 밴딩머신를 만들던 중 여러가지 alert를 주기 위해 새로 custom 모달창을 만들었다. 기본 alert에서 모달창으로 모든 것을 옮기던 중 문제가 발생했다. 입금 버튼을 눌렀을 시나 음료수가 품절되었을 경우는 사용자에게 그저 정보를 알려주기 위해서 모달창을 사용했지만 음료수를 현재 장바구니에서 뺄때 사용자에게 묻는 것은 cancel 버튼을 눌렀을 경우와 yes 버튼을 눌렀을 경우 다른 이벤트가 생겼다.
그리고 - 버튼을 통해 현재 장바구니에서 음료수를 삭제할 경우와 x 버튼을 통해 음료수를 삭제할 경우의 이벤트가 달랐다.
/* 모달창 처리 */
// isRemove == true: 현재 장바구니에서 아이템 삭제할 때
// isSub == true: btn-sub을 통해서만 아이템 삭제할 때
const onModal = function(title, itemCart, itemCount, drinkName, btnDrink, isRemove=false, isSub=false) {
modal.classList.add("on");
modal.querySelector("h2").textContent = title;
modal.querySelector("p").textContent = msgWarning.get(title);
modal.querySelector(".btn-cancel").addEventListener("click", () => {
console.log("cancel");
if(isSub) {
currentCart.set(drinkName, 1);
itemCount.textContent = currentCart.get(drinkName);
}
modal.classList.remove("on");
});
modal.querySelector(".btn-yes").addEventListener("click", () => {
console.log("yes");
if(isRemove && !isSub) {
drinkInfo.get(drinkName).amount += currentCart.get(drinkName);
btnDrink.querySelector(".drink-amount").textContent = parseInt(btnDrink.querySelector(".drink-amount").textContent) + currentCart.get(drinkName);
insertedMoney = insertedMoney + drinkInfo.get(drinkName).price * currentCart.get(drinkName);
inserted.textContent = numberToMoney(insertedMoney);
}
if(isRemove) {
listCurrent.removeChild(itemCart);
currentCart.delete(drinkName);
btnDrink.classList.remove("active");
}
modal.classList.remove("on");
});
}
{once: true}
를 넘겨줄 경우 한번만 이벤트가 일어난다.{once: true}
로 인해 한번만 작동하고 삭제되었지만 btn-yes의 경우는 눌러지지 않았기 때문에 계속 추가되었다. const onModal = function(title, itemCart, itemCount, drinkName, btnDrink, isRemove=false, isSub=false) {
modal.classList.add("on");
modal.querySelector("h2").textContent = title;
modal.querySelector("p").textContent = msgWarning.get(title);
const btnCancel = modal.querySelector(".btn-cancel");
const btnYes = modal.querySelector(".btn-yes");
const onCancelClicked = () => {
console.log("cancel");
if(isSub) {
currentCart.set(drinkName, 1);
itemCount.textContent = currentCart.get(drinkName);
}
modal.classList.remove("on");
}
const onYesClicked = () => {
console.log("yes");
if(isSub) {
currentCart.set(drinkName, currentCart.get(drinkName) + 1);
}
if(isRemove) {
drinkInfo.get(drinkName).amount += currentCart.get(drinkName);
btnDrink.querySelector(".drink-amount").textContent = parseInt(btnDrink.querySelector(".drink-amount").textContent) + currentCart.get(drinkName);
insertedMoney = insertedMoney + drinkInfo.get(drinkName).price * currentCart.get(drinkName);
inserted.textContent = numberToMoney(insertedMoney);
}
if(isRemove) {
listCurrent.removeChild(itemCart);
currentCart.delete(drinkName);
btnDrink.classList.remove("active");
}
modal.classList.remove("on");
}
btnCancel.removeEventListener("click", onCancelClicked, false);
btnYes.removeEventListener("click", onYesClicked, false);
btnCancel.addEventListener("click", onCancelClicked, {once: true});
btnYes.addEventListener("click", onYesClicked, {once: true});
{once: true}
를 사용했을때랑 같은 에러가 생겼다. {once: true}
의 경우 처럼 btn-cancel을 눌렀을 경우 btn-cancel의 이벤트는 add와 remove이 잘 반복되지만 btn-yes의 경우는 반복되지 않고 계속 이벤트가 추가되는 것처럼 보였다. btnCancel.removeEventListener("click", onCancelClicked, false);
btnCancel.addEventListener("click", () => {
onCancelClicked();
btnYes.removeEventListener("click", onYesClicked, false);
}, {once: true});
btnYes.addEventListener("click", onYesClicked, {once: true});
btnCancel.addEventListener("click", () => {
onCancelClicked();
btnYes.removeEventListener("click", onYesClicked, false);
}, {once: true});
btnYes.addEventListener("click", () => {
onYesClicked();
btnCancel.removeEventListener("click", onCancelClicked, false);
}, {once: true});
btnCancel.addEventListener("click", onCancelClicked, {once: true});
btnCancel.addEventListener("click", () => {
btnYes.removeEventListener("click", onYesClicked, false);
}, {once: true});
btnYes.addEventListener("click", onYesClicked, {once: true});
btnYes.addEventListener("click", () => {
btnCancel.removeEventListener("click", onCancelClicked, false);
}, {once: true});
한 마크업을 공유하기 위해 이벤트를 추가하고 삭제하는 것을 반복해야 하는 경우가 있다는 것을 알게되었다. 이것이 최선이 아닐 것 같지만 현재로써는 내 선에서 해결할 수 있는 정도인 것 같다.
아직은 addEventListener와 removeEventListener에 대해 제대로 파악하지 못하고 있는 것 같다. 어떻게 작동은 시켰지만 바깥에서 removeEventListener를 작동시켰음에도 삭제가 되지 않은 이유를 알기 어렵다. 다음 시간에 다시 정확히 addEventListener와 removeEventListener의 작동 방식과 옵션 등등을 학습해서 정확한 이유를 알아야겠다.
나중에 target에 어떤 이벤트가 있는지 알기 위해서target.getEventListeners( target )
을 이용할 수 있을 것 같다.
다음에 강사님과 멘토님께 물어봐 실무에서는 어떤 기술을 사용해 한 마크업을 공유하는지도 물어봐야겠다.