
회원가입 페이지에서 쉽게 볼 수 있는 약관동의 기능을 자바스크립트로 구현해 보았다.
모든 체크박스를 통제하는 최상단 체크박스와 세부 항목 체크박스 안에 또 다른 체크박스 리스트를 만들었고, foreEach문과 Array.from을 사용해 기능을 구현했다.

label과 input태그를 사용해 체크박스 요소를 만들어 주었다. 이때 전체 동의 기능을 하는 체크박스에는 ‘select-all’ , ‘select-all-mkt’ 클래스를 나머지 세부 항목에 해당하는 체크박스에는 checkbox 클래스를 주어 자바스크립트에서 구별해 사용할 수 있도록 했다.
<div class="agreement-form">
<p class="title">약관동의</p>
<div class="all-check">
<label class="checkbox">
<input type="checkbox" class="select-all">
<span class="txt">모든 약관을 확인하고 전체 동의합니다.</span>
</label>
</div>
<ul class="list">
<li class="item">
<label class="checkbox">
<input type="checkbox">
<span class="txt">[필수] 이용약관 동의</span>
</label>
<button type="button" class="btn small outline2 thin">내용보기</button>
</li>
<li class="item">
<label class="checkbox">
<input type="checkbox">
<span class="txt">[필수] 개인정보 수집 및 이용 동의</span>
</label>
<button type="button" class="btn small outline2 thin">내용보기</button>
</li>
<li class="item inner">
<label class="checkbox">
<input type="checkbox">
<span class="txt">[선택] 개인정보 자사 마케팅 수집 및 이용 동의</span>
</label>
<div class="info-box">
<ul>
<li>- 수집/이용 목적: 자사 마케팅을 위한 개인정보 이용</li>
<li>- 수집항목: 구매자 정보, 상품 구매/취소/반품/교환/환불 정보, 수령인 정보</li>
<li>- 보유/이용기간: 회원 탈퇴 후 5일까지</li>
</ul>
<p class="notice">※ 개인정보 제공에 대한 동의를 거부할 권리가 있으며, 동의를 거부할 경우 마케팅 정보를 받을 수 없습니다.</p>
</div>
</li>
<li class="item inner">
<label class="checkbox">
<input type="checkbox" class="select-all-mkt">
<span class="txt">[선택] 마케팅 정보 수신 동의</span>
</label>
<div class="info-box">
<ul class="marketing-list">
<li>
<label class="checkbox">
<input type="checkbox">
<span class="txt">이메일</span>
</label>
</li>
<li>
<label class="checkbox">
<input type="checkbox">
<span class="txt">SMS</span>
</label>
</li>
<li>
<label class="checkbox">
<input type="checkbox">
<span class="txt">전화(상담)</span>
</label>
</li>
</ul>
<p class="notice">※ 마케팅 정보 수신동의를 하시면 스키니랩에서 제공하는 쇼핑/혜택 및이벤트 소식을 받을 수 있습니다.</p>
</div>
</li>
</ul>
</div>
최상단 요소인 agreement-form을 querySelector로 불러오고 아래 나머지 요소들은 이 agreement-form에서 불러오도록 했다.
전체 동의 체크박스 가 change 되었을 때 forEach문을 사용해 모든 세부항목 체크박스가 전체동의 체크박스의 상태와(checked) 같아지도록 했다.
이때 중복으로 구현되는 부분은 따로 함수로 빼주어 좀 더 효율적인 코드를 작성해 보았다.
Array.from 함수를 사용해 유사 배열 객체(반복 가능한 객체)를 얕게 복사해 새로운 Array 객체를 만들어 주었고 이 객체에 every 함수를 사용해 각 각의 체크박스를 모두 눌렀을때 전체 동의 체크박스가 체크 되어지도록 혰다
3번과 유사한 방법으로 some 함수를 사용해 선택 항목에는 하나라도 체크시 선택 항목 체크박스가 체크되어 지도록 했다.
💡 Array.from() - 배열이나 객체를 복사해 새로운 Array 로 만들어 주는 메서드
every() - 배열 안의 모든 요소가 주어진 판별 함수를 통과하는지 테스트
some() - 배열 안의 어떤 요소라도 주어진 판별 함수를 적어도 하나라도 통과하는지 테스트
const $agreementForm = document.querySelector('.agreement-form');
const $selectAll = $agreementForm.querySelector('.select-all');
const $listInput = $agreementForm.querySelectorAll('.list input');
const $selectAllMkt = $agreementForm.querySelector('.select-all-mkt');
const $mktListInput = $agreementForm.querySelectorAll('.marketing-list input');
const toggleCheckbox = (allBox, itemBox) => {
allBox.addEventListener('change', () => {
itemBox.forEach((item) => {
item.checked = allBox.checked;
});
})
}
toggleCheckbox($selectAll, $listInput);
toggleCheckbox($selectAllMkt, $mktListInput);
$listInput.forEach((item) => {
item.addEventListener('change', () => {
const isChecked = Array.from($listInput).every(i => i.checked);
$selectAll.checked = isChecked;
});
});
$mktListInput.forEach((item) => {
item.addEventListener('change', () => {
const isChecked = Array.from($mktListInput).some(i => i.checked);
$selectAllMkt.checked = isChecked;
});
});