드롭박스를 만들면서, 꼭 옵션중 하나가 클릭되었을 때 만이 아니라 그냥 바깥공백을 클릭했을 때에도 저 드롭박스가 사라지게 하고싶었다.
그래서 드롭다운 버튼에 blur이벤트를 걸어 버튼이 포커스를 잃을 때에도 드롭박스가 사라지게 코드를 작성했다.
<script>
const btnToggle = document.querySelector('.btn-select');
const list = document.querySelector('.list-member');
const options = document.querySelectorAll('.dropdown-option');
btnToggle.addEventListener('click', function () {
list.classList.toggle('show');
});
btnToggle.addEventListener('blur', function () {
list.classList.remove('show');
});
options.forEach(function (item) {
item.addEventListener('click', function (e) {
const value = e.currentTarget.textContent;
btnToggle.textContent = value;
});
});
</script>
문제
저 드롭박스 안에 각각의 옵션들은 click이벤트가 발생했을 때 그 안에있는 text가 버튼 안에 들어가도록 해놨는데, blur이벤트를 추가한 뒤로는 그게 적용이 되지 않았다.
원인
이벤트가 일어날 때에는 아래의 순서를 가진다.
- mousedown
- blur
- mouseup
- click
사실 블러를 빼고 생각하면,
마우스가 눌러지는 순간(mousedown)이 그 어떤 이벤트보다 먼저 일어나고,
눌렸다 떼지는 순간(mouseup)이 일어난 뒤에
이 두개를 마무리한 모습이 클릭(click)이라고 여기는 것은 어찌보면 당연하다.
결론은 내가 원하는 click 이벤트가 먼저 일어나 버튼의 텍스트가 바뀌고 -> blur 이벤트가 일어나 드롭박스가 사라지는 것은 이벤트 순서상 맞지 않는 것이었다.
해결방법
click 대신 mousedown을 사용하면 blur보다 먼저 일어나게 되므로 내가 원하는대로 작동한다.
<script>
const btnToggle = document.querySelector('.btn-select');
const list = document.querySelector('.list-member');
const options = document.querySelectorAll('.dropdown-option');
btnToggle.addEventListener('click', function () {
list.classList.toggle('show');
});
btnToggle.addEventListener('blur', function () {
list.classList.remove('show');
});
options.forEach(function (item) {
item.addEventListener('mousedown', function (e) {
const value = e.currentTarget.textContent;
btnToggle.textContent = value;
});
});
</script>
참고한 스택오버플로우
'Front-End Developer > JavaScript' 카테고리의 다른 글
(DOM)click이벤트로 HTML요소 텍스트와 CSS스타일 변경하기 (0) | 2022.05.16 |
---|---|
하드코드->forEach->이벤트 위임 [점점 나아지는 코드 맛보기] (0) | 2022.05.14 |
DOM이란 무엇인가 (0) | 2022.05.13 |
JS 이벤트 플로우 완벽이해 (0) | 2022.05.13 |
증감 연산자(Increment & Decrement Operators) (0) | 2022.05.11 |