-
[js] event? event.stoppropagation?front-end/javascript 2021. 10. 18. 20:28728x90
event.preventDefault? event.stoppropagation? 자바스크트립에서 이벤트 바인딩 시에 많이 보이던 함수였다.
저 둘을 이전부터 많이 사용되었고, 앞으로도 많이 사용될 거라 생각되어. 나중에 시간 되면 분석해보기로 했었던 찰나.
오늘 개발하면서 저 둘의 개념을 혼동하여, 30분 동안이나 삽질을 했다. 이참에 다시 정리해보기로 했다.
event?
먼저 event가 뭘까? 모든 동작은 event를 받아서 동작한다고 생각하면된다. 이벤트에도 종류가 있는데 tag별로 이벤트가 다르다. form event, click event, 특정 이벤트가 발생하면, 이벤트를 구독(참조)하여 동작을 지시하는 방식으로 되어있다.
쉽게 말해서 발생한 이벤트를 코드에 알려줘서, 동작하는 것을 이벤트라고한다. https://developer.mozilla.org/ko/docs/Web/Events
쉽게 클릭이벤트를 발생시켜보는 script를 만들어보자.
const btn = document.createElement('button'); btn.innerHTML = 'CLICK' btn.addEventListener( 'click', () => { console.log('click'); }) document.body.append(btn);
간단하게 클릭이벤트를 참조하여 클릭이벤트를 발생해 보았다. 여기서 궁금증이 있다. 앞서 설명했듯이 이벤트의 종류가 무수히 많은데 어떤 이벤트인지 알 수 있는가?이다. 그렇다 알 수 있다. 참조하는 함수의 매개변수로 전달되게 된다. 설명보다는 직접 보자.
const btn = document.createElement('button'); btn.innerHTML = 'CLICK' btn.addEventListener( 'click', (e) => { console.log(e); console.log('click'); }) document.body.append(btn);
첫 번째 매개변수로 전달받은 값에 우리가 발생한 이벤트 정보를 담고 있다. Pointer에서 발생한 이벤트이니 PointerEvent라는 점을 쉽게 유추할 수 있다.
만약에 버튼 안에 버튼이 있다면??? 어떻게 동작할까?? 직접 만들어보았다.
const btn = document.createElement('button'); const btn2 = document.createElement('button'); const btn3 = document.createElement('button'); btn.innerHTML = 'CLICK' btn.addEventListener( 'click', (e) => { console.log('click'); }) btn2.innerHTML = 'CLICK' btn2.addEventListener( 'click', (e) => { console.log('click1'); }) btn3.innerHTML = 'CLICK' btn3.addEventListener( 'click', (e) => { console.log('click2'); }) btn2.append(btn3); btn.append(btn2); document.body.append(btn);
btn1부터 ~ btn3까지 클릭해보자. 어떤 결과가 나올지 예측해보자
btn1을 클릭하면 click이 나올 것이고
btn2을 클릭하면 click2가 나올 것이고
btn3을 클릭하면 click3가 나올 것이다
그러나 직접 실행해보면 다음과 같은 결과가 나온다.
어랏 왜 그럴까?? 이걸 전문용어로 이벤트 버블링이라고 한다. 거의 모든 이벤트는 버블링 된다고 한다.
focus 이벤트는 버블링 되지 않는 이벤트 중 하나이다. 몇몇 이벤트를 제외하곤 이벤트는 버블링 된다.
event.stopPropagation???
이벤트 버블링이 먼지는 알았다. 여기서 문제가 있다. 우리는 click2를 클릭했는데. 위 버튼도 클릭한다고 컴퓨터는 인식한다. 이문제를 해결하기 위해 제공하는 함수가 stoppropagation이다. 즉 상위 이벤트가 발생하지 않도록 막는 역할이라고 생각하면 된다.
const btn = document.createElement('button'); const btn2 = document.createElement('button'); const btn3 = document.createElement('button'); btn.innerHTML = 'CLICK' btn.addEventListener( 'click', (e) => { console.log('click'); }) btn2.innerHTML = 'CLICK' btn2.addEventListener( 'click', (e) => { e.stopPropagation(); console.log('click2'); }) btn3.innerHTML = 'CLICK' btn3.addEventListener( 'click', (e) => { e.stopPropagation(); console.log('click3'); }) btn2.append(btn3); btn.append(btn2); document.body.append(btn);
최상단에 있는 btn3을 클릭 시 click3만 나오는 모습을 확인할 수 있다.
정리 및 느낀점
- 겹쳐있는 버튼을 작업하다. 몇 분째 삽질만 계속되었다. 그 이유는 stopPropagation에 정확한 용도를 모르고 있었기 때문이었다.
- 전에 생각 없이 남발했었던 나 자신이 보여서 안타까웠지만, 이번 시간에 다시 한번 stopPropagation에 대해 정확하게 이해했고, preventEventDefault()와의 차이점도 분명히 이해 할 수 있는 시간이었다.
728x90'front-end > javascript' 카테고리의 다른 글
[JS] 자바스크립트 클래스 추가/삭제 (0) 2021.08.31 [javascript] key event 이해하기 (0) 2020.03.18