자바스크립트 addEventListener 중복 방지
addEventListener 함수는 DOM요소에 이벤트가 일어났을 때 콜백함수를 실행하게 해준다.
let button = document.querySelector('button');
button.addEventListener('click', ()=>{
console.log('버튼 클릭했음')
})
addEventListener의 첫번째 인자는 이벤트의 종류를 의미하고, 두번째 인자에는 콜백함수가 들어간다.
위 코드의 경우 'click' 이벤트 발생시, 뒤에 있는 익명 화살표함수를 실행하라는 뜻이다.
근데 코딩을 하다보면 하나의 DOM 요소에 이벤트리스너가 중첩되는 경우가 종종 생긴다.
<ul>
<li>List 1</li>
<li>List 2</li>
<li>List 3</li>
<li>List 4</li>
<li>List 5</li>
</ul>
<br>
<button>버튼</button>
<script>
let button = document.querySelector('button');
let list_item = document.querySelectorAll('ul>li');
list_item.forEach((el) => {
el.addEventListener('click', () => {
button.addEventListener('click', () => {
console.log('버튼 클릭함!');
})
})
})
</script>
예시로 위와 같은 페이지가 있다고 치자.
각 li 를 클릭하기 전에는 버튼을 눌러도 아무 액션이 일어나지 않지만,
li를 클릭하면 버튼에 이벤트리스너가 추가된다.
근데 리스트를 여러번 클릭하면 할수록 버튼에 이벤트리스너가 중첩된다.
이와 같은 일을 방지하려면 버튼에 고유한 프로퍼티를 추가하여 해당 프로퍼티를 이벤트리스너로 등록하는 방법이 있다.
(말만 들으면 뭔가 복잡해 보이지만 코드보면 매우 간단하다...내가 설명을 못해서 그렇다...)
let button = document.querySelector('button');
let list_item = document.querySelectorAll('ul>li');
list_item.forEach((el) => {
el.addEventListener('click', () => {
if(button.clickHandler){
//버튼에 clickHandler 라는 속성이 있다면?
button.removeEventListener('click', button.clickHandler);
//이벤트리스너에 추가된 clickHandler 제거
}
button.clickHandler = () =>{
//clickHandler라는 속성은 이런 함수입니다.
console.log('버튼 클릭함!');
}
button.addEventListener('click', button.clickHandler);
//clickHandler 속성을 이벤트리스너로 추가합니다.
})
})
1. 리스트 클릭 시 button에 clickHandler 라는 프로퍼티를 추가한다.
2. button에 clickHandler 라는 프로퍼티가 있을 경우 (그럼 clickHandler가 이벤트리스너로도 등록 되어있는 상태)
3. button에 추가되어있는 이벤트리스너를 removeEventListener 로 제거한다.
4. 다시 clickHandler를 정의한다.
5. clickHandler를 button에 addEventListener로 추가한다.
이런식으로 이벤트리스너를 추가하면 중첩될 일 없이 안전하게 관리할 수 있다.