버튼을 클릭 했을 때 드롭다운 메뉴가 나타나게 하는 것까지는 했다고 치자.
여기서 메뉴를 클릭하지 않고 다른 곳을 클릭 했을 때 드롭다운 메뉴가 사라지는 방법에 대해 다루겠다.
알고 보면 별 것 아닌데 모르면 어렵게 구현해야 한다.
1. HTML
<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 이벤트가 발생한다.
2. Javascript
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)
button 선택이 해제될 때(blur) display를 원상태로 돌린다.
CSS에서 display의 값을 none으로 했기 때문에 빈 string을 넣어주면 원래 상태로 돌아간다.
다만 다른 곳을 클릭할 때 뿐만 아니라
드롭다운 내부의 아이템을 클릭하는 경우에도 blur 이벤트가 발생하기 때문에
클릭시 blur 이벤트가 먼저 발생하고 드롭다운이 사라져 아이템 클릭 이벤트가 먹히지 않을 수 있으니
아래처럼 setTimeout을 추가해서 드롭다운이 사라지는 시간을 살짝 지연시키든지 하는 작업이 더 필요하다.
button.addEventListener('blur', () => {
const dropdown = document.querySelector('.dropdown');
// 0.2초 뒤에 실행
setTimeout(() => {
dropdown.style.display = '';
}, 200);
});
더 간단한 방법으로 드롭다운의 아이템 클릭시 발생하는 이벤트에 click 이벤트 대신 mousedown 이벤트를 쓰면
blur 이벤트 이전에 호출되기 때문에 위 문제를 쉽게 해결할 수 있다.
3. CSS
body {
display: flex;
justify-content: center;
align-items: center;
margin: 0;
height: 100vh;
}
.button-container {
position: relative;
}
.button {
display: flex;
align-items: center;
background: white;
border: 1px solid grey;
padding: 10px;
font-size: 1rem;
cursor: pointer;
outline: none;
}
.dropdown {
display: none;
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
width: 100px;
border: 1px solid grey;
}
.dropdown-item {
text-align: center;
padding: 10px;
cursor: pointer;
}
.dropdown-item:hover {
background: whitesmoke;
}
body는 가운데 정렬을 위한 설정이고
부모인 button-container의 position을 relative로 하고 자식인 dropdown을 absolute로 해야
부모 위치를 기준으로 dropdown의 위치를 조절 할 수 있다.
여기서는 top에 100%를 줘서 부모의 height 만큼 내려오게 하여
button 바로 밑에 dropdown이 붙도록 했다.
left에 50%를 주면 왼쪽 모서리가 부모의 중간 지점에 오고
transform에 translateX(-50%)를 주면 자신의 width 반절만큼 왼쪽으로 움직인다.
결과적으로 아래처럼 부모를 기준으로 가운데 정렬이 된다.
'자바스크립트 > DOM 예제' 카테고리의 다른 글
버튼 클릭시 클립보드에 복사하는 방법 (0) | 2021.05.01 |
---|---|
자바스크립트 div 엘리먼트를 스크린샷해서 이미지 파일로 만들기 (0) | 2020.03.12 |
자바스크립트 그림 그리기 - canvas (0) | 2020.03.08 |
마우스를 올려 놓을 때 이벤트 발생 예제 (0) | 2020.02.27 |