Figma를 통해 간단 구현
(1) 몸무게와 신장, 결과 버튼 만들기
index.html
<form>
<div class="row">
<div class="form-input">
<label for="bmi-weight">몸무게(kg)</label>
<input id="bmi-weight" class="input" name="bmi-weight" type="number" value="" placeholder="kg 단위">
</div>
<div class="form-input">
<label for="bmi-height">신장(cm)</label>
<input id="bmi-height" class="input" name="bmi-height" type="number" value="" placeholder="cm 단위">
</div>
<div class="form-button">
<button type="submit" id="resultBtn" class="btn-result">결과</button>
</div>
</div>
</form>
main.css
form {width:100%;}
.row {display:flex;flex-direction:row;justify-content:center;gap:4px;margin-bottom:4px;}
.form-input {display:flex;flex-direction: column;margin-left:4px;}
.form-input label {color:#6B778C;font-size:12px;line-height:16px;margin-bottom:4px;font-weight:800;}
.form-input input {background-color:#FAFBFC;border:2px solid #DFE1E6;margin:0;padding:0 12px;width:200px;height:48px;box-sizing: border-box;outline: none;border-radius:4px;color:#091E42;}
.form-input input::placeholder {color:#a5aec4;}
.form-button {margin:20px 0 0 4px;}
.btn-result {padding:0 40px;height:48px;background-color:#0E1E3A;color:#FFF;text-align: center;border-radius:4px;display:flex;justify-content:center;align-items:center;border:none;}
.btn-result.line {color:#0E1E3A;border:1px solid #0E1E3A;background-color:#FFF;margin-top:8px;}
(2) BMI 수치와 상태 표시 결과, 초기화 버튼 만들기
index.html
<form>
...
<div id="res">
<div class="bmi-wrap">
<progress id="bmi-progress" class="progress" value="" min="0" max="100" optimum="23" low="18.5" high="25"></progress>
<div class="bmi-message">
<p class="main">당신의 BMI는 <strong id="bmi" class="msg-color"></strong> 입니다.</p>
<p class="sub"><strong id="state" class="msg-color"></strong> 입니다.</p>
</div>
<div class="row">
<button type="reset" id="reset" class="btn-result line" style="display:none;">초기화</button>
</div>
</div>
</div>
</form>
main.css
.bmi-wrap {display:flex;flex-direction: column;align-content: center;margin:36px 0;}
.progress {appearance: none; width:512px; height:6px; margin:0 auto;}
.progress::-webkit-progress-bar {background:#EBECF0;border-radius:6px;box-shadow: inset 3px 3px 10px #EBECF0;}
.progress::-webkit-progress-value {border-radius:6px;}
.progress.normal::-webkit-progress-value {background: #11A65E;}
.progress.underweight::-webkit-progress-value,
.progress.overweight::-webkit-progress-value,
.progress.obesity::-webkit-progress-value {background: #E31C1C;}
.bmi-message {margin:24px 0 12px;text-align:center;}
.bmi-message .main {height:30px;font-size:18px;line-height:24px;margin-bottom:8px;}
.bmi-message .sub {height:30px;font-size:14px;line-height:20px;}
.bmi-message .msg-color {display:inline-block;font-weight:800;width:80px; border-bottom:1px solid #0E1E3A;}
Point : 체중(kg)를 신장(cm)의 제곱으로 나눈 값
(1) 구현 로직 정리
main.js
function onSubmit(event) {
event.preventDefault();
// 입력란의 문자열을 실수로 변경
const w = parseFloat(event.target[0].value)
const h = parseFloat(event.target[1].value)
console.log(w, h)
// 조건 : 숫자인지, 양수인지
// parseFloat : 수가 아닌 문자로 시작하면 NaN을 반환하므로 isNaN 함수 사용 (isNaN : 숫자가 아닌 값을 찾음)
if(isNaN(w) || isNaN(h) || w <= 0 || h <= 0) {
alert("적절한 값이 아닙니다.")
return;
}
// BMI 계산 : 소수점 2자리까지 표시(toFixed)
const bmi = w / ((h/100) * (h/100))
console.log(bmi.toFixed(2))
// submit 시 결과 표시
const res = document.getElementById("res")
res.style.display = "block"
// submit 시 초기화 버튼 표시
const resetBtnEl = document.getElementById("reset")
resetBtnEl.style.display = "block"
// BMI 수식 및 진행률 표시
const bmiEl = document.getElementById("bmi");
const progressEl = document.getElementById("bmi-progress");
bmiEl.innerText = bmi.toFixed(2)
progressEl.value = bmi
let state;
let common = true
if(bmi < 18.5) {
state = "저체중"
common = false;
progressEl.classList.add('underweight')
}
if(bmi >= 18.5 && bmi <= 23) {
state = "정상체중"
common = true;
progressEl.classList.add('normal')
}
if(bmi >= 23 && bmi <= 25) {
state = "과체중"
common = false;
progressEl.classList.add('overweight')
}
if(bmi >= 25) {
state = "비만"
common = false;
progressEl.classList.add('obesity')
}
const stateEl = document.getElementById("state");
stateEl.innerText = state
stateEl.style.color = common ? "#11A65E" : "#E31C1C"
bmiEl.style.color = common ? "#11A65E" : "#E31C1C"
// 초기화버튼 시 진행률 초기화
const resutBtnEl = document.getElementById("resultBtn");
resetBtnEl.addEventListener("click", function() {
progressEl.classList.remove('underweight');
progressEl.classList.remove('normal');
progressEl.classList.remove('overweight');
progressEl.classList.remove('obesity');
});
}
(2) onsubmit 시 onSubmit 함수 실행, onreset 시 res 결과 숨김(초기화)
index.html
<form onsubmit="onSubmit(event)" onreset="document.getElementById('res').style.display = 'none'">
...
...
</form>
💬 간만에 1개로 정리한 강의, 이번 강의는 어렵지 않아서 원래 있던 내용에 몇 가지 사항을 응용해보았다. 찾아보면 같은 BMI 구현인데 다양한 방식이 있는 거 같았다.
다른 예제 코드
💬 건강 TMI
이전 직장에서 집이 가까운 거리(25분) + 개발공부시작 + 스트레스 폭식 + 먹고 바로 눕기 등등을 하면서 현재 회사 입사 당시 4kg가 찐 상태였다. 아침 일찍+야근 등 바이오리듬도 불안정한 것 같아 체중감량과 절식, 심신안정에 도움이 되는 한약을 지어먹고 있다. 나이가 들수록 내적으로 여러 질환이 올 수 있기 때문에 적절하게 관리하는 것이 중요한 것 같다. 특히 컴퓨터를 많이 보는 직업군이라면 더더욱.. 그 외에도 영양제 12종을 챙겨 먹고 있는데.. 4년 전 우연히 본 이 블로그를 계기로.. (약쟁이?) 열심히 일하려면 아무래도 건강 관리가 무엇보다 중요한 것 같다. (요즘은 바쁜 와중인데 어느 정도 적응이 되고, 업무가 안정화 되면 운동도 병행할 예정이다 💪..) 그치만 식습관이 제일 중요..(군것질...)