λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

πŸ‘©πŸ»‍πŸ’» dev

[ν† μŠ€] Transpiler, “μ‚¬μš©”말고 “ν™œμš©”ν•˜κΈ°

πŸ—£οΈ 이벀트 버블링과 캑쳐링에 λŒ€ν•΄μ„œ μ•Œκ³  κ³„μ‹œλ‚˜μš”?

λͺ¨λ˜ μžλ°”μŠ€ν¬λ¦½νŠΈ λ”₯λ‹€μ΄λΈŒμ—μ„œ λ΄€μ—ˆλŠ”λ°;;
버블링은 버블 μ •λ ¬μ²˜λŸΌ bubble upμ΄λΌλŠ” λ§μ—μ„œ μœ μΆ”ν•  수 μžˆλ“―μ΄ μ–΄λ–€ μ΄λ²€νŠΈκ°€ μ•„λž˜μ—μ„œ μœ„λ‘œ μ „μ΄λ˜λŠ” κ±°κ³ , 
캑쳐링은 λ°˜λŒ€λ‘œ μœ„μ—μ„œ μ•„λž˜λ‘œ μ „μ΄λ˜λŠ” κ±° μ•„λ‹ˆμ—ˆλ‚˜?

κ°œλ…μ€ μ–΄λŠ 정도 μ•Œκ³  μžˆμ§€λ§Œ μ‹€μ œ μ μš©μ„ ν•˜λŠ” κ²½μš°λ‘œλŠ” 연결이 λ˜μ§€ μ•Šμ•˜μ—ˆλ‹€.
이번 κΈ°νšŒμ— μ‹€μ œλ‘œ 캑쳐링을 ν™œμš©ν•œ ν† μŠ€μ˜ 'Transpiler, “μ‚¬μš©”말고 “ν™œμš©”ν•˜κΈ°'κ°€ 쒋은 μ˜ˆμ‹œμΈ κ±° κ°™μ•„μ„œ μ•Œμ•„λ³΄κ³ μž ν•œλ‹€.

법적 μ˜μ—­μ„ 잘 λͺ¨λ₯΄λŠ” μž…μž₯μ—μ„œ μ‚¬μš©μžμ˜ μΌκ±°μˆ˜μΌνˆ¬μ‘±μ„ λ‘œκΉ…ν•˜λŠ” 건 λ™μ˜ν•˜μ—λ§Œ κ°€λŠ₯ν•  κ±° κ°™κΈ° λ•Œλ¬Έμ— μ μš©ν•΄ λ³Ό κΈ°νšŒκ°€ μžˆμ„μ§€λŠ” λͺ¨λ₯΄κ² μ§€λ§Œ, μ‹€μ œ μ‚¬μš© 사둀λ₯Ό μ•Œμ•„μ•Ό 기얡에 더 남을 κ±° κ°™μ•„μ„œ, 
μ–΄λ–€ μ‹μœΌλ‘œ νŠΈλžœμŠ€νŒŒμΌλŸ¬μ™€ 이벀트 캑쳐링을 ν™œμš©ν•΄μ„œ λ‘œκΉ… κ³Όμ • κ°œμ„ μ„ ν–ˆλŠ”μ§€ ν† μŠ€κ°€ 이 이벀트 캑쳐링을 ν™œμš©ν•΄μ„œ λ‘œκΉ…μ„ μžλ™ν™”ν•œ 방법에 λŒ€ν•΄ μ‚΄νŽ΄λ³΄κ³ μž ν•œλ‹€.

λ¨Όμ € 이전에 μ •λ¦¬ν–ˆλ˜ 이벀트 μ „νŒŒμ— λŒ€ν•œ 글을 μž¬λ°©λ¬Έν•΄μ„œ 버블링/캑쳐링에 λŒ€ν•΄ μ‚΄νŽ΄λ³Έ λ’€, ν† μŠ€μ˜ 글을 정리해 보자.

이벀트 μ „νŒŒ (event propagation)

이벀트 μ „νŒŒλž€, dom 트리 상에 μ‘΄μž¬ν•˜λŠ” dom μš”μ†Œ λ…Έλ“œμ—μ„œ λ°œμƒν•˜λŠ” μ΄λ²€νŠΈλŠ” dom 트리λ₯Ό 톡해 μ „νŒŒλ˜λŠ” 것을 λ§ν•œλ‹€.

λ‹€μŒ μ½”λ“œλŠ” 각 νƒœκ·Έμ— 클릭 이벀트둜 둜그λ₯Ό 찍고 μžˆλŠ”λ°, 이벀트 μ „νŒŒκ°€ μ–΄λ–»κ²Œ λ°œμƒν•˜λŠ”μ§€ μ‚΄νŽ΄λ³΄μž.

<body>
    <p>버블링 캑쳐링 이벀트 <button>λ²„νŠΌ</button></p>
</body>

document.body.addEventListener('click',()=>{
    console.log('Handler for body');
});

document.querySelector('p').addEventListener('click',()=>{
    console.log('Handler for paragraph');
});

document.querySelector('button').addEventListener('click',()=>{
    console.log('Handler for button');
});

 

λ²„νŠΌμ„ ν΄λ¦­ν•˜λ©΄ μ–΄λ–€ 일이 μƒκΈΈκΉŒ?

 

πŸ‘‰ 직접 해보기 https://1973072.playcode.io/

 

JavaScript Playground

Upgrade to Personal Prop plan to remove the introduction. The introduction appears once for every user.

1973072.playcode.io

 

λ¨Όμ € μƒμ„±λœ 이벀트 κ°μ²΄λŠ” 이벀트λ₯Ό λ°œμƒμ‹œν‚¨ dom μš”μ†ŒμΈ 이벀트 타깃을 μ€‘μ‹¬μœΌλ‘œ dom 트리λ₯Ό 톡해 μ „νŒŒλœλ‹€.

μ „νŒŒ λ‹¨κ³„λŠ” 3λ‹¨κ³„λ‘œ ꡬ뢄할 수 μžˆλŠ”λ°, 캑쳐링/ 타깃 / λ²„λΈ”λ§μœΌλ‘œ κ΅¬μ„±λœλ‹€.

 

캑쳐링 λ‹¨κ³„μ—μ„œλŠ” μ΄λ²€νŠΈκ°€ dom 트리 μ΅œμƒλ‹¨μ—μ„œ ν•˜μœ„ μš”μ†Œλ‘œ μ „νŒŒλ˜κ³ , νƒ€κΉƒ λ‹¨κ³„μ—μ„œλŠ” μ΄λ²€νŠΈκ°€ 이벀트 타깃에 λ„λ‹¬ν•˜μ—¬ μ‹€ν–‰ν•˜κ³ , 

버블링 λ‹¨κ³„μ—μ„œλŠ” μ΄λ²€νŠΈκ°€ ν•˜μœ„ μš”μ†Œμ—μ„œ μƒμœ„ μš”μ†Œ λ°©ν–₯으둜 μ „νŒŒλœλ‹€.

 

μ΄λ ‡κ²Œ 이벀트 μ „νŒŒκ°€ λ˜λŠ” ν˜„μƒμ„ μ—Όλ‘ν•˜κ³  λ™μž‘μ„ μ˜ˆμΈ‘ν•΄ λ³Έλ‹€λ©΄

'Handler for paragraph'(캑쳐링) -> 'Handler for  button'(타깃)->'Handler for body'(버블링) 순으둜 좜λ ₯될 것이닀.

 

ν•˜μ§€λ§Œ μ‹€μ œλ‘œ λ²„νŠΌμ„ ν΄λ¦­ν•˜λ©΄ λ‹€μŒκ³Ό 같이 좜λ ₯이 λœλ‹€.

'Handler for  button' -> 'Handler for paragraph' -> 'Handler for body'

μ΄λŠ” 이벀트 λ¦¬μŠ€λ„ˆμ— capture option을 νŠΉμ •( { capture: true } ) ν•˜μ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έμ— 이벀트λ₯Ό 캑쳐링 λ‹¨κ³„μ—μ„œ μž‘μ§€ μ•ŠλŠ”λ‹€. 

λ”°λΌμ„œ button μš”μ†Œλ₯Ό ν΄λ¦­ν•˜λ©΄ μΊ‘쳐링 -> 타깃 -> 버블링 λ‹¨κ³„에 λ”°λΌμ„œ

body μš”μ†Œμ™€ p μš”μ†Œμ˜ 이벀트λ₯Ό 캑처만 ν•˜κ³  (μ‹€ν–‰ x), 타깃인 λ²„νŠΌ μš”μ†Œμ—μ„œ μ΄λ²€νŠΈκ°€ μ‹€ν–‰λ˜κ³ ,

버블링 λ‹¨κ³„μ—μ„œ pμš”μ†Œμ™€ bodyμš”μ†Œμ˜ 이벀트 순차적으둜 μ‹€ν–‰λœλ‹€.

 

캑쳐링 λ‹¨κ³„μ—μ„œ 이벀트 싀행을 μ›ν•œλ‹€λ©΄ λ‹€μŒκ³Ό 같이 μ˜΅μ…˜μ„ μΆ”κ°€ν•΄ 보면 

document.querySelector('p').addEventListener('click',()=>{
    console.log('Handler for paragraph');
}, { capture: true });

 

μ΄λ²ˆμ—λŠ” 좜λ ₯ μˆœμ„œκ°€ 첫 μ˜ˆμΈ‘λŒ€λ‘œ λ™μž‘ν•œλ‹€.

πŸ‘‰ 직접 해보기 https://1973090.playcode.io/

 

Clone JavaScript Playground

Upgrade to Personal Prop plan to remove the introduction. The introduction appears once for every user.

1973090.playcode.io

 

ν•˜μ§€λ§Œ λ•Œμ— 따라 이벀트 μ „νŒŒκ°€ λ˜μ§€ μ•Šλ„λ‘ ν•˜κ³  싢을 μˆ˜λ„ μžˆλ‹€. 그럴 λ•Œ event.stopPropagation λ©”μ„œλ“œλ₯Ό ν™œμš©ν•  수 μžˆλ‹€.

λ‹€λ§Œ μƒμœ„ μš”μ†Œμ—μ„œ 버블링이 ν•„μš”ν•œ 상황을 μ•„μ˜ˆ μ°¨λ‹¨ν•˜κΈ° λ•Œλ¬Έμ— μ‚¬μš©μ— 주의λ₯Ό ν•΄μ•Ό ν•œλ‹€.

이벀트 μœ„μž„ (event delegation)

이벀트 μœ„μž„μ€ μ—¬λŸ¬ 개의 ν•˜μœ„ dom μš”μ†Œμ— 각각 이벀트 ν•Έλ“€λŸ¬λ₯Ό λ“±λ‘ν•˜λŠ” λŒ€μ‹ 

ν•˜λ‚˜μ˜ μƒμœ„ dom μš”μ†Œμ— 이벀트 ν•Έλ“€λŸ¬λ₯Ό λ“±λ‘ν•˜μ—¬ μ—¬λŸ¬ μš”μ†Œλ₯Ό ν•œκΊΌλ²ˆμ— λ‹€λ£° 수 μžˆλ„λ‘ 이벀트 μ „νŒŒλ₯Ό ν™œμš©ν•œ 이벀트 핸듀링 νŒ¨ν„΄μ΄λ‹€.

 

이제 data-click-log 속성이 μžˆλŠ” κ°€μž₯ κ·Όμ ‘ν•œ μš”μ†Œλ₯Ό ν΄λ¦­ν•˜λ„λ‘ λ³€κ²½ν•΄ 보자.

<body data-click-log="body">
    <p data-click-log="paragraph">
      버블링 캑쳐링 이벀트 <button data-click-log="button">λ²„νŠΌ</button>
    </p>
</body>

<script>
  document.body.addEventListener(
      'click',
      event => {
        const logTarget = event.target.closest('[data-click-log]'); 
        if (logTarget) {
          console.log(`Handler for ${logTarget.getAttribute('data-click-log')}`);
        }
      },
      { capture: true }
    );
</script>

 

 

μ΄λ ‡κ²Œ 이벀트 μ „νŒŒ 속성을 ν™œμš©ν•΄ λ‹¨μˆœ 반볡의 과정을 ν•˜λ‚˜ 덜 수 μžˆλ‹€.

μ΄λ²ˆμ—λŠ” ν† μŠ€μ˜ κΈ€μ—μ„œλŠ” 트랜슀파일러λ₯Ό ν™œμš©ν•΄ data-click-log 속성을 μžλ™μœΌλ‘œ μ£Όμž…ν•˜λŠ” 방법에 λŒ€ν•΄ μ‚΄νŽ΄λ³΄μž.

ν† μŠ€: Transpilerλ₯Ό ν™œμš©ν•œ λ‘œκΉ…

 

νŠΈλžœμŠ€νŒŒμΌλŸ¬λŠ” μ½”λ“œλ₯Ό λ³€ν™˜ν•΄ μ£ΌλŠ” 도ꡬ닀.

예λ₯Ό λ“€λ©΄, ES6λ₯Ό ES5둜 λ³€ν™˜ν•˜κ±°λ‚˜ λ¦¬μ•‘νŠΈμ˜ JSX/TSλ₯Ό λΈŒλΌμš°μ €κ°€ 이해할 수 μžˆλŠ” μžλ°”μŠ€ν¬λ¦½νŠΈλ‘œ λ³€ν™˜ν•΄ μ£ΌλŠ” 역할을 ν•΄μ£Όκ³ ,

λΈŒλΌμš°μ € ν˜Έν™˜μ„± 등을 μœ μ§€ν•  수 μžˆλ„λ‘ λ„μ™€μ€€λ‹€λŠ” μ μ—μ„œ, κ°œλ°œμžλŠ” λΉ„μ¦ˆλ‹ˆμŠ€ λ‘œμ§μ— 집쀑을 해쀄 수 μžˆλ‹€λŠ” μ μ—μ„œ μœ μš©ν•˜λ‹€.

babelμ΄λ‚˜ swcκ°€ λŒ€ν‘œμ μΈ νŠΈλžœμŠ€νŒŒμΌλŸ¬μ— ν•΄λ‹Ήλ˜λŠ”λ°, ν† μŠ€λŠ” 이 트랜슀파일러의 νŠΉμ§•μ„ μ‚΄λ € λ‘œκΉ… 과정을 κ°œμ„ ν–ˆλ‹€.

 

λ‘œκΉ…μ„ μ„€κ³„ν•˜λŠ” 방식은 크게 두 κ°€μ§€λ‘œ 생각해 λ³Ό 수 μžˆλ‹€.

// μˆ˜λ™μœΌλ‘œ λ‘œκΉ… ν•¨μˆ˜ μ‹€ν–‰
<Button
  onClick={() => {
    log({ content: 'λ‹€μŒ' });
    handleClick();
  }}
>
  λ‹€μŒ
</Button>

// μΆ”μƒν™”λœ λ‘œκΉ… μ»΄ν¬λ„ŒνŠΈ ν™œμš©
<LoggingClick>
  <Button onClick={handleClick}>
    λ‹€μŒ
  </Button>
</LoggingClick>

 

λ˜λŠ” μœ„μ—μ„œ λ‹€λ£¨μ—ˆλ˜ 이벀트 캑쳐링과 data-attribute으둜 λ‘œκΉ…μ„ μ²˜λ¦¬ν•  μˆ˜λ„ μžˆλ‹€.

<Button onClick={() => {}} data-click-log>
  λ‹€μŒ
</Button>

// 클릭 μ‹œ click event 캑쳐링을 톡해 μΈμ§€ν•˜κ³ , 
// 클릭 νƒ€κΉƒμ—μ„œ κ°€μž₯ κ·Όμ ‘ν•œ data-click-log 속성을 μ§€λ‹Œ DOM μ°Ύκ³ ,
// dom의 text nodeλ₯Ό νŒŒμ•…ν•˜μ—¬ μœ μ €κ°€ ν΄λ¦­ν•œ μ»΄ν¬λ„ŒνŠΈμ˜ 정보λ₯Ό λ‹€μŒκ³Ό 같이 λ‘œκΉ…ν•œλ‹€.

{
  log_type: 'click',
  content: 'λ‹€μŒ',
}

 

ν•˜μ§€λ§Œ μœ„μ˜ 방식은 μ˜€νƒ€λ‚˜ λˆ„λ½ μ‹€μˆ˜μ— μ·¨μ•½ν•˜κ³  μ—¬λŸ¬ ν”„λ‘­μŠ€κ°€ μ „λ‹¬λ˜λŠ” μƒν™©μ—μ„œλŠ” λ”μš±λ” μ·¨μ•½ν•΄μ§ˆ μˆ˜λ°–μ— μ—†λ‹€. 

그리고 반볡/κ·œμΉ™μ μœΌλ‘œ μ½”λ“œλ₯Ό λ³€κ²½ν•΄μ•Ό ν•˜λŠ” μ§€λ£¨ν•œ μž‘μ—…λ„ 업무 νš¨μœ¨μ„ μ €ν•˜μ‹œν‚¬ 것이닀.

<Button
  type="primary"
  variant="weak"
  size="large"
  data-cilck-log // μ˜€νƒ€
  onClick={() => {}}
  disabled={false}
  loading={false}
  css={{ minWidth: 100, minHeight: 80 }}
>
  λ‹€μŒ
</Button>

 

lint rule을 μΆ”κ°€ν•˜κ±°λ‚˜ μžλ™ μ™„μ„± κΈ°λŠ₯을 μ œκ³΅ν•˜λŠ” λ°©μ‹μœΌλ‘œ λ‹¨μˆœ μ‹€μˆ˜λ₯Ό 쀄일 μˆ˜λŠ” μžˆμ§€λ§Œ,

이 방식은 λΉ„μ¦ˆλ‹ˆμŠ€ 둜직과 직결된 μ½”λ“œλž‘ λ‘œκΉ… μ½”λ“œλ₯Ό λΆ„λ¦¬ν•˜μ§€ μ•ŠλŠ”λ‹€λŠ” μ μ—μ„œ 근본적인 문제λ₯Ό ν•΄κ²°ν•  수 μ—†μ–΄ μ•„μ‰½λ‹€λŠ” λ¬Έμ œκ°€ μ—¬μ „νžˆ μžˆλ‹€.

clickable ν•œ μš”μ†Œμ— data-click-log 속성을 μžλ™μœΌλ‘œ μ£Όμž…ν•  수 μžˆλ‹€λ©΄? +𝛼 μ½”λ“œλ₯Ό 지 ν•„μš”κ°€ μ—†λ‹€λ©΄? 

 

μ—¬κΈ°μ„œ 트랜슀파일러의 역할이 빛을 λ‚Ό 수 μžˆλ‹€.

νŠΉμ •μ‘°κ±΄(Clickable ν•œ μš”μ†Œ)에 따라 μ•Œλ§žκ²Œ(data-click-log 속성 μΆ”κ°€) μ½”λ“œ λ³€ν™˜ν•˜κΈ°μ— transplierκ°€ 적합!

<Button onClick={() => {}}>
  λ‹€μŒ
</Button>

// μœ„μ˜ μ½”λ“œκ°€ μ•„λž˜μ²˜λŸΌ μžλ™ λ³€ν™˜λ˜λ©΄ μ’‹κ² λ‹€!
<Button onClick={() => {}} data-click-log>
  λ‹€μŒ
</Button>

 

ν† μŠ€λŠ” λ‹€μŒκ³Ό 같이 clickable (onClick, onChange, onTouchStart)와 같은 μœ μ € 클릭 λ°˜μ‘ 이벀트 ν•Έλ“€λŸ¬λ₯Ό κ·œμ •ν•˜κ³ ,

ν•΄λ‹Ή 쑰건에 μΆ©μ‘±ν•˜λŠ” SWC와 Babel용 ν”ŒλŸ¬κ·ΈμΈμ„ λ§Œλ“€μ—ˆλ‹€.

const CLICK_EVENTS = ['onClick', 'onTouchStart', 'onChange', 'onMouseDown'];
const CLICK_LOG_ATTR = 'data-click-log';

function plugin({ types: t }: typeof babel): PluginObj {
  return {
    name: 'babel-plugin-tossbank-logger',
    visitor: {
      JSXOpeningElement(path) { // JSX νƒœκ·Έμ˜ μ‹œμž‘ μš”μ†Œλ“€μ„ μˆœνšŒν•˜λ©° μ‹€ν–‰ν•  콜백 μ •μ˜
        const { node } = path;

		// 각 μš”μ†Œ μˆœνšŒν•˜λ©° CLICK_EVENTS에 ν•΄λ‹Ήν•˜λŠ” clickable 이벀트 ν•Έλ“€λŸ¬κ°€ μ‘΄μž¬ν•˜λŠ” 지 체크
        const hasOnClickAttribute = node.attributes.some(attr => { 
          return CLICK_EVENTS.includes(attr.name.name);
        });
		// clickable μ΄λ²€νŠΈκ°€ μ‘΄μž¬ν•˜λ©΄ CLICK_LOG_ATTR μ£Όμž…!
        if (hasOnClickAttribute) {
          const dataClickLogAttribute = t.jSXAttribute(t.jSXIdentifier(CLICK_LOG_ATTR), null);

          node.attributes.push(dataClickLogAttribute);
        }
      },
    },
  };
}

 

Babel은 AST(좔상 ꡬ문 트리)λ₯Ό λ§Œλ“€κ³ , 각 ν”ŒλŸ¬κ·ΈμΈμ—κ²Œ μ œκ³΅ν•˜μ—¬ 각 λ…Έλ“œλ“€μ„ μˆœνšŒν•˜λ©° μ²˜λ¦¬ν•  수 μžˆλ„λ‘ μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ œκ³΅ν•˜κ³  μžˆλ‹€.

이제 λ‘œκΉ… ν”ŒλŸ¬κ·ΈμΈμ„ ν™œμš©ν•œλ‹€λ©΄ 클릭 λ‘œκΉ…μ„ μ½”λ“œμ— μΆ”κ°€ν•  ν•„μš” 없이 λΉ„μ¦ˆλ‹ˆμŠ€ 둜직만으둜 μ½”λ“œλ₯Ό μž‘μ„±ν•  수 μžˆλ‹€.

<Button onClick={() => {}}>
  λ‹€μŒ
</Button>

 

ν•΄λ‹Ή λ°©λ²•μœΌλ‘œλŠ” 관심사가 뢄리될 뿐만 μ•„λ‹ˆλΌ λˆ„κ΅¬λ“ μ§€ λ™μΌν•˜κ²Œ λ‘œκΉ…μ„ μ²˜λ¦¬ν•˜λ„λ‘ 보μž₯ν•΄ μ€€λ‹€λŠ” μž₯점이 μžˆλ‹€.


πŸ€ λ§ˆμΉ˜λ©΄μ„œ

μ˜€λŠ˜μ€ 이벀트 μœ„μž„(event delegation)κ³Ό 트랜슀파일러λ₯Ό ν™œμš©ν•œ ν† μŠ€μ˜ λ‘œκΉ… μžλ™ν™” 방법에 λŒ€ν•΄ μ‚΄νŽ΄λ΄€λ‹€.
이전에 이벀트 μœ„μž„/μ „νŒŒμ— λŒ€ν•΄ μ •λ¦¬ν•œ 글이 μžˆμ—ˆλŠ”λ°, 였λ₯˜λ₯Ό 발견!
μ±…λ§Œ 읽고 ν”Όμƒμ μœΌλ‘œ 그럴 것이닀~라고 μƒκ°ν–ˆλŠ”λ°, μ‹€μ œλ‘œ μ½”λ“œλ₯Ό μ°μ–΄λ³΄λ‹ˆ μ’€ λ‹€λ₯Έ κ²°κ³Όκ°€ λ‚˜μ™”μ—ˆλ‹€.
이벀트 버블링/캑쳐링에 λŒ€ν•΄ κ°€λ¬Όκ°€λ¬Ό ν•΄μ§ˆ λ•Œμ―€, 이벀트 μ „νŒŒμ— λŒ€ν•΄ μ•Œκ³  μžˆλŠ” 것을 μ κ²€ν•˜κ³ , 쒋은 μ‹€μ œ μ‚¬μš© 사둀에 λŒ€ν•΄ 닀뀄 λ³Ό 수 μžˆμ–΄μ„œ λ”μš± 기얡에 남을 κ±° κ°™λ‹€!

ν† μŠ€ κΈ€ λŒ“κΈ€μ— 질문이 ν•˜λ‚˜ μžˆμ—ˆλŠ”λ°, 닡을 μ°ΎκΈ° μœ„ν•΄ 이것저것 찾아보닀가 λ¦¬μ•‘νŠΈμ—μ„œλŠ” 이벀트 핸듀링 방식이 κΈ°μ‘΄ domκ³ΌλŠ” μ’€ λ‹€λ₯Έ ν˜•νƒœλΌλŠ” κ±Έ μ•Œκ²Œ λ˜μ—ˆλŠ”λ°, λ‹€μŒμ—λŠ” 이 뢀뢄에 λŒ€ν•΄ 더 μ‚΄νŽ΄λ³Ό κ±° κ°™λ‹€.

 

 

λ¦¬μ•‘νŠΈ 이벀트 ν•Έλ“€λŸ¬λŠ” 버블링 μ‹œ μ‹€ν–‰λœλ‹€λŠ” 점을 보면 onClickCaptureλ₯Ό 톡해 λ”°λ‘œ λͺ…μ‹œν•˜μ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έμ— 버블링을 ν™œμš©ν•œ 게 λ§žλŠ” κ±° κ°™λ‹€.

πŸ“š References

https://github.com/Pyotato/fe_study/blob/main/modern_javascript_deep_dive/40_event.md

 

fe_study/modern_javascript_deep_dive/40_event.md at main · Pyotato/fe_study

πŸ“• ν”„λ‘ νŠΈμ—”λ“œ 곡뢀λ₯Ό ν•˜λ©΄μ„œ λ„μ μ΄λŠ” 이것 저것. Contribute to Pyotato/fe_study development by creating an account on GitHub.

github.com

https://toss.tech/article/27750

 

Transpiler, “μ‚¬μš©”말고 “ν™œμš©”ν•˜κΈ°

맀일 “μ‚¬μš©”만 ν•˜λŠ” transpiler, ν† μŠ€λ±…ν¬μ—μ„œλŠ” ν•œ 단계 더 잘 “ν™œμš©”ν•΄ 보기둜 ν–ˆμ–΄μš”. μ˜€λŠ˜μ€ transpiler둜 λ‘œκΉ… 과정을 κ°œμ„ ν•œ 사둀λ₯Ό μ†Œκ°œ λ“œλ¦΄κ²Œμš”.

toss.tech

https://ko.javascript.info/bubbling-and-capturing

 

버블링과 캑처링

 

ko.javascript.info