이전에도 나는 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") {
// 동작
}
})
더 추가 예정