-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[이정중]-vending-machine #17
base: main
Are you sure you want to change the base?
Changes from 12 commits
8ef3ab0
42bbab5
7d9aeb3
dcffcdd
609caf3
9c18f2d
3e0d876
0eebc7d
a27d8b5
69938ef
9da5572
caf3975
02d5afb
09650eb
c15b513
0f16b29
2206ce6
cf4d486
b2b9f8e
51e8afd
ccdb187
4560fda
445d98c
760cb2b
52b5c83
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Document</title> | ||
<link rel="stylesheet" href="./reset.css"> | ||
<link rel="stylesheet" href="./style.css"> | ||
</head> | ||
<body> | ||
<main id="Wrap" class=""> | ||
<div class="balance_btns_warp"> | ||
<input readonly type="text" class="balance" value="0"> | ||
<div class="btn_wrap grid"></div> | ||
</div> | ||
<div class="controler_history_wrap"> | ||
<form class="controller grid"> | ||
<input type="text" class="controller_input"> | ||
<button type="submit" class="controller_btn insert_coin">투입</button> | ||
<button type="button" class="controller_btn return_balance">반환</button> | ||
</form> | ||
<ul class="history" readonly> | ||
</ul> | ||
</div> | ||
</main> | ||
<script src="./index.js" type="module"></script> | ||
</body> | ||
</html> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
const $controllerInput = document.querySelector(".controller_input"); | ||
const $controllerForm = document.querySelector(".controller"); | ||
const $balance = document.querySelector(".balance"); | ||
const $btnWrap = document.querySelector(".btn_wrap"); | ||
const $returnBalanceBtn = document.querySelector(".return_balance"); | ||
const $historyUl = document.querySelector(".history"); | ||
|
||
const CHEAPEST_PRICE = 300; | ||
const ALL_ITEMS_COUNT = 9; | ||
const GENTLEE = "GT"; | ||
let balance = 0; | ||
|
||
const addComma = (number) => | ||
number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); | ||
const changeBalance = (balance) => { | ||
$balance.value = balance.toLocaleString(); | ||
}; | ||
const returnBalance = () => { | ||
if (balance === 0) return; | ||
logHistory(`${balance}원을 반환합니다.`); | ||
balance = 0; | ||
changeBalance(balance); | ||
}; | ||
const logHistory = (logText) => { | ||
const $li = document.createElement("li"); | ||
$li.innerHTML = logText; | ||
$historyUl.appendChild($li); | ||
$historyUl.scrollTo({ top: $historyUl.scrollHeight, behavior: "smooth" }); | ||
}; | ||
|
||
const onChangeControllerInput = (inputEvent) => { | ||
const valueOnlyNumber = inputEvent.target.value.replace(/[^0-9]/g, ""); | ||
$controllerInput.value = valueOnlyNumber; | ||
}; | ||
const onSubmitControllerForm = (e) => { | ||
e.preventDefault(); | ||
if ($controllerInput.value === "") return; | ||
balance += +$controllerInput.value; | ||
changeBalance(balance); | ||
logHistory(`${$controllerInput.value}원을 투입했습니다.`); | ||
$controllerInput.value = ""; | ||
}; | ||
const onClickItem = (price, itemName) => { | ||
if (balance < price) return; | ||
|
||
balance -= price; | ||
changeBalance(balance); | ||
logHistory(`${itemName}을 구입하였습니다.`); | ||
if (balance < CHEAPEST_PRICE) returnBalance(); | ||
}; | ||
const makeBtns = () => { | ||
for (let i = 0; i < ALL_ITEMS_COUNT; i++) { | ||
const $btn = document.createElement("button"); | ||
const price = CHEAPEST_PRICE + i * 100; | ||
const itemName = `${GENTLEE}${price}`; | ||
$btn.classList.add("item"); | ||
$btn.innerHTML = itemName; | ||
$btn.addEventListener("click", () => onClickItem(price, itemName)); | ||
$btn.addEventListener("mousedown", () => { | ||
balance < price && changeBalance(price); | ||
}); | ||
$btn.addEventListener("mouseup", () => { | ||
balance < price && changeBalance(balance); | ||
}); | ||
$btn.addEventListener("mouseout", () => { | ||
balance < price && changeBalance(balance); | ||
}); | ||
$btnWrap.appendChild($btn); | ||
} | ||
}; | ||
|
||
$controllerInput.addEventListener("input", onChangeControllerInput); | ||
$controllerForm.addEventListener("submit", onSubmitControllerForm); | ||
$returnBalanceBtn.addEventListener("click", returnBalance); | ||
makeBtns(); |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 2024년의 환경은 2011년과 너무 달라서, 이제는 CSS Reset이 거의 필요하지 않고 예전에 비해 굉장히 간단한 선언만 필요합니다. 😄 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 감사합니다!! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/* http://meyerweb.com/eric/tools/css/reset/ | ||
v2.0 | 20110126 | ||
License: none (public domain) | ||
*/ | ||
|
||
html, body, div, span, applet, object, iframe, | ||
h1, h2, h3, h4, h5, h6, p, blockquote, pre, | ||
a, abbr, acronym, address, big, cite, code, | ||
del, dfn, em, img, ins, kbd, q, s, samp, | ||
small, strike, strong, sub, sup, tt, var, | ||
b, u, i, center, | ||
dl, dt, dd, ol, ul, li, | ||
fieldset, form, label, legend, | ||
table, caption, tbody, tfoot, thead, tr, th, td, | ||
article, aside, canvas, details, embed, | ||
figure, figcaption, footer, header, hgroup, | ||
menu, nav, output, ruby, section, summary, | ||
time, mark, audio, video, input, textarea { | ||
margin: 0; | ||
padding: 0; | ||
border: 0; | ||
font-size: 100%; | ||
font: inherit; | ||
vertical-align: baseline; | ||
box-sizing: border-box; | ||
} | ||
/* HTML5 display-role reset for older browsers */ | ||
article, aside, details, figcaption, figure, | ||
footer, header, hgroup, menu, nav, section { | ||
display: block; | ||
} | ||
body { | ||
line-height: 1; | ||
} | ||
ol, ul { | ||
list-style: none; | ||
} | ||
blockquote, q { | ||
quotes: none; | ||
} | ||
blockquote:before, blockquote:after, | ||
q:before, q:after { | ||
content: ''; | ||
content: none; | ||
} | ||
table { | ||
border-collapse: collapse; | ||
border-spacing: 0; | ||
} | ||
|
||
button{ | ||
cursor: pointer; | ||
} | ||
input{ | ||
border: 1px solid #000; | ||
} | ||
input::-webkit-outer-spin-button, | ||
input::-webkit-inner-spin-button { | ||
-webkit-appearance: none; | ||
margin: 0; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
#Wrap{ | ||
max-width: 747px; | ||
margin: 0 auto; | ||
gap: 8px; | ||
} | ||
|
||
.balance_btns_warp{ | ||
width: 100%; | ||
padding: 16px; | ||
background-color: skyblue; | ||
} | ||
.balance_btns_warp .balance{ | ||
width: 100%; | ||
height: 80px; | ||
text-align: center; | ||
margin-bottom: 24px; | ||
font-size: 36px; | ||
} | ||
|
||
|
||
.balance_btns_warp .btn_wrap{ | ||
display: grid; | ||
grid-template-rows: repeat(3, 1fr); | ||
grid-template-columns: repeat(3, 1fr); | ||
gap: 12px; | ||
} | ||
|
||
.balance_btns_warp .btn_wrap .item{ | ||
height: 100px; | ||
font-size: 24px; | ||
background-color: turquoise; | ||
} | ||
.balance_btns_warp .btn_wrap .item:hover{ | ||
background-color: cornflowerblue; | ||
} | ||
.balance_btns_warp .btn_wrap .item:active{ | ||
background-color: blue; | ||
} | ||
|
||
.controler_history_wrap{ | ||
width: 100%; | ||
padding: 16px; | ||
background-color: yellowgreen; | ||
} | ||
.controler_history_wrap .controller{ | ||
display: grid; | ||
grid-template-columns: 3fr 1fr 1fr; | ||
gap: 8px; | ||
height: 80px; | ||
margin-bottom: 24px; | ||
font-size: 36px; | ||
} | ||
.controler_history_wrap .controller .controller_input{ | ||
min-width: 0; | ||
padding-left: 16px; | ||
} | ||
.controler_history_wrap .controller .controller_btn{ | ||
font-size: 24px; | ||
} | ||
.controler_history_wrap .history{ | ||
display: flex; | ||
flex-direction: column; | ||
gap: 8px; | ||
width: 100%; | ||
height: 321px; | ||
padding: 16px; | ||
background-color: white; | ||
overflow: auto; | ||
|
||
} | ||
@media screen and (min-width : 1024px) { | ||
#Wrap{ | ||
display: flex; | ||
max-width: 1024px; | ||
} | ||
.balance_btns_warp, .controler_history_wrap{ | ||
width: 50%; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이런 방식도 고민해 볼 수 있습니다. :)
자세한 구현은 DOM API만 이용한 드래그앤드롭 구현을 보면 도움이 됩니다.