Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

이벤트 위임에 대한 고찰 #61

Open
samslow opened this issue Jul 22, 2020 · 2 comments
Open

이벤트 위임에 대한 고찰 #61

samslow opened this issue Jul 22, 2020 · 2 comments
Assignees
Labels
Answered 답변이 완료된 상태

Comments

@samslow
Copy link
Member

samslow commented Jul 22, 2020

@snowjang24 가 07월 22일 스터디에서 이벤트 위임은 이벤트 캡처링의 일부가 아닌가?라는 질문에 대한 답변입니다.

( 혹시 질문이 틀렸다면, 정정 해 주세요.)

먼저 답변은 이벤트 위임은 하위 요소에 각각 이벤트를 붙이지 않고 상위 요소에서 하위 요소의 이벤트를 제어하는 방식 이라고 정의 할 수 있습니다.

<h1>오늘의 할 일</h1>
<ul class="itemList">
	<li>
		<input type="checkbox" id="item1">
		<label for="item1">이벤트 버블링 학습</label>
	</li>
	<li>
		<input type="checkbox" id="item2">
		<label for="item2">이벤트 캡쳐 학습</label>
	</li>
</ul>
<script>
var inputs = document.querySelectorAll('input');
inputs.forEach(function(input) {
	input.addEventListener('click', function(event) {
		alert('clicked');
	});
});
</script>

위 방식대로라면 ul 안에 li 들은 모두 클릭시에 clicked 라는 alert이 뜨게 됩니다.

var itemList = document.querySelector('.itemList');

var li = document.createElement('li');
var input = document.createElement('input');
var label = document.createElement('label');
var labelText = document.createTextNode('이벤트 위임 학습');

input.setAttribute('type', 'checkbox');
input.setAttribute('id', 'item3');
label.setAttribute('for', 'item3');
label.appendChild(labelText);
li.appendChild(input);
li.appendChild(label);
itemList.appendChild(li);

하지만, 만약 위 코드처럼 동적으로 li가 증가한다면, script 태그의 내용이 모든 inputs을 잡지는 못 하겠죠.

이때 필요한 것이 ul에 모든 이벤트 발생을 위임하여 동적 생성에도 대응 할 수 있도록 하는 것입니다.

즉, li에서 발생하는 이벤트 버블링을 부모 객체가 캐치 할 수 있도록 하는 것입니다.

물론 li에다 일일히 이벤트를 달아주는 방법도 있겠지만, 이보다는 이벤트 위임이 코드 가독성과 성능 면에서 유용합니다.

var itemList = document.querySelector('.itemList');
itemList.addEventListener('click', function(event) {
	alert('clicked');
});

이렇게 말입니다!

추가 질문이 있으실 것 같은데, 여기에 더 달아주세요.

@samslow samslow added the Answered 답변이 완료된 상태 label Aug 9, 2020
@samslow samslow self-assigned this Aug 9, 2020
@gmlwo530
Copy link

안녕하세요. 좋은 글 작성 해주셔서 감사합니다.

한 가지 논의하고 싶은게 댓글 남겨요.

이벤트를 부모에게 위임하게 되면

자식의 이벤트가 일어나는 동시에 자식의 이벤트가 부모로 버블링 되어 부모도 클릭 이벤트가 발생하게 됩니다.

즉, 위의 예제에서 자식들에게 특정 처리를 해주지 않으면 li 또는 input 태그를 클릭 하면 alert가 2번 실행 됩니다.

같은 코드가 2번 실행 되는 것을 성능이 유용하다고 할 수 있는지 궁금합니다!!

오타 발견 : 즉, li에서 발생하는 이벤트 버블링을 부목부모 객체가 캐치 할 수 있도록 하는 것입니다.

@samslow
Copy link
Member Author

samslow commented Aug 19, 2020

@gmlwo530 안녕하세요. 좋은 질문 감사드립니다.
위 예제에서 모든 내용을 그대로 치시되 제일 위에 있던 Inputs관련 코드는 빼는게 원래 의도한 코드긴 합니다.

// 아래 코드는 빼야합니다.
var inputs = document.querySelectorAll('input'); 
inputs.forEach(function(input) {
	input.addEventListener('click', function(event) {
		alert('clicked');
	});
});

얘기 해 주신 것처럼 같은 코드가 2번 실행되는거라 성능은 당연히 조금은 더 안좋겠죠 ?
아 그리고 alert가 2번 실행되는 또다른 이유는 li내부 태그가 Input이어서 이벤트를 한번 더 전달해서 그렇습니다.
참고할만한 CodeSandbox 첨부합니다.

오타 제보 감사합니다 ㅋㅋ

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Answered 답변이 완료된 상태
Projects
None yet
Development

No branches or pull requests

2 participants