이전에도 나는 JS를 독학하다 한계치에 다다른 후 포기한 경험이 있는 사람으로써 이대로 가다가는 또 아무것도 머리에 넣지 못할 것 같아 실패한 경험을 쓰기로 했다.
두 달 전에 HTML/CSS 작업은 완료해 둔 상태의 밴딩머신이 동작할 수 있도록 해 주어야 하는데...... 마음먹은 대로 움직이지를 않아 멘토님의 도움과 여기저기서 얻은 정보로 수정해 보았다.

기존에 구현한 방식
: drink[name]의 형식으로 데이터에 접근해 음료의 이름을 읽어 오려고 시도함
문제점
: name을 선언하지 않았기 때문에 값을 읽어 올 수 없음
해결
: button 동작 시 해당 음료의 정보를 데이터 객체에서 가져올 수 있도록 하기 위해 dataset을 사용
💡 dataset 사용법
- HTML 태그에 접두어(data)가 붙은 속성을 추가 후 값을 지정한다.
- JS에서 요소를 선택 후
dataset객체에서 속성을 읽도록 한다. 접두어(data)는 생략해 사용한다.
HTML
<button class="btn-cola btn-original" data-name="Original_Cola" data-price="1000">
JS
drink의 이름(name)이 data-name과 일치하는 객체의 count 값이 0일 때 alert 띄움drink는 데이터를 담고 있는 변수if (drink[name].count == 0) {
alert("품절된 음료입니다!");
}
depositBtn)을 누르면 입력한 금액이 잔액으로 뜨면서 동시에 소지금도 차감되도록 하기기존에 구현한 방식
: 자판기 최초 동작 시 insertAdjacentHTML를 통해 입금한 금액을 띄우는 태그를 추가하도록 함
문제점
: 입금액을 입력 후 입금 버튼을 눌러도 잔액 칸에 금액이 뜨지 않음
이유
balance가 담고 있는 요소가 span.balance인데, 여러 번의 수정 과정에서 클래스명 balance를 작성하지 않음myMoney는 HTML 요소가 아닌 50000이라는 숫자를 담고 있는 변수이므로 textContent가 동작하지 않는 것이 당연함해결
moneyDiv 뒤에 insertAdjacentHTML을 이용해 span 태그 삽입span 태그를 담는 변수 moneySpan 선언moneySpan을 선택해 숫자만 바꿔 주도록 할 것이기 때문수정 전 코드
const depositBtn = document.querySelector(".btn-deposit"); // 입금 버튼
let myMoney = 50000; // 소지금
let balance = document.querySelector(".balance"); // 잔액
let count = 0; // 자판기 작동 횟수
// 소지금 띄우기
let moneyDiv = document.querySelector(".my-money");
let moneySpan = moneyDiv.insertAdjacentHTML(
"beforeend",
`<span class="current">${myMoney}</span>`
);
myMoney.textContent = comma(myMoney);
수정 후 코드
const depositBtn = document.querySelector(".btn-deposit"); // 입금 버튼
const balance = document.querySelector(".balance"); // 잔액 요소
let myMoney = 50000; // 기본 소지금
let balanceValue = 0; // 현재 잔액
// 소지금 띄우기
let moneyDiv = document.querySelector(".my-money");
moneyDiv.insertAdjacentHTML(
"beforeend",
`<span class="current">${comma(myMoney)}</span>`
);
const moneySpan = document.querySelector(".current"); // 현재 소지금 요소
// 입금 버튼 동작 로직
// 현재 소지금과 잔액 값 띄우기
balance.textContent = comma(balanceValue);
moneySpan.textContent = comma(myMoney);
insertAdjacentHTML로 태그 추가되도록 하고 이후부터는 입금한 값만 바뀌도록 하기기존에 구현한 방식
: count 변수 이용해 실행 횟수를 세도록 한 후 자판기 최초 동작 시에만 insertAdjacentHTML를 이용해 잔액을 띄우도록 함
문제점
: 상당히 복잡한 코드, 깔끔하지 않고 동작하지도 않음
해결
moneySpan이라는 텍스트가 들어갈 곳은 insertAdjacentHTML로 추가해 뒀으니 누를 때마다 입금액이 누적되도록 textContent로 넣어 주기만 하면 됨input 요소에서 입금액 입력 후 입금 버튼 클릭 시 칸이 비워질 수 있도록 초기화 해 주는 기능 추가// 소지금 띄우기
let moneyDiv = document.querySelector(".my-money");
moneyDiv.insertAdjacentHTML(
"beforeend",
`<span class="current">${comma(myMoney)}</span>`
);
const moneySpan = document.querySelector(".current");
depositBtn.addEventListener("click", () => {
let inpDeposit = parseInt(document.querySelector(".inp-deposit").value);
let check = /^[0-9]+$/; // 숫자인지 확인
if (check.test(inpDeposit)) {
myMoney -= inpDeposit;
balanceValue += inpDeposit;
alert(`${inpDeposit} 원이 입금되었습니다.`);
// 잔액 띄우기
let balanceDiv = document.querySelector(".box-balance");
balanceDiv.insertAdjacentHTML(
"beforeend",
`<span class="balance">${balance}</span>`
);
totalMoney = `${myMoney}`;
} else if (check.test(inpDeposit) && count != 0) {
myMoney -= inpDeposit;
// balance += inpDeposit
balance = `${balance - inpDeposit}`;
} else {
alert("숫자로만 입력해 주세요.");
}
count++;
});
수정 후 코드
depositBtn.addEventListener("click", () => {
let inpDeposit = parseInt(document.querySelector(".inp-deposit").value); // 입금액 읽어 오기
let check = /^[0-9]+$/; // 숫자인지 확인
if (check.test(inpDeposit)) {
// 소지금과 잔액 계산
myMoney -= inpDeposit;
balanceValue += inpDeposit;
// 현재 소지금과 잔액 값 띄우기
balance.textContent = comma(balanceValue);
moneySpan.textContent = comma(myMoney);
} else {
alert("숫자로만 입력해 주세요.");
}
document.querySelector(".inp-deposit").value = "";
});
기존에 구현한 방식
: querySelector를 이용해 .btn-cola를 읽어 와 데이터에 접근 시도
문제점
.btn-cola 클래스를 가지는 버튼이 여러 개이기 때문에 첫 번째 요소만 반환하게 됨 해결 방법 1
: querySelectorAll을 이용해 모든 button.btn-cola를 가지고 온 후 forEach로 순회
const colaBtns = document.querySelectorAll(".btn-cola");
colaBtns.forEach(button => {
button.addEventListener("click", () => {
// 동작
});
})
button.btn-cola들의 부모 요소인 ul.colaList를 가지고 와 이벤트 부여 후 자식 요소들에게 이벤트 위임const colaList = document.querySelector(".colaList"); // 콜라 리스트
colaList.addEventListener("click", (e) => {
if(e.target.className == "btn-cola") {
// 동작
}
})
더 추가 예정