본문 바로가기
JavaScript

javascript] 이벤트 작성 시 유의점.

by 완기 2021. 2. 18.
728x90
반응형

자바스크립트에는 클릭했을 때, 이벤트, 마우스를 눌렀을 때, 마우스가 해당 영역을 떠났을 때 등, 

다양한 이벤트 요소로 다이내믹한 웹을 구현하여 사용자와 상호작용을 한다. 

 

사용자의 경험이 증가함에 따라, 매 이벤트마다 페이지를 새로고침 하지 않고,

한 페이지 내에서 사용자와 상호 작용하는 비동기식 이벤트 처리가 유행이 되어갔다. 

(서버도 문서 전체를 다시 응답을 줄 필요가 없어서 상대적으로 리소스가 절약)

 

때문에 SPA와 관련된 FE 프레임워크인 vue나 react 같은 플랫폼들이 인기가 많아진 것이다.

 

여하튼 본론으로 들어가면, 회사 업무를 진행하던 도중,

Vanila JS로 동적으로 Element들이 추가/삭제가 되는 웹 페이지를 작성할 필요가 있었다.

 

이 과정을 진행하면서 클릭 이벤트를 걸어 놓으면 동적으로 추가된 엘리먼트는 해당 이벤트가 동작하지 않는 문제가 발생했다.

 

이 문제의 원인은 DOM객체가 모두 생성된 이후 생성된 Element로 이벤트는 그전에 생성되어있던 DOM 객체에만 적용이 되던 것이었다.

 

이 문제는업무 시간 관계상 빠르게 처리해야 했기 때문에 불가피하게 JQuery를 사용했지만 확실히 JQuery는 속성들이 많아질수록, 속도가 굉장히 느려짐을 느꼈다.

 

어쨌든! 이런 문제가 발생하는 경우에 대한 해결 방법을 알아보자.


1.Jquery의 on() 사용.

JQuery의 on 메서드를 사용해서 이벤트 항목을 인자로 넣어주면 제이쿼리가 웹 페이지 내에 셀렉터로 지정된 속성에 이벤트를 부여한다.

그 셀렉터가 설령 동적으로 append 된 Element라고 해도 이벤트를 바인딩하고 있어서,

선택자만 잘 선택하면 페이지 새로 고침 없이 모든 속성에 걱정 없이 사용이 가능했다.

 

예:)

var gen=document.getElementById('GenerateDiv') // 버튼을 동적으로 생성하는 버튼

gen.onclick=function (){
	var newButton=document.createElement('div');
	newButton.innerText='새로 생성된 div';
	document.body.appendChild(newButton);
	console.log('new gen');
}

document.queryselectorAll('div').onclick=function(){
	alert('clicked')
}

예를 들어 위와 같은 코드가 있다고 치면, 위 코드는 generateDiv라는 선택자를 클릭하면 div 태그를 동적으로 생성한다.

 

그리고 문서 내 div 를 클릭하면 알림 창을 띄우는데, 위 코드는 새로 생성된 항목에는 동작하지 않는다.

 

이유인즉슨, 위에 작성했던 DOM의 생성 시기 때문에 그렇다.

위에 작성한 자바스크립트는 미리 element로 정의된 DOM만 작동하기 때문에 JQuery를 사용하면 

이러한 문제를 해결할 수 있다.

 

$('div').on('click',function(){
	alert('clicked');
});

이런 식으로 작성하게 되면 추후에 생성되는 모든 div태그에도 이벤트를 바인딩하기 때문에 동적으로 추가된 요소에도 이벤트가 동작한다.

 

그러나 이 방법 또한 문제가 있는데,

위와 같이 사용하면 의도한 대로 작성은 잘 되는 것 같지만, 실제로 돌려보면 alert가 여러 번 뜬다.

 

그 이유는 무엇일까? 

바로 이벤트 버블링 때문이다.

 

이벤트 버블링은 특정 화면 요소에서 이벤트가 발생했을 때 해당 이벤트가 더 상위의 화면 요소들로 전달되어 가는 특성을 의미한다.

 

html은 수 많은 요소들이 있고, 하위 요소에 이벤트를 바인딩하면

해당 이벤트가 부모 요소들로 이벤트를 전달해 여러 번 실행되는 문제가 있다.

 

$(selector).off('click').on('click',function(){
	doSomeThing();
})

Jquery에선 위와 같은 문제를 해결할 수 있다.

 


2.event delegate 

event delegate란 이벤트 위임이란 의미다. 

 

<ul>
	<div>1</div>
	<div>2</div>
	<div>3</div>
	<div>4</div>
	<div>5</div>
</ul>

이런 태그가 있다고 가정하고 어떤 버튼을 클릭하면 div 엘리먼트를 ul의 자식으로 추가하고 클릭 시 alert를 띄운다고 하면,

 

5번 div까지만 클릭 이벤트가 작동한다. 

 

이유는 서론에 언급한 이유와 같다.

 

event delegate는 위임이란 말 그대로 div에 클릭 이벤트를 바인딩하는것이 아니고, 부모 엘리먼트인 ul에 클릭 이벤트를 위임하는 것이다.

 

이렇게 되면 div는 어차피 ul의 자식 노드로 동적으로 추가되기 때문에 동적으로 추가되는 div를 클릭하는 것이 이벤트가 바인딩된 ul을 클릭하는 것이기 때문에, 이벤트는 동작한다.

 

이 처럼, 부모 요소에게 이벤트를 바인딩하는 것을 event delegate라고 한다.

 

이런 방법으로 무거운 jquery를 사용하지 않고 동적인 이벤트를 바인딩할 수 있다.

728x90
728x90

댓글