<div class="button-container">
<button class="button">클릭</button>
<div class="dropdown">
<div class="dropdown-item">서울</div>
<div class="dropdown-item">대전</div>
<div class="dropdown-item">대구</div>
<div class="dropdown-item">부산</div>
</div>
</div>
반드시 button 엘리먼트를 써서 이벤트를 구현해야 한다. input류의 엘리먼트만 blur 이벤트가 적용되기 때문이다.
(일반 엘리먼트에 blur 이벤트를 넣고 싶다면 tabindex 속성을 활용하자.)
https://developer.mozilla.org/ko/docs/Web/HTML/Global_attributes/tabindex
blur 이벤트는 선택이 해제됐을 때 발생하는 이벤트다. 버튼을 클릭했을 때 버튼을 선택한 상태가 되고 (focus) 버튼이 아닌 다른 곳을 클릭하면 선택 상태가 해제되어 button에 blur 이벤트가 발생한다.
const button = document.querySelector('.button');
button.addEventListener('click', () => {
const dropdown = document.querySelector('.dropdown');
dropdown.style.display = 'block';
});
button.addEventListener('blur', () => {
const dropdown = document.querySelector('.dropdown');
dropdown.style.display = '';
});
button을 클릭했을 때 dropdown의 display를 보여주고(block) utton 선택이 해제될 때(blur) display를 원상태로 돌린다.
CSS에서 display의 값을 none으로 했기 때문에 빈 string을 넣어주면 원래 상태로 돌아간다.
다만 다른 곳을 클릭할 때 뿐만 아니라 드롭다운 내부의 아이템을 클릭하는 경우에도 blur 이벤트가 발생하기 때문에 클릭시 blur 이벤트가 먼저 발생하고 드롭다운이 사라져 아이템 클릭 이벤트가 먹히지 않을 수 있으니 아래처럼 etTimeout
추가해서 드롭다운이 사라지는 시간을 살짝 지연시키든지 하는 작업이 더 필요하다.
button.addEventListener('blur', () => {
const dropdown = document.querySelector('.dropdown');
// 0.2초 뒤에 실행
setTimeout(() => {
dropdown.style.display = '';
}, 200);
});
더 간단한 방법으로 드롭다운의 아이템 클릭시 발생하는 이벤트에 click 이벤트 대신 mousedown 이벤트를 쓰면 blur 이벤트 이전에 호출되기 때문에 위 문제를 쉽게 해결할 수 있다.