index.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>스타벅스 주문 시스템</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h1>스타벅스 메뉴</h1>
<div id="menu">
<h2>메뉴</h2>
<!-- 메뉴 아이템이 여기에 추가될 것입니다 -->
</div>
<div id="order-summary">
<h2>주문 내역</h2>
<ul id="order-list"></ul>
<p>총 가격: ₩<span id="total-price">0</span></p>
<button id="submit-order">주문 제출</button>
</div>
<script src="script.js"></script>
</body>
</html>
script.js
document.addEventListener('DOMContentLoaded', () => {
const menu = [
{ name: '아메리카노', price: 4100 },
{ name: '카페라떼', price: 4600 },
{ name: '카푸치노', price: 4600 },
{ name: '카라멜 마끼아또', price: 5800 },
{ name: '자바 칩 프라푸치노', price: 6300 },
{ name: '딸기 요거트 블렌디드', price: 6300 }
];
let order = {}; // 주문 항목을 저장하는 딕셔너리.
let totalPrice = 0; // 전체 값.
const menuContainer = document.getElementById('menu');
const orderList = document.getElementById('order-list');
const totalPriceElement = document.getElementById('total-price');
const submitOrderButton = document.getElementById('submit-order');
menu.forEach((item, index) => {
let divall = document.createElement('div'); // 커피 이름과 가격, 주문 추가 버튼이 다 들어있는 올인원 영역
divall.classList.add('linebox'); // 올인원 영역 클래스는 linebox
let div1 = document.createElement('div');
div1.classList.add('cofname');
let span1 = document.createElement('span');
span1.textContent = `${item.name}`;
div1.appendChild(span1)
let div2 = document.createElement('div') // 커피 가격과 주문 추가 버튼이 들어있는 영역.
div2.classList.add('price-btn'); // 해당 영역 클래스는 price-btn
let span2 = document.createElement('span');
span2.id = 'cofprice';
span2.textContent = `₩${item.price}`;
let button = document.createElement('button');
button.id = 'addbtn';
button.innerText = '주문 추가.';
button.setAttribute('data-index', index); // 각 메뉴 아이템의 인덱스를 저장
div2.appendChild(span2)
div2.appendChild(button)
divall.appendChild(div1)
divall.appendChild(div2) // 합체.
document.getElementById('menu').appendChild(divall) // 오더 리스트에 추가.
});
menuContainer.addEventListener('click', (event) => {
// 버튼이 눌릴 시에 발동.
if (event.target.tagName === 'BUTTON') {
// 어떤 메뉴의 버튼이 눌릴 시.
const index = event.target.getAttribute('data-index');
// 클릭된 버튼의 data-index 속성을 가져옴
const selectedItem = menu[index];
// 메뉴 배열에서 해당 메뉴를 찾아옴 ex)아메리카노가 선택되면 0번째로 지정되겠지?
if (!order[selectedItem.name]) {
order[selectedItem.name] = {
price: selectedItem.price,
quantity: 1
}; // order 리스트에 선택된 아이템의 이름이 존재하지 않을 시
// price의 밸류를 선택된 커피의 값으로 변경.
// quantity 키 생성 및 밸류를 1로 설정.
// ex)아메리카노가 선택될 시, 0번째 인덱스의 이름을 조회.
// 아메리카노의 수량을 1로 설정.
} else {
order[selectedItem.name].quantity += 1;
// order 리스트에 선택된 아이템의 이름이 존재할 시.
// quantity의 밸류를 1 늘린다.
// 아메리카노가 이미 장바구니에 들어있으면, 아메리카노의 수량이 1에서 2가 된다.
}
totalPrice += selectedItem.price;
// 총합 가격은 selectedItem이란 딕셔너리의 price.
updateOrderList();
//주문 내역 업데이트 함수 불러오기.
}
});
// 주문 내역 업데이트 함수
function updateOrderList() {
orderList.innerHTML = '';
for (let itemName in order) {
const orderItem = order[itemName];
const orderItemElement = document.createElement('li');
orderItemElement.classList.add('orderitemelements');
orderItemElement.innerHTML = `
${itemName} - ₩${orderItem.price.toLocaleString()} x${orderItem.quantity}
<button class="remove" data-item="${itemName}">삭제</button>
`;
orderList.appendChild(orderItemElement);
}
totalPriceElement.textContent = totalPrice.toLocaleString();
}
// 아이템 삭제 로직
orderList.addEventListener('click', (event) => {
const itemName = event.target.getAttribute('data-item');
if (event.target.classList.contains('remove')) {
totalPrice -= order[itemName].price * order[itemName].quantity;
delete order[itemName];
updateOrderList();
}
});
// 주문 제출 로직
submitOrderButton.addEventListener('click', () => {
if (Object.keys(order).length > 0) {
alert('주문해 주셔서 감사합니다!');
order = {};
totalPrice = 0;
updateOrderList();
} else {
alert('주문 내역이 비어 있습니다!');
}
});
});
styles.css
body {
font-family: Arial, sans-serif;
padding: 20px;
max-width: 600px;
margin: 0 auto;
}
h1 {
text-align: center;
}
h2 {
margin-left: 10px;
}
p {
margin-left: 10px;
}
#menu {
border: solid 1.5px gray;
border-radius: 5px;
}
#order-summary {
border: solid 1.5px gray;
border-radius: 5px;
margin-top: 10px;
}
/* 여기에 #menu와 #order-summary의 스타일을 추가하세요. */
/* 버튼과 관련된 스타일은 아래의 예시를 참고하여 완성하세요. */
button {
background-color: #00704a;
color: white;
padding: 10px;
border: none;
border-radius: 5px;
cursor: pointer;
}
button:hover {
background-color: #005936;
}
#submit-order {
display: block;
/* block 요소로 변경 */
margin: 20px auto;
/* 중앙 정렬 */
width: 90%;
/* 부모의 80% 너비를 차지 */
background-color: #00704a;
color: white;
/* 버튼을 크게 보이게 하기 위한 패딩 */
border: none;
border-radius: 5px;
/* 글씨 크기 조정 */
cursor: pointer;
}
.orderitemelements {
margin-top: 5px;
}
.remove {
background-color: red;
color: white;
padding: 10px;
border: none;
border-radius: 5px;
cursor: pointer;
}
.remove:hover {
background-color: pink
}
.linebox {
display: flex;
justify-content: space-between;
/* 라인박스를 조정해서 양 옆에 공간을 두고 요소들이 배치되게끔 조정함. */
height: 50px;
/* 키를 조정해서 요소 간 간격이 어느 정도 있게 유격을 생성. */
}
.cofname {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
margin-left: 10px;
}
.price-btn {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
#cofprice {
margin-right: 10px;
}
#addbtn{
margin-right: 10px;
}
'사전 캠프 > 추가 과제' 카테고리의 다른 글
비밀의 사이트를 만드는 중이다. (1) (내용은 당연히 비밀.) (2) | 2024.09.25 |
---|---|
JavaScript를 활용하여 동적 데이터 생성하기 (2) | 2024.09.24 |
스타벅스 주문 시스템 만들기 (난이도 상) (2) (0) | 2024.09.19 |
스타벅스 주문 시스템 만들기 (난이도 상) (1) (1) | 2024.09.18 |
MBTI 테스트 (난이도 중) (2) | 2024.09.17 |