-
Notifications
You must be signed in to change notification settings - Fork 5
[tip-calculator-app] modi(경주원) 미션 제출합니다. #4
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
base: joowon
Are you sure you want to change the base?
Changes from all commits
19c2b49
2be8908
e6e28a4
af54283
2065683
7b2bd23
5122c4b
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 |
|---|---|---|
| @@ -1,44 +1,95 @@ | ||
| <!DOCTYPE html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="UTF-8"> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- displays site properly based on user's device --> | ||
|
|
||
| <link rel="icon" type="image/png" sizes="32x32" href="./images/favicon-32x32.png"> | ||
|
|
||
| <title>Frontend Mentor | Tip calculator app</title> | ||
|
|
||
| <!-- Feel free to remove these styles or customise in your own stylesheet 👍 --> | ||
| <style> | ||
| .attribution { font-size: 11px; text-align: center; } | ||
| .attribution a { color: hsl(228, 45%, 44%); } | ||
| </style> | ||
| </head> | ||
| <body> | ||
|
|
||
| Bill | ||
|
|
||
| Select Tip % | ||
| 5% | ||
| 10% | ||
| 15% | ||
| 25% | ||
| 50% | ||
| Custom | ||
|
|
||
| Number of People | ||
|
|
||
| Tip Amount | ||
| / person | ||
|
|
||
| Total | ||
| / person | ||
|
|
||
| Reset | ||
|
|
||
| <div class="attribution"> | ||
| Challenge by <a href="https://www.frontendmentor.io?ref=challenge" target="_blank">Frontend Mentor</a>. | ||
| Coded by <a href="#">Your Name Here</a>. | ||
| </div> | ||
| </body> | ||
| </html> | ||
| <head> | ||
| <meta charset="UTF-8" /> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
| <!-- displays site properly based on user's device --> | ||
|
|
||
| <link | ||
| rel="icon" | ||
| type="image/png" | ||
| sizes="32x32" | ||
| href="./images/favicon-32x32.png" | ||
| /> | ||
| <link rel="stylesheet" href="style.css" /> | ||
| <link rel="preconnect" href="https://fonts.googleapis.com" /> | ||
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> | ||
| <link | ||
| href="https://fonts.googleapis.com/css2?family=Kumbh+Sans:wght@400;700&display=swap" | ||
| rel="stylesheet" | ||
| /> | ||
|
|
||
| <title>Frontend Mentor | Tip calculator app</title> | ||
| </head> | ||
| <body> | ||
| <div class="container"> | ||
| <div class="logo-section"> | ||
| <img src="images/logo.svg" /> | ||
| </div> | ||
| <div class="calculator-section"> | ||
| <div class="input-section"> | ||
| <div class="input-title-box"> | ||
| <div class="input-title">Bill</div> | ||
| <div class="input-alert bill-alert">Can't be zero</div> | ||
| </div> | ||
|
|
||
| <input | ||
| type="text" | ||
| class="calculator-input bill-input" | ||
| placeholder="0" | ||
| oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*)\./g, '$1');" | ||
| /> | ||
|
Comment on lines
+36
to
+41
Member
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. 이건 뭔가요??
Author
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. 숫자만 입력하고 싶은데 |
||
|
|
||
| <div class="input-title">Select Tip %</div> | ||
| <div class="select-tip-section"> | ||
| <button class="select-tip-button" value="0.05">5%</button> | ||
| <button class="select-tip-button" value="0.10">10%</button> | ||
| <button class="select-tip-button" value="0.15">15%</button> | ||
| <button class="select-tip-button" value="0.25">25%</button> | ||
| <button class="select-tip-button" value="0.50">50%</button> | ||
| <input | ||
| type="text" | ||
| class="custom-tip-input" | ||
| placeholder="Custom" | ||
| oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*)\./g, '$1');" | ||
|
Member
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. oninput에서 사용되는 이벤트 핸들링 로직이 중복되므로 재사용성을 위해 함수로 분리 해도 좋을 것 같다고 생각합니다! |
||
| /> | ||
| </div> | ||
|
|
||
| <div class="input-title-box"> | ||
| <div class="input-title">Number of People</div> | ||
| <div class="input-alert people-alert">Can't be zero</div> | ||
| </div> | ||
|
|
||
| <input | ||
| type="text" | ||
| class="calculator-input people-input" | ||
| placeholder="0" | ||
| oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*)\./g, '$1');" | ||
| /> | ||
| </div> | ||
| <div class="result-section"> | ||
| <div class="tip-result-section"> | ||
| <div class="tip-result-row"> | ||
| <div class="result-title-box"> | ||
| <div class="result-title">Tip Amount</div> | ||
| <div class="result-subtitle">/ person</div> | ||
| </div> | ||
| <div class="tip-result tip-per-person">$ 0.00</div> | ||
| </div> | ||
|
|
||
| <div class="tip-result-row"> | ||
| <div class="result-title-box"> | ||
| <div class="result-title">Total</div> | ||
| <div class="result-subtitle">/ person</div> | ||
| </div> | ||
| <div class="tip-result total-per-person">$ 0.00</div> | ||
| </div> | ||
| </div> | ||
|
|
||
| <button class="reset-button">RESET</button> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </body> | ||
| <script src="index.js"></script> | ||
| </html> | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,108 @@ | ||||||
| const billInput = document.querySelector(".bill-input"); | ||||||
| const billAlert = document.querySelector(".bill-alert"); | ||||||
|
|
||||||
| const tipRatioInputs = document.querySelectorAll(".select-tip-button"); | ||||||
| const customTipRatioInput = document.querySelector(".custom-tip-input"); | ||||||
|
|
||||||
| const peopleInput = document.querySelector(".people-input"); | ||||||
| const peopleAlert = document.querySelector(".people-alert"); | ||||||
|
|
||||||
| const tipPerPersonOutput = document.querySelector(".tip-per-person"); | ||||||
| const totalPerPersonOutput = document.querySelector(".total-per-person"); | ||||||
| const resetButton = document.querySelector(".reset-button"); | ||||||
|
Comment on lines
+1
to
+12
Member
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. 의미에 맞게 나누어서 띄어쓰기를 한 것이 보기 좋은 것 같습니다. |
||||||
|
|
||||||
| let bill = 0; | ||||||
| let tipRatio = 0; | ||||||
| let people = 0; | ||||||
| let tipPerPerson = 0; | ||||||
| let totalPerPerson = 0; | ||||||
|
Comment on lines
+14
to
+18
Member
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. 변순 직관적이라서 좋지만, 관련 있는 데이터는 묶어서 데이터를 관리하는 것이 좋습니다. |
||||||
|
|
||||||
| const calculate = () => { | ||||||
| if (bill === 0 || tipRatio === 0 || people === 0) { | ||||||
| return; | ||||||
| } | ||||||
|
|
||||||
| tipPerPerson = (bill * tipRatio) / people; | ||||||
| totalPerPerson = bill / people + tipPerPerson; | ||||||
|
|
||||||
| tipPerPersonOutput.innerHTML = `$ ${tipPerPerson.toFixed(2)}`; | ||||||
| totalPerPersonOutput.innerHTML = `$ ${totalPerPerson.toFixed(2)}`; | ||||||
| }; | ||||||
|
|
||||||
| const onBillChange = (e) => { | ||||||
| if (e.target.value === "0") { | ||||||
| billAlert.style.visibility = "visible"; | ||||||
| e.target.style.border = "1px solid red"; | ||||||
| } else { | ||||||
| billAlert.style.visibility = "hidden"; | ||||||
| e.target.style.border = "none"; | ||||||
|
|
||||||
| bill = Number(e.target.value); | ||||||
|
Member
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. 단항 연산자
Suggested change
Author
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. 사실 당시에 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. 오 저도 알아갑니다!! |
||||||
| calculate(); | ||||||
| } | ||||||
| }; | ||||||
|
|
||||||
| const onTipRatioClick = (e) => { | ||||||
| tipRatioInputs.forEach((tipRatioInput) => { | ||||||
| tipRatioInput.classList.remove("selected"); | ||||||
| }); | ||||||
| customTipRatioInput.value = null; | ||||||
|
Member
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. value에 null보다는 빈 문자열은 어떨까요 ? 자바스크립트에서는 이미 값이 없음을 나타내는 Why I banned ‘null’ from my Javascript code and why you should too
Author
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. 스터디 때 다뤘던 내용!!!인데 순간 거꾸로 착각하고 코드를 작성했네요. 다음부터는 조금 차분하게 스프린트를 진행해야겠습니다.... 그나저나 input tag의 value 초기값이 빈 문자열인 건 이번에 처음 알았어요! |
||||||
|
|
||||||
| e.target.classList.add("selected"); | ||||||
| tipRatio = Number(e.target.value); | ||||||
| calculate(); | ||||||
| }; | ||||||
|
|
||||||
| const onCustomTipRatioChange = (e) => { | ||||||
| tipRatioInputs.forEach((tipRatioInput) => { | ||||||
| tipRatioInput.classList.remove("selected"); | ||||||
| }); | ||||||
|
Comment on lines
+57
to
+59
Member
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. 자주 쓰이는 로직이므로 분리해서 사용하는 건 어떨까요? |
||||||
|
|
||||||
| tipRatio = Number(e.target.value); | ||||||
| calculate(); | ||||||
| }; | ||||||
|
|
||||||
| const onPeopleChange = (e) => { | ||||||
| if (e.target.value === "0") { | ||||||
| peopleAlert.style.visibility = "visible"; | ||||||
| e.target.style.border = "1px solid red"; | ||||||
| } else { | ||||||
| peopleAlert.style.visibility = "hidden"; | ||||||
| e.target.style.border = "none"; | ||||||
|
|
||||||
| people = Number(e.target.value); | ||||||
| calculate(); | ||||||
| } | ||||||
| }; | ||||||
|
|
||||||
| const onResetButtonClick = (e) => { | ||||||
| bill = 0; | ||||||
| tipRatio = 0; | ||||||
| people = 0; | ||||||
| tipPerPerson = 0; | ||||||
| totalPerPerson = 0; | ||||||
|
|
||||||
| billInput.value = null; | ||||||
| billInput.style.border = "none"; | ||||||
| billAlert.style.visibility = "hidden"; | ||||||
|
|
||||||
| tipRatioInputs.forEach((tipRatioInput) => { | ||||||
| tipRatioInput.classList.remove("selected"); | ||||||
| }); | ||||||
| customTipRatioInput.value = null; | ||||||
|
|
||||||
| peopleInput.value = null; | ||||||
| peopleInput.style.border = "none"; | ||||||
| peopleAlert.style.visibility = "hidden"; | ||||||
|
|
||||||
| tipPerPersonOutput.innerHTML = "$ 0.00"; | ||||||
| totalPerPersonOutput.innerHTML = "$ 0.00"; | ||||||
| }; | ||||||
|
|
||||||
| billInput.addEventListener("keyup", onBillChange); | ||||||
| tipRatioInputs.forEach((tipRatioInput) => { | ||||||
| tipRatioInput.addEventListener("click", onTipRatioClick); | ||||||
| }); | ||||||
| customTipRatioInput.addEventListener("keyup", onCustomTipRatioChange); | ||||||
| peopleInput.addEventListener("keyup", onPeopleChange); | ||||||
| resetButton.addEventListener("click", onResetButtonClick); | ||||||
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.
저는 사람수가 0이 되는 경우에 대해서만 alert 처리를 했는데, input에 대해서도 0일 때를 처리하니 더 디테일이 사는 것 같아요!