์ด๋ฒคํธ ๋ฒ๋ธ๋ง
๊ธฐ๋ณธ์ ์ธ ์ด๋ฒคํธ ์บก์ณ๋ง, ๋ฒ๋ธ๋ง์ ๋ํด์ ์ ๋ฆฌ ํด๋ณด์์ต๋๋ค.
Apr 27, 2021
UX TECH TF ์ ๋ฌด์์ DOM๊ณผ ์ด๋ฒคํธ๋ฅผ ๋ค๋ฃจ๋ ์ผ์ด ๋ง์๋ฐ์, ์ด๋ฒคํธ ๋ฒ๋ธ๋ง, ์บก์ณ๋ง ๊ณต๋ถํ ํ ์ ๋ฆฌํ ๋ด์ฉ์ ๊ณต์ ๋๋ฆฌ๊ณ ์ ํฉ๋๋ค.
๋ฒ๋ธ๋ง
Element1 ์์์์ Element2๊ฐ ์๊ณ ๋ ์์์๋ ๋ชจ๋ ํด๋ฆญ ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ์์ต๋๋ค.
์ฌ์ฉ์๊ฐ Element2๋ฅผ ํด๋ฆญํ๋ฉด Element1, Element2 ๋๊ตฐ๋ฐ ๋ชจ๋์์ ์ด๋ฒคํธ๊ฐ ์คํ ๋ฉ๋๋ค.
์ด๋ค ์ด๋ฒคํธ๊ฐ ๋จผ์ ์คํ ๋ ๊น์?
jsfiddle์์ ํ์ธ ํด์ฃผ์ธ์!
์ด๋ฒคํธ ์ ๋ฌ ๋ฐ ํ๋ฆ
ํ์ค DOM ์ด๋ฒคํธ์์ ์ ์ํ ์ด๋ฒคํธ ํ๋ฆ์๋ 3๊ฐ์ง ๋จ๊ณ๊ฐ ์์ต๋๋ค.
- ์บก์ณ๋ง ๋จ๊ณ: ์ด๋ฒคํธ๊ฐ ํ์ ์์๋ก ์ ํ๋๋ ๋จ๊ณ
- ํ๊น ๋จ๊ณ: ์ด๋ฒคํธ๊ฐ ์ค์ ํ๊ฒ ์์์ ์ ๋ฌ๋๋ ๋จ๊ณ
- ๋ฒ๋ธ๋ง ๋จ๊ณ: ์ด๋ฒคํธ๊ฐ ์์ ์์๋ก ์ ํ๋๋ ๋จ๊ณ
์๋ ๊ทธ๋ฆผ์ DOMํธ๋ฆฌ์์ ์ด๋ฒคํธ์ ํ๋ฆ์ ๊ทธ๋ฆผ์ผ๋ก ํํํ ๊ฒ์ ๋๋ค.

์ง์ ๊ทธ๋ ค๋ณด๋ฉด์ ์ดํดํ๊ธฐ
์ ๊ทธ๋ฆผ๊ณผ ๋จ๊ณ๋ฅผ ์ดํดํ๊ณ ๋ฌธ์ ๋ฅผ ๋ค์ ์ดํด๋ณด๋ฉด ์ด๋ ์ต๋๋ค.
- element2๋ฅผ ํด๋ฆญ ํฉ๋๋ค.
- ๋งจ ์๋จ์ ์กฐ์์ธ window์์๋ถํฐ ์ด๋ฒคํธ๊ฐ ์์๋์ด element2๊น์ง ์ ํ๋ฉ๋๋ค.(์บก์ณ๋ง ๋จ๊ณ)
- element2์ ํ ๋น๋ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.(ํ๊น ๋จ๊ณ)
- ๋ค์ window๊น์ง ์ด๋ฒคํธ๊ฐ ์ ํ๋ฉ๋๋ค.(๋ฒ๋ธ๋ง ๋จ๊ณ)
- element1์ ํ ๋น๋ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.
- ์ด๋ฒคํธ ํ๋ฆ์ด ์ข ๋ฃ๋ฉ๋๋ค.

์บก์ณ๋ง
๋์ผํ๊ฒ element2๋ฅผ ํด๋ฆญํ๋ฉด element1์ด ๋จผ์ ์ถ๋ ฅ๋๊ณ element2๊ฐ ์ถ๋ ฅ๋๊ฒ ํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํ ๊น์?
์ด๋ ์บก์ณ๋ง์ ์ด์ฉํ๋ฉด ๋ฉ๋๋ค.
addEventListener์ options ์ด์ฉํด์ ์บก์ฒ๋ง์ ํ์ฑํ ์์ผ์ฃผ๋ฉด ๋๋๋ฐ์ ๊ธฐ๋ณธ์ ์ผ๋ก addEventListener์์ ๊ธฐ๋ณธ๊ฐ์ false(๋ฒ๋ธ๋ง)์ ๋๋ค.
target.addEventListener(type, listener, options);
ele1.addEventListener('click', () => {}, { capture: true });
๋ค์ ํ๋ฒ ๊ทธ๋ฆผ์ ๋ณด๋ฉด์ ๋ฌธ์ ๋ฅผ ์ดํด๋ณผ๊น์?

- element2๋ฅผ ํด๋ฆญ ํฉ๋๋ค.
- ๋งจ ์๋จ์ ์กฐ์์ธ window์์๋ถํฐ ์ด๋ฒคํธ๊ฐ ์์๋์ด element2๊น์ง ์ ํ๋ฉ๋๋ค.(์บก์ณ๋ง ๋จ๊ณ)
- ์บก์ณ๋ง ๋จ๊ณ์์ ๋ฐ๊ฒฌ๋ element1์ ํ ๋น๋ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.
- element2์ ํ ๋น๋ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.(ํ๊น ๋จ๊ณ)
- ๋ค์ window๊น์ง ์ด๋ฒคํธ๊ฐ ์ ํ๋ฉ๋๋ค.(๋ฒ๋ธ๋ง ๋จ๊ณ)
- ์ด๋ฒคํธ ํ๋ฆ์ด ์ข ๋ฃ๋ฉ๋๋ค.
jsfiddle์์ ํ์ธ ํด์ฃผ์ธ์!
๋ฌธ์
์๋์ ๊ฐ์ด ์ด๋ฒคํธํธ๋ค๋ฌ๋ฅผ ๋ฑ๋ก ํด๋์ผ๋ฉด ์ด๋ป๊ฒ ๋ ๊น์?
ele2.addEventListener('click', () => alert('๋ฒ๋ธ:Element2'));
ele1.addEventListener('click', () => alert('๋ฒ๋ธ:Element1'));
ele1.addEventListener('click', () => alert('์บก์ณ:Element1'), { capture: true });
- element2๋ฅผ ํด๋ฆญ ํฉ๋๋ค.
- ๋งจ ์๋จ์ ์กฐ์์ธ window์์๋ถํฐ ์ด๋ฒคํธ๊ฐ ์์๋์ด element2๊น์ง ์ ํ๋ฉ๋๋ค.(์บก์ณ๋ง ๋จ๊ณ)
- ์บก์ณ๋ง ๋จ๊ณ์์ ๋ฐ๊ฒฌ๋ element1์ ํ ๋น๋ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.
- element2์ ํ ๋น๋ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.(ํ๊น ๋จ๊ณ)
- ๋ค์ window๊น์ง ์ด๋ฒคํธ๊ฐ ์ ํ๋ฉ๋๋ค.(๋ฒ๋ธ๋ง ๋จ๊ณ)
- ๋ฒ๋ธ๋ง ๋จ๊ณ์์ ๋ฐ๊ฒฌ๋ element1์ ํ ๋น๋ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.
- ์ด๋ฒคํธ ํ๋ฆ์ด ์ข ๋ฃ๋ฉ๋๋ค.
์บก์ณ:Element1 -> ๋ฒ๋ธ: Element2 -> ๋ฒ๋ธ: Element1์ ์์๋ก ์ถ๋ ฅ๋ฉ๋๋ค.
jsfiddle์์ ํ์ธ ํด์ฃผ์ธ์!
๋ฒ๋ธ๋ง๊ณผ ์บก์ณ๋ง์ ์ญ์ฌ
๊ณผ๊ฑฐ ๋ท์ค์ผ์ดํ vs MS์ ๋ธ๋ผ์ฐ์ ์ ์์ด ์์๋ค๊ณ ํฉ๋๋ค. ๋งจ ์ฒ์ ์ธ๊ธํ ๋ฌธ์ ์์
๋ท์ค์ผ์ดํ๋ element1์ ์ด๋ฒคํธ๊ฐ ๋จผ์ ๋ฐ์ํ๋ค๊ณ ์ด์ผ๊ธฐํ์ต๋๋ค.(์บก์ฒ๋ง)
๋ง์ดํฌ๋ก์ํํธ๋ element2 ์ด๋ฒคํธ๊ฐ ์ฐ์ ํ๋ค๊ณ ํ์ต๋๋ค.(๋ฒ๋ธ๋ง)
W3C์์๋ ํ๋ช ํ๊ฒ ๋๊ฐ์ง๋ฅผ ๋ชจ๋ ๊ฐ์ง์ ์๋ ์ค๊ฐ์ ์ ํํ์๊ณ ํ์ฌ์ ์ด๋ฒคํธ ์ ๋ฌ๊ณผ ํ๋ฆ์ ๊ฐ์ง๊ฒ ๋์๋ค๊ณ ํฉ๋๋ค.
can i use์์ capturing์ ๊ฒ์ ํด๋ณด๋ฉด IE 6-8์ ์บก์ณ๋ง ์ง์์ด ์๋๋ค๊ณ ํ์ธ์ด ๋๋ค์!
๋ง์น๋ฉฐ
์ด๋ฒคํธ์ ์ ๋ฌ ๋จ๊ณ์ ํ๋ฆ์ ์ดํด๋ณด๊ณ ๋ฒ๋ธ๋ง, ์บก์ณ๋ง์ ๊ฐ๋จํ๊ฒ ์ ์ฉํด๋ณด๋ฉด์ ์์๋ดค๋๋ฐ์
์ค๋ฌด์์ ํ๋์ ์ด๋ฒคํธ ์์์ ๋ํด์๋ ์ฐ๋ ค๊ณ ํ์ผ๋ ์๊ฐ๋ณด๋ค ๊ธ์ด ๊ธธ์ด์ ธ์ 2ํธ์์ ์๊ฐํด๋๋ฆฌ๊ฒ ์ต๋๋ค. ์ฝ์ด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค.