๐ ๋ค์ด๊ฐ๋ฉฐ
์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์ด์ฉํ ํ์๊ฐ์ , ์ฝ๊ด ๋์ ์์ ๋ฅผ ๊ฒ์ํ๋ฉด jQuery๋ฅผ ์ด์ฉํ ์์ ๊ฐ ๋ง์๋ฐ, ์์ฆ์๋ jQuery๋ฅผ ๋ง์ด ์ฌ์ฉํ์ง ์๋ ์ถ์ธ์ด๊ณ , ์์ Vanilla ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฉํ๋ฉฐ ๊ณต๋ถํ๋ ๊ฒ์ด ๋งค์ฐ ๋์์ด ๋๊ธฐ ๋๋ฌธ์ jQuery ์์ด ์์ Vanilla ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์ด์ฉํ์ฌ ์์ ๋ฅผ ๋ง๋ค์ด ๋ณด๊ฒ ์ต๋๋ค.
์์ฑ ํ๋ฉด
HTML ๊ตฌ์ฑ
<div class="wrap">
<div class="logo">
<h1>JUN</h1>
</div>
<div class="contents">
<form action="/" method="POST" id="form__wrap">
<div class="terms__check__all">
<input type="checkbox" name="checkAll" id="checkAll"" />
<label for="checkAll"
>JUN ์ด์ฉ์ฝ๊ด, ๊ฐ์ธ์ ๋ณด ์์ง ๋ฐ ์ด์ฉ, ํ๋ก๋ชจ์
์ ๋ณด ์์ (์ ํ)์<br />๋ชจ๋ ๋์ํฉ๋๋ค.</label
>
</div>
<ul class="terms__list">
<li class="terms__box">
<div class="input__check">
<input type="checkbox" name="agreement" id="termsOfService" value="termsOfService" required />
<label for="termsOfService" class="required">JUN ์ด์ฉ์ฝ๊ด ๋์</label>
</div>
<div class="terms__content">
์ฌ๋ฌ๋ถ์ ํ์ํฉ๋๋ค. JUN ์๋น์ค ๋ฐ ์ ํ(์ดํ ‘์๋น์ค’)์ ์ด์ฉํด ์ฃผ์
์ ๊ฐ์ฌํฉ๋๋ค. ๋ณธ ์ฝ๊ด์ ๋ค์ํ JUN
์๋น์ค์ ์ด์ฉ๊ณผ ๊ด๋ จํ์ฌ JUN ์๋น์ค๋ฅผ ์ ๊ณตํ๋ JUN ์ฃผ์ํ์ฌ(์ดํ ‘JUN’)์ ์ด๋ฅผ ์ด์ฉํ๋ JUN ์๋น์ค
ํ์(์ดํ ‘ํ์’) ๋๋ ๋นํ์๊ณผ์ ๊ด๊ณ๋ฅผ ์ค๋ช
ํ๋ฉฐ, ์์ธ๋ฌ ์ฌ๋ฌ๋ถ์ JUN ์๋น์ค ์ด์ฉ์ ๋์์ด ๋ ์ ์๋
์ ์ตํ ์ ๋ณด๋ฅผ ํฌํจํ๊ณ ์์ต๋๋ค. JUN ์๋น์ค๋ฅผ ์ด์ฉํ์๊ฑฐ๋ JUN ์๋น์ค ํ์์ผ๋ก ๊ฐ์
ํ์ค ๊ฒฝ์ฐ ์ฌ๋ฌ๋ถ์ ๋ณธ
์ฝ๊ด ๋ฐ ๊ด๋ จ ์ด์ ์ ์ฑ
์ ํ์ธํ๊ฑฐ๋ ๋์ํ๊ฒ ๋๋ฏ๋ก, ์ ์ ์๊ฐ์ ๋ด์์ด ์ฃผ์ ๊น๊ฒ ์ดํด๋ด ์ฃผ์๊ธฐ
๋ฐ๋๋๋ค.
</div>
</li>
<li class="terms__box">
<div class="input__check">
<input type="checkbox" name="agreement" id="privacyPolicy" value="privacyPolicy" required />
<label for="privacyPolicy" class="required">๊ฐ์ธ์ ๋ณด ์์ง ๋ฐ ์ด์ฉ ๋์</label>
</div>
<div class="terms__content">
๊ฐ์ธ์ ๋ณด๋ณดํธ๋ฒ์ ๋ฐ๋ผ JUN์ ํ์๊ฐ์
์ ์ฒญํ์๋ ๋ถ๊ป ์์งํ๋ ๊ฐ์ธ์ ๋ณด์ ํญ๋ชฉ, ๊ฐ์ธ์ ๋ณด์ ์์ง ๋ฐ
์ด์ฉ๋ชฉ์ , ๊ฐ์ธ์ ๋ณด์ ๋ณด์ ๋ฐ ์ด์ฉ๊ธฐ๊ฐ, ๋์ ๊ฑฐ๋ถ๊ถ ๋ฐ ๋์ ๊ฑฐ๋ถ ์ ๋ถ์ด์ต์ ๊ดํ ์ฌํญ์ ์๋ด ๋๋ฆฌ์ค๋
์์ธํ ์ฝ์ ํ ๋์ํ์ฌ ์ฃผ์๊ธฐ ๋ฐ๋๋๋ค.1. ์์งํ๋ ๊ฐ์ธ์ ๋ณด ์ด์ฉ์๋ ํ์๊ฐ์
์ ํ์ง ์์๋ ์ ๋ณด ๊ฒ์,
๋ด์ค ๋ณด๊ธฐ ๋ฑ ๋๋ถ๋ถ์ ๋ค์ด๋ฒ ์๋น์ค๋ฅผ ํ์๊ณผ ๋์ผํ๊ฒ ์ด์ฉํ ์ ์์ต๋๋ค. ์ด์ฉ์๊ฐ ๋ฉ์ผ, ์บ๋ฆฐ๋, ์นดํ,
๋ธ๋ก๊ทธ ๋ฑ๊ณผ ๊ฐ์ด ๊ฐ์ธํ ํน์ ํ์์ ์๋น์ค๋ฅผ ์ด์ฉํ๊ธฐ ์ํด ํ์๊ฐ์
์ ํ ๊ฒฝ์ฐ, ๋ค์ด๋ฒ๋ ์๋น์ค ์ด์ฉ์
์ํด ํ์ํ ์ต์ํ์ ๊ฐ์ธ์ ๋ณด๋ฅผ ์์งํฉ๋๋ค.
</div>
</li>
<li class="terms__box">
<div class="input__check">
<input type="checkbox" name="agreement" id="allowPromotions" value="allowPromotions" />
<label for="allowPromotions">ํ๋ก๋ชจ์
์ ๋ณด ์์ ๋์</label>
</div>
<div class="terms__content">
JUN์์ ์ ๊ณตํ๋ ์ด๋ฒคํธ/ํํ ๋ฑ ๋ค์ํ ์ ๋ณด๋ฅผ ํด๋์ ํ(JUN์ฑ ์๋ฆผ ๋๋ ๋ฌธ์), ์ด๋ฉ์ผ๋ก ๋ฐ์๋ณด์ค ์
์์ต๋๋ค. ์ผ๋ถ ์๋น์ค(๋ณ๋ ํ์ ์ฒด๊ณ๋ก ์ด์ํ๊ฑฐ๋ JUN ๊ฐ์
์ดํ ์ถ๊ฐ ๊ฐ์
ํ์ฌ ์ด์ฉํ๋ ์๋น์ค ๋ฑ)์
๊ฒฝ์ฐ, ๊ฐ๋ณ ์๋น์ค์ ๋ํด ๋ณ๋ ์์ ๋์๋ฅผ ๋ฐ์ ์ ์์ผ๋ฉฐ, ์ด๋์๋ ์์ ๋์์ ๋ํด ๋ณ๋๋ก ์๋ดํ๊ณ
๋์๋ฅผ ๋ฐ์ต๋๋ค.
</div>
</li>
</ul>
<button type="submit" class="next-button" disabled>ํ์ธ</button>
</form>
</div>
</div>
* ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋์์ ๊ฐ๊ฐ์ ๊ฐ์ ํ์ธํด์ผ ํ๊ธฐ ๋๋ฌธ์ ๊ฐ๊ฐ์ ์ฒดํฌ๋ฐ์ค์ id์ value๋ฅผ ์ฃผ์์ต๋๋ค.
์ด ๊ธ์ ๋ชฉ์ ์ ์๋ฐ์คํฌ๋ฆฝํธ๋ก ์์ ๋ฅผ ์์ฑํ๋ ๋ชฉ์ ์ด๊ธฐ ๋๋ฌธ์ CSS ์คํ์ผ๋ง์ ๊ตณ์ด ์์ฑํ์ง ์์ ๊ฒ์ ๋๋ค.
์ด์ ์์ฑ๋ ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋๋ฅผ ํ๋ํ๋ ํด์ํด๊ฐ๋ฉด์ ์ ๋ฆฌ๋ฅผ ํ ๊ฒ์ ๋๋ค.
์ด ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๊ด ๋์ ์์ ์ ๋ก์ง์
1. ๋ชจ๋ ๋์๊ฐ ์ฒดํฌ๊ฐ ๋๋ฉด ๋ชจ๋ ์ฒดํฌ๋ฐ์ค๊ฐ ์ฒดํฌ๊ฐ ๋๊ณ ํด์ ๋๋ฉด ๋ชจ๋ ํด์ ๊ฐ ๋์ด์ผ ํจ.
2. ํ์ ๋์(2๊ฐ)๊ฐ ์ฒดํฌ๋์ด์ผ ๋ฒํผ์ด ํ์ฑํ๋๊ณ ํ๋๋ผ๋ ์ฒดํฌ๊ฐ ์๋๋ฉด ๋ฒํผ์ ๋นํ์ฑํ.
3. ๋ชจ๋ ๋์๋ฅผ ์ฒดํฌํ์ง ์๊ณ ๋ฐ์ 3๊ฐ์ ์ฒดํฌ๋ฐ์ค๋ก ์ผ์ผ์ด ์ฒดํฌํ์ ๋ ๋ชจ๋ ๋์ ์ฒดํฌ ๋ฐ์ค๊ฐ ํ์ฑํ๋์ด์ผ ํจ.
4. ๋ฐ๋๋ก ๋ชจ๋ ์ฒดํฌ๋์ด์๋ ์ํ์์ ์ฒดํฌ๋ฐ์ค ํ๋๋ผ๋ ํด์ ๊ฐ ๋๋ฉด ๋ชจ๋ ๋์ ์ฒดํฌ ๋ฐ์ค๊ฐ ํด์ ๋์ด์ผ ํจ.
์์ฑ๋ ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋
'use strict';
const form = document.querySelector('#form__wrap');
const checkAll = document.querySelector('.terms__check__all input');
const checkBoxes = document.querySelectorAll('.input__check input');
const submitButton = document.querySelector('button');
const agreements = {
termsOfService: false,
privacyPolicy: false,
allowPromotions: false,
};
form.addEventListener('submit', (e) => e.preventDefault()); // ์๋ก๊ณ ์นจ(submit) ๋๋ ๊ฒ ๋ง์
checkBoxes.forEach((item) => item.addEventListener('input', toggleCheckbox));
function toggleCheckbox(e) {
const { checked, id } = e.target;
agreements[id] = checked;
this.parentNode.classList.toggle('active');
checkAllStatus();
toggleSubmitButton();
}
function checkAllStatus() {
const { termsOfService, privacyPolicy, allowPromotions } = agreements;
if (termsOfService && privacyPolicy && allowPromotions) {
checkAll.checked = true;
} else {
checkAll.checked = false;
}
}
function toggleSubmitButton() {
const { termsOfService, privacyPolicy } = agreements;
if (termsOfService && privacyPolicy) {
submitButton.disabled = false;
} else {
submitButton.disabled = true;
}
}
checkAll.addEventListener('click', (e) => {
const { checked } = e.target;
if (checked) {
checkBoxes.forEach((item) => {
item.checked = true;
agreements[item.id] = true;
item.parentNode.classList.add('active');
});
} else {
checkBoxes.forEach((item) => {
item.checked = false;
agreements[item.id] = false;
item.parentNode.classList.remove('active');
});
}
toggleSubmitButton();
});
1. DOM
์ฐ์ ์ฝ๋ ์๋จ์ DOM ์์๋ค์ ์ก์์ฃผ์์ต๋๋ค.
const form = document.querySelector('#form__wrap'); // ๋ฐ์ดํฐ๋ฅผ ์ ์กํ๋ Form
const checkAll = document.querySelector('.terms__check__all input'); // ๋ชจ๋ ๋์ ์ฒดํฌ๋ฐ์ค
const checkBoxes = document.querySelectorAll('.input__check input'); // ๋ชจ๋ ๋์๋ฅผ ์ ์ธํ 3๊ฐ์ ์ฒดํฌ๋ฐ์ค
const submitButton = document.querySelector('button'); // ํ์ธ ๋ฒํผ
์๊น ์์์ ๋งํ ๋ก์ง๋๋ก
์ฆ, ์ฒดํฌ๋ฐ์ค์ ์ด๋ฒคํธ๊ฐ ์ผ์ด๋ ๋๋ง๋ค ์ฒดํฌ๋ฐ์ค์ ์ํ๋ฅผ ํ์ธํด์ ๋ณํ๋ฅผ ์์ผ์ฃผ์ด์ผ ํฉ๋๋ค.
๊ทธ๋์ ์ฒดํฌ๋๋ ์ฒดํฌ ๋ฐ์ค๋ค์ True & False ๊ฐ์ผ๋ก ์ ์ด๋ฅผ ํ๋ฉฐ ์ํ๋ฅผ ํ์ธํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ์๋์ ๊ฐ์ด Object๋ฅผ ์ด์ฉํด HTML์์ ์์ฑํ ์ฒดํฌ๋ฐ์ค ๊ฐ๊ฐ์ id์ ๋์ผํ๊ฒ ์์ฑํ ํ Default ๊ฐ์ ์ฃผ์์ต๋๋ค.
์ ์ด๋ฐ์์ผ๋ก ์์ฑํ๋์ง๋ ๊ณง ์ ์ ์์ต๋๋ค.
(์ฒดํฌ ๋ฐ์ค์ ์ฒดํฌ ์ฌ๋ถ(true & false)๋ฅผ ์ ์ฅํ๋ ์์ ์ ์ฅ ๊ณต๊ฐ ์ด๋ผ๊ณ ์๊ฐํ๋ฉด ์ผ๋จ ์ดํด๊ฐ ์ฌ์ธ ๊ฒ์ ๋๋ค.)
const agreements = {
termsOfService: false, // ์ฒซ๋ฒ์งธ ํ์๋์ ์ฒดํฌ๋ฐ์ค
privacyPolicy: false, // ๋๋ฒ์งธ ํ์๋์ ์ฒดํฌ๋ฐ์ค
allowPromotions: false, // ์ด๋ฒคํธ ์์ ๋์ ์ฒดํฌ๋ฐ์ค
};
2. ๋ชจ๋ ๋์ CheckBox
์ด์ ํด์ผ ํ ๊ฒ์ '๋ชจ๋ ๋์' ์ฒดํฌ๋ฐ์ค๊ฐ ์ฒดํฌ๊ฐ ๋๋ฉด ๋ชจ๋ ์ฒดํฌ๋ฐ์ค์ ์ฒดํฌ๋ฅผ ํ๊ณ , '๋ชจ๋ ๋์' ์ฒดํฌ๋ฐ์ค๊ฐ ํด์ ๋๋ฉด ๋ชจ๋ ์ฒดํฌ ๋ฐ์ค์ ์ฒดํฌ์ํ๋ฅผ ํด์ ๋๊ฒ ํด์ผ ํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ , ๋ฒํผ๋ ํ์ฑํ๋์ด์ผ ํ๋๋ฐ ๋ฒํผ์ด ํ์ฑํ๋๋ ์กฐ๊ฑด์ 'ํ์ ๋์'๊ฐ ๋ชจ๋ ์ฒดํฌ๋์ด์ผ ํ์ฑํ๊ฐ ๋์ด์ผ ํฉ๋๋ค.
๊ฐ๋จํ๊ฒ ๋จผ์ ์ค๋ช ํ๋ฉด '๋ชจ๋ ๋์' ์ฒดํฌ๋ฐ์ค๋ฅผ ์ฒดํฌ ๋๋ ํด์ ํ๊ฒ ๋๋ฉด ๋ชจ๋ ์ฒดํฌ ๋ฐ์ค๋ค์ ์ฒดํฌ ๋๋ ํด์ ํ๊ณ ๊ทธ ์ฒดํฌ ์ํ๋ฅผ ์์ ์์ฑํ Object์ ๋ณด๋ด์ฃผ๊ณ ๋ฒํผ์ ํ์ฑํ ๋๋ ๋นํ์ฑํํ๋ ํจ์๋ฅผ ์คํํฉ๋๋ค.
checkAll.addEventListener('click', (e) => {
const { checked } = e.target;
if (checked) {
checkBoxes.forEach((item) => {
item.checked = true;
agreements[item.id] = true;
item.parentNode.classList.add('active');
});
} else {
checkBoxes.forEach((item) => {
item.checked = false;
agreements[item.id] = false;
item.parentNode.classList.remove('active');
});
}
toggleSubmitButton();
});
'๋ชจ๋ ๋์' ์ฒดํฌ ๋ฐ์ค์ click event๊ฐ ๋ฐ์ํ๋ฉด ์์ ๊ฐ์ ์ฝ๋๊ฐ ์คํ๋๊ฒ ์์ฑํ์์ต๋๋ค.
click์ ํ๋ฉด event๊ฐ ๋ฐ์ํ๊ณ , event๊ฐ ๋ฐ์ํ๋ ์์๊ฐ event์ target์ด ๋๋ ๊ฒ์ ๋๋ค.
์ฆ, e.target์ '๋ชจ๋ ๋์' ์ฒดํฌ๋ฐ์ค ์์๋ฅผ ๋ปํฉ๋๋ค.
e.target์ ๋ถ๋ถ์ด ์ดํด๊ฐ ์ ๊ฐ๊ฑฐ๋ ๋ ์๊ณ ์ถ์ผ๋ฉด ์๋์ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํด๋ณด๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
developer.mozilla.org/ko/docs/Web/API/Event/target
const { checked } = e.target;
๊ทธ๋ฆฌ๊ณ ์์ ๊ฐ์ด ES6 ๋ฌธ๋ฒ์ธ ๊ตฌ์กฐ ๋ถํด ํ ๋น์ผ๋ก target์ checked ๊ฐ์ ๊ฐ์ ธ์ค๊ฒ ํ๋๋ฐ
(CheckBox์ ์ฒดํฌ ์ํ๋ฅผ ํ์ธํ ์ ์๋ checked๋ true(์ฒดํฌใ ) & false(์ฒดํฌ x ) ๊ฐ์ ๋ฐํํฉ๋๋ค.)
const checked = e.target.checked;
์ด๋ ๊ฒ ์์ฑํ ๊ฒ๊ณผ ๊ฐ์ต๋๋ค.
์ด ๋ถ๋ถ์ด ์ดํด๊ฐ ์ ๊ฐ๋ฉด ์๋์ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
์ด์ '์ฒดํฌ'๊ฐ ๋๋ฉด ์ํ๋ฌธ์ ์คํํด์ผ ํ๋๊น ์๋์ ๊ฐ์ด if๋ฌธ์ ์์ฑํ ๊ฒ์ ๋๋ค.
if (checked) {
checkBoxes.forEach((item) => {
item.checked = true;
agreements[item.id] = true;
item.parentNode.classList.add('active');
});
} else {
checkBoxes.forEach((item) => {
item.checked = false;
agreements[item.id] = false;
item.parentNode.classList.remove('active');
});
}
event target์์ ๋ฐ์ checked์ ๊ฐ์ด True (์ฒดํฌ) ๋ฉด forEach๋ฌธ์ ํตํด ์ฒดํฌ ๋ฐ์ค ์์๋ค์ ํ๋์ฉ ๋๋ ค์ ์ํ์ ํฉ๋๋ค.
(forEach์ ๋ํด ์๊ณ ์ถ์ผ๋ฉด ์๋์ ๋งํฌ ์ฐธ๊ณ )
developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
if (checked) {
checkBoxes.forEach((item) => {
item.checked = true;
agreements[item.id] = true;
item.parentNode.classList.add('active');
});
}
item(์ฒดํฌ๋ฐ์ค)์ checked๋ฅผ true๋ก ๋ณ๊ฒฝํฉ๋๋ค. ( checked๋ฅผ true๋ฅผ ์ฃผ๋ฉด ์ฒดํฌ ๋ฐ์ค๋ ์ฒดํฌ๊ฐ ๋จ.)
๊ทธ๋ค์ ์์์ ์์ฑํ Object์์ ์ฒดํฌ๋ฐ์ค์ id๊ฐ๊ณผ ๋์ผํ๊ฒ ์์ฑํ ๊ฒ์ ๋ณผ ์ ์์ ๊ฒ์ ๋๋ค.
์ฌ๊ธฐ์ item์ id๊ฐ์ ๋ฐ์์์ Object์์ ์์ฑํ id๊ฐ๊ณผ ๋์ผํ ๋ถ๋ถ์ true ๊ฐ์ ๋ฃ์ด ์ฃผ๋ ๊ฒ์ ๋๋ค.
agreements[item.id] = true;
์ด๋ ๊ฒ ๋ฃ์ด์ฃผ๋ ์ด์ ๋ if๋ฌธ์ ์ํํ ํ,
์ฒดํฌ๋ฐ์ค์ ์ฒดํฌ ์ฌ๋ถ(true & false)๋ฅผ ํ์ธํ๊ณ ๋ฒํผ์ ํ์ฑํํ ์ง ๋นํ์ฑํํ ์ง ์ ํด์ผ ํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
์ด์ else ๋ถ๋ถ์ ๋ฐ๋๋ก ์ฒดํฌ๊ฐ ํด์ ๋๋ฉด ๋ฐ๋๋ก ์ฒดํฌ๋ฐ์ค ์์๋ค์ forEach๋ฌธ์ ๋๋ ค ์ฒดํฌ๋ฅผ ํด์ ํ๊ณ ์์์ id์ Objcet ๊ฐ๋ค์ false๋ก ๋ณด๋ธ๋ค๊ณ ์ดํดํ์๋ฉด ๋ฉ๋๋ค.
else {
checkBoxes.forEach((item) => {
item.checked = false;
agreements[item.id] = false;
item.parentNode.classList.remove('active');
});
}
toggleSubmitButton();
์ด์ if๋ฌธ์ด ๋๋๊ฒ ๋๋ฉด ๋ฐ๋ก toggleSubmitButton(); ํจ์๋ฅผ ์คํํฉ๋๋ค.
3. ํ์ ๋์ ์ฒดํฌ ์ฌ๋ถ์ ๋ํ ๋ฒํผ ํ์ฑํ or ๋นํ์ฑํ
์ด ํจ์๋ 'ํ์ ๋์' ์ฒดํฌ ์ฌ๋ถ๋ฅผ ํ์ธํ ๋ค ๋ฒํผ์ ํ์ฑํ, ๋นํ์ฑํ ๋์์ ํ๋ ํจ์์ ๋๋ค.
function toggleSubmitButton() {
const { termsOfService, privacyPolicy } = agreements;
if (termsOfService && privacyPolicy) {
submitButton.disabled = false;
} else {
submitButton.disabled = true;
}
}
์์์ ์์ฑํ agreements Object์ 'ํ์ ๋์' ์์๋ค์ ๊ฐ์ ๊ฐ์ ธ์ ๋ณ์์ ๋ด์ต๋๋ค.
const { termsOfService, privacyPolicy } = agreements;
์ด 'ํ์ ๋์' ์ฒดํฌ ๋ฐ์ค๊ฐ ๋ ๋ค true(์ฒดํฌ) ์ด๋ฉด ๋ฒํผ์ disabled๋ฅผ false๋ก ๋ฐ๊พธ์ด ๋ฒํผ์ ํ์ฑํ์์ผ ์ค๋๋ค.
if (termsOfService && privacyPolicy) {
submitButton.disabled = false; // ๋ฒํผ ํ์ฑํ
} else {
submitButton.disabled = true; // ๋ฒํผ ๋นํ์ฑํ
}
'๋ชจ๋ ๋์' ์ฒดํฌ ๋ถ๋ถ์ ๋ํ ์ฝ๋๋ ์์ฑ์ด ๋ ๊ฒ์ ๋๋ค.
4. 3๊ฐ์ ์ฒดํฌ ๋ฐ์ค์ ๋ํ ์ด๋ฒคํธ
์ด์ ๋๋จธ์ง 3๊ฐ์ ์ฒดํฌ ๋ฐ์ค์ ๋ถ๋ถ์ ๋ด๋นํ๋ ์ฝ๋๋ฅผ ์ดํด๋ด ์๋ค.
checkBoxes.forEach((item) => item.addEventListener('input', toggleCheckbox));
function toggleCheckbox(e) {
const { checked, id } = e.target;
agreements[id] = checked;
this.parentNode.classList.toggle('active');
checkAllStatus();
toggleSubmitButton();
}
์ฒดํฌ ๋ฐ์ค์ input ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ๋๋ง๋ค toggledCheckbox(); ํจ์๋ฅผ ์คํํด ์ค๋๋ค.
checkBoxes.forEach((item) => item.addEventListener('input', toggleCheckbox));
์ฌ๊ธฐ์ input ์ด๋ฒคํธ๋ <input>, <select> ๋ฐ <textarea> ์์์ value ์์ฑ์ด ๋ฐ๋ ๋๋ง๋ค ๋ฐ์ํฉ๋๋ค.
input ์ด๋ฒคํธ์ ๋ ๊ถ๊ธํ๊ฑฐ๋, input ์ด๋ฒคํธ์ change ์ด๋ฒคํธ์ ๋ํ ์ฐจ์ด๊ฐ ๊ถ๊ธํ๋ฉด ์๋์ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
developer.mozilla.org/ko/docs/Web/API/HTMLElement/input_event
toggleCheckbox ํจ์๋ input ์ด๋ฒคํธ๊ฐ ๋ฐ์๋ ์์๋ฅผ ๋ฐ์์ id์ checked(์ฒดํฌ ์ํ) ๊ฐ์ ๋ณ์์ ๋ด๊ณ agreements Object์ id๊ฐ๊ณผ ๋์ผํ ๊ณณ์ checked ๊ฐ์ ๋ฃ์ด์ค ๋ค์์ checkAllStatus()๋ฅผ ์คํํ๊ณ toggleSubmitButton() ํจ์๋ฅผ ์คํํฉ๋๋ค.
function toggleCheckbox(e) {
const { checked, id } = e.target;
agreements[id] = checked;
this.parentNode.classList.toggle('active'); // ์ฌ๊ธฐ์ ์ค์ํ์ง ์์
checkAllStatus();
toggleSubmitButton();
}
checkAllStatus() ํจ์๋ 3๊ฐ์ ์ฒดํฌ๋ฐ์ค์ ์ํ๋ฅผ ํ์ธํด์ '๋ชจ๋ ๋์' ์ฒดํฌ ๋ฐ์ค์ ์ฒดํฌ ์ฌ๋ถ๋ฅผ ์ ํ๋ ํจ์์ ๋๋ค.
function checkAllStatus() {
const { termsOfService, privacyPolicy, allowPromotions } = agreements;
if (termsOfService && privacyPolicy && allowPromotions) {
checkAll.checked = true;
} else {
checkAll.checked = false;
}
}
agreements Object์ ์์๋ค์ ๋ณ์๋ก ๋ด๊ณ
const { termsOfService, privacyPolicy, allowPromotions } = agreements;
3๊ฐ์ ์ฒดํฌ ๋ฐ์ค๊ฐ ๋ชจ๋ ์ฒดํฌ ์ํ์ด๋ฉด '๋ชจ๋ ๋์' ์ฒดํฌ ๋ฐ์ค์ ์ฒดํฌ ์ํ๋ฅผ true(์ฒดํฌ)๋ก ํด์ฃผ๊ณ ํ๋๋ฉด false(์ฒดํฌ ํด์ )ํฉ๋๋ค.
if (termsOfService && privacyPolicy && allowPromotions) {
checkAll.checked = true;
} else {
checkAll.checked = false;
}
๊ทธ๋ฆฌ๊ณ , toggleSubmitButton(); ํจ์๋ฅผ ์คํํ๊ฒ ๋ฉ๋๋ค.
(์ด ํจ์์ ๋ํด์๋ ์์์ ์ค๋ช ํจ (๋ฒํผ ํ์ฑํ, ๋นํ์ฑํ ํจ์)
์ด๋ก์ ์ฝ๋๋ฅผ ์คํํด ํ์ธํด ๋ณด๋ฉด ์๊ฐํ ๋๋ก ์ ์๋ํ๋ ๊ฒ์ ๋ณผ ์ ์์ ๊ฒ์ ๋๋ค.
๐ ๋ง๋ฌด๋ฆฌ
+ ๋ง์ ๋ถ๋ค์ด ํ์๋ก ํ์๋ ๊ฒ ๊ฐ์์ ์ฝ๋ ์์ ๋ ์ฝ๋ ์๋๋ฐ์ค ๋งํฌ ์ฒจ๋ถํด ๋๋ฆฌ๊ฒ ์ต๋๋ค!
(ํ์ธ ๊ฒฐ๊ณผ ๋ฐ๋ก ์ ์ํด์ ํ์ธํ๋ฉด ์ ๋๋ก ์๋ํ์ง ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ๋งํฌ ๋ค์ด๊ฐ์ ์ ์๋๋ฐ์ค ๋ด์ ๋ธ๋ผ์ฐ์ ์์ ์๋ก๊ณ ์นจ ํ๋ฒ ํด์ฃผ์๋ฉด ์ ์ ์๋ ํ ๊ฒ๋๋ค.)
codesandbox.io/s/agreement-l5uc6
์ ์ฒด์ ์ธ ์ฝ๋๋ฅผ ๋ณด์ฌ์ค ํ, ์ฝ๋์ ๋์ ์๋ฆฌ, ์์, ๋ก์ง์ ๋ํด์ ์ค๋ช ์ ํ๋ฉด์ Vanilla ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์ด์ฉํด์ ์์ฑํ ํ์๊ฐ์ , ์ฝ๊ด ๋์ ์์ ์ ์ฝ๋์ ๋ํ ์ ๋ฆฌ๋ ๋๋ฌ์ต๋๋ค.
(๋ณธ ๊ธ์ ์ ํ๋ฒ '๊น๋ฒ๊ทธ' ๋์ ์์ ๋ฅผ ํ์ฉ, ์ฐธ๊ณ ํ์์ต๋๋ค.)