대가는 결과를 만든다

js event listener 내에서 많이 사용하는 객체 정리 & 이벤트 위임 본문

개발/Javascript

js event listener 내에서 많이 사용하는 객체 정리 & 이벤트 위임

yunzema 2020. 6. 15. 20:17
반응형

이벤트 정의 함수 내에서 자주 쓰게되는 객체들 간단히 정리해본다.

ELEMENT.addEventListener('click', function (e){
    console.log(this);		        //event listener를 추가하는 dom element 객체
    console.log(e.currentTarget);	//위의 this와 동일
    console.log(e.target);		//클릭한 dom element 객체
    console.log(this.parentNode);	//클릭한 dom element의 부모 객체
})

 

이어서 많이 사용하는 addEventListener의 이벤트 위임에 대해 정리한다.

- addEventListener를 dom에 많이 부여할 수록 메모리를 차지하므로 페이지 성능에 영향을 줄 수 있다.

- 이를 개선하기 위해 최대한 부모 dom에 addEventListener를 부여해서 동일한 기능을 구현 할 수 있는데 이것을 이벤트 위임이라 한다.

 

아래와 같은 element가 있다고 가정했을 때, 

<div class="menu">
    <button class="menu-btn">1번 메뉴</button>
    <button class="menu-btn">2번 메뉴</button>
    <button class="menu-btn">3번 메뉴</button>
</div>

버튼에 각각 이벤트 함수를 붙인다면 아래와 같이 할 것이다.

const buttons = document.querySelectorAll('.menu-btn');
buttons.forEach(button => {
    button.addEventListener('click', ()=>{
    	//... do something
    }, false);
});

하지만, 이벤트 위임으로 처리한다면 아래와 같이 한번의 이벤트 함수 추가로만 처리할 수 있다.

// 이벤트 위임
const menu = document.querySelector('.menu');

function clickHandler(e) {
	
    //e.currentTarget은 this와 동일
    //e.target은 클릭한 대상 dom
	if (e.target.classList.contains('menu-btn')) {
		//...do something
	}
}

menu.addEventListener('click', clickHandler);

 

예를 들어 상품 목록이 있고, 스크롤하면 그 다음 항목들이 계속 추가 되는 형태의 페이징이 구현되있다고 치자.

동적으로 계속 추가되는 항목들에 이벤트 리스너를 계속 추가하는 것보다 위와 같이 이벤트 위임으로 처리하면 목록을 감싸는 부모 element 하나에만 이벤트 리스너를 추가해서 구현할 수 있다. 

 

+ 추가

만약에 아래처럼 클릭 이벤트 함수를 추가할 element의 하위에 다른 element들도 있는 경우

<div class="menu">
    <button class="menu-btn">
    	<img class="icon" src="/a.png"/>
        <span class="btn-label">1번 메뉴</span>
    </button>
    <button class="menu-btn">
    	<img class="icon" src="/b.png"/>
        <span class="btn-label">2번 메뉴</span>
    </button>
    <button class="menu-btn">
    	<img class="icon" src="/c.png"/>
        <span class="btn-label">3번 메뉴</span>
    </button>
</div>

1. css를 이용해 이벤트를 막을 수 있다.

.icon{
	pointer-events: none;
}

.btn-label{
	pointer-events: none;
}

2. 아래와 같이 스크립트로 구현 할 수 있다.

// 이벤트 위임
const menu = document.querySelector('.menu');

function clickHandler(e) {
	
    let elem = e.target;
    
	while (!elem.classList.contains('menu-btn')) {
    		elem = elem.parentNode;
        
        	if(elem.nodeName ==='BODY'){
        		elem = null;
            		return;
        	}
	}
    
	//...do something

}

menu.addEventListener('click', clickHandler);
Comments