Skip to content

Latest commit

Β 

History

History
779 lines (598 loc) Β· 24.9 KB

File metadata and controls

779 lines (598 loc) Β· 24.9 KB

39μž₯ 이벀트

39.6 DOM μ‘°μž‘

DOM μ‘°μž‘μ€ μƒˆλ‘œμš΄ λ…Έλ“œλ₯Ό μƒμ„±ν•˜μ—¬ DOM에 μΆ”κ°€ν•˜κ±°λ‚˜ κΈ°μ‘΄ λ…Έλ“œλ₯Ό μ‚­μ œ λ˜λŠ” κ΅μ²΄ν•˜λŠ” 것.
DOM μ‘°μž‘μ— μ˜ν•΄ DOM에 μƒˆλ‘œμš΄ λ…Έλ“œκ°€ μΆ”κ°€λ˜κ±°λ‚˜ μ‚­μ œλ˜λ©΄ λ¦¬ν”Œλ‘œμš°μ™€ λ¦¬νŽ˜μΈνŠΈκ°€ λ°œμƒν•˜λŠ” 원인이 λ˜λ―€λ‘œ μ„±λŠ₯에 영ν–₯을 쀌. λ³΅μž‘ν•œ μ½˜ν…μΈ λ₯Ό λ‹€λ£¨λŠ” DOM μ‘°μž‘μ€ μ„±λŠ₯ μ΅œμ ν™”λ₯Ό μœ„ν•΄ μ£Όμ˜ν•΄μ„œ 닀루어야 함.

39.6.1 innerHTML

Element.prototype.innerHTML ν”„λ‘œνΌν‹°λŠ” setter, getter λͺ¨λ‘ μ‘΄μž¬ν•˜λŠ” μ ‘κ·Όμž ν”„λ‘œνΌν‹°λ‘œμ„œ μš”μ†Œ λ…Έλ“œμ˜ HTML λ§ˆν¬μ—…μ„ μ·¨λ“ν•˜κ±°λ‚˜ 변경함. μš”μ†Œ λ…Έλ“œμ˜ innerHTML ν”„λ‘œνΌν‹°λ₯Ό μ°Έμ‘°ν•˜λ©΄ μš”μ†Œ λ…Έλ“œμ˜ μ½˜ν…μΈ  μ˜μ—­ 내에 ν¬ν•¨λœ λͺ¨λ“  HTML λ§ˆν¬μ—…μ„ λ¬Έμžμ—΄λ‘œ λ°˜ν™˜ν•¨

39-41

<!DOCTYPE html>
<html>
  <body>
    <div id="foo">Hello <span>world!</span></div>
  </body>
  <script>
    // #foo μš”μ†Œμ˜ μ½˜ν…μΈ  μ˜μ—­ λ‚΄μ˜ HTML λ§ˆν¬μ—…μ„ λ¬Έμžμ—΄λ‘œ μ·¨λ“ν•œλ‹€.
    console.log(document.getElementById('foo').innerHTML);
    // "Hello <span>world!</span>"
  </script>
</html>

textContent ν”„λ‘œνΌν‹°λŠ” HTML λ§ˆν¬μ—… λ¬΄μ‹œν•˜κ³  ν…μŠ€νŠΈλ§Œ λ°˜ν™˜
innerHTML ν”„λ‘œνΌν‹°λŠ” HTML λ§ˆν¬μ—…μ΄ ν¬ν•¨λœ λ¬Έμžμ—΄ κ·ΈλŒ€λ‘œ λ°˜ν™˜

39-42

μš”μ†Œ λ…Έλ“œμ˜ innerHTML ν”„λ‘œνΌν‹°μ— λ¬Έμžμ—΄μ„ ν• λ‹Ήν•˜λ©΄ μš”μ†Œ λ…Έλ“œμ˜ λͺ¨λ“  μžμ‹ λ…Έλ“œκ°€ 제거되고
ν• λ‹Ήν•œ λ¬Έμžμ—΄μ— ν¬ν•¨λ˜μ–΄ μžˆλŠ” HTML λ§ˆν¬μ—…μ΄ νŒŒμ‹±λ˜μ–΄ μš”μ†Œ λ…Έλ“œμ˜ μžμ‹ λ…Έλ“œλ‘œ DOM에 반영됨

<!DOCTYPE html>
<html>
  <body>
    <div id="foo">Hello <span>world!</span></div>
  </body>
  <script>
    // HTML λ§ˆν¬μ—…μ΄ νŒŒμ‹±λ˜μ–΄ μš”μ†Œ λ…Έλ“œμ˜ μžμ‹ λ…Έλ“œλ‘œ DOM에 λ°˜μ˜λœλ‹€.
    document.getElementById('foo').innerHTML = 'Hi <span>there!</span>';
  </script>
</html>

39-43

μš”μ†Œ λ…Έλ“œμ˜ innerHTML ν”„λ‘œνΌν‹°μ— ν• λ‹Ήν•œ HTML λ§ˆν¬μ—… λ¬Έμžμ—΄μ€ λ Œλ”λ§ 엔진에 μ˜ν•΄ νŒŒμ‹±λ˜μ–΄
μš”μ†Œ λ…Έλ“œμ˜ μžμ‹μœΌλ‘œ DOM에 반영됨

<!DOCTYPE html>
<html>
  <body>
    <ul id="fruits">
      <li class="apple">Apple</li>
    </ul>
  </body>
  <script>
    const $fruits = document.getElementById('fruits');

    // λ…Έλ“œ μΆ”κ°€
    $fruits.innerHTML += '<li class="banana">Banana</li>';

    // λ…Έλ“œ ꡐ체
    $fruits.innerHTML = '<li class="orange">Orange</li>';

    // λ…Έλ“œ μ‚­μ œ
    $fruits.innerHTML = '';
  </script>
</html>

μ‚¬μš©μžλ‘œλΆ€ν„° μž…λ ₯받은 데이터(untrusted input data)λ₯Ό κ·ΈλŒ€λ‘œ innerHTML ν”„λ‘œνΌν‹°μ— ν• λ‹Ήν•˜λŠ” 것은 크둜슀 μ‚¬μ΄νŠΈ μŠ€ν¬λ¦½νŒ… 곡격에 μ·¨μ•½ν•˜λ―€λ‘œ μœ„ν—˜ν•¨. λ§ˆν¬μ—… 내에 μ•…μ„± μ½”λ“œκ°€ 있으면 νŒŒμ‹± κ³Όμ •μ—μ„œ κ·ΈλŒ€λ‘œ μ‹€ν–‰λ˜κΈ° λ•Œλ¬Έ.

39-44

슀크립트 νƒœκ·Έ μ‚½μž…ν•˜μ—¬ μžλ°”μŠ€ν¬λ¦½νŠΈκ°€ μ‹€ν–‰λ˜λ„λ‘ ν•˜λŠ” 예제

<!DOCTYPE html>
<html>
  <body>
    <div id="foo">Hello</div>
  </body>
  <script>
    // innerHTML ν”„λ‘œνΌν‹°λ‘œ 슀크립트 νƒœκ·Έλ₯Ό μ‚½μž…ν•˜μ—¬ μžλ°”μŠ€ν¬λ¦½νŠΈκ°€ μ‹€ν–‰λ˜λ„λ‘ ν•œλ‹€.
    // HTML5λŠ” innerHTML ν”„λ‘œνΌν‹°λ‘œ μ‚½μž…λœ script μš”μ†Œ λ‚΄μ˜ μžλ°”μŠ€ν¬λ¦½νŠΈ μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜μ§€ μ•ŠλŠ”λ‹€.
    document.getElementById('foo').innerHTML
      = '<script>alert(document.cookie)</script>';
  </script>
</html>

=> HTML5λŠ” innerHTML ν”„λ‘œνΌν‹°λ‘œ μ‚½μž…λœ script μš”μ†Œ λ‚΄μ˜ μžλ°”μŠ€ν¬λ¦½νŠΈ μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜μ§€ μ•ŠμŒ. HTML5λ₯Ό μ§€μ›ν•˜λŠ” λΈŒλΌμš°μ €μ—μ„œ λ™μž‘ν•˜μ§€ μ•ŠμŒ.

ν•˜μ§€λ§Œ script μš”μ†Œ 없이도 크둜슀 μ‚¬μ΄νŠΈ μŠ€ν¬λ¦½νŒ… 곡격은 κ°€λŠ₯

39-45

κ°„λ‹¨ν•œ 크둜슀 μ‚¬μ΄νŠΈ μŠ€ν¬λ¦½νŒ… 곡격

<!DOCTYPE html>
<html>
  <body>
    <div id="foo">Hello</div>
  </body>
  <script>
    // μ—λŸ¬ 이벀트λ₯Ό κ°•μ œλ‘œ λ°œμƒμ‹œμΌœμ„œ μžλ°”μŠ€ν¬λ¦½νŠΈ μ½”λ“œκ°€ μ‹€ν–‰λ˜λ„λ‘ ν•œλ‹€.
    document.getElementById(
      'foo'
    ).innerHTML = `<img src="x" onerror="alert(document.cookie)">`;
  </script>
</html>

innerHTML ν”„λ‘œνΌν‹°λ₯Ό μ‚¬μš©ν•œ DOM μ‘°μž‘μ€ κ΅¬ν˜„μ΄ κ°„λ‹¨ν•˜κ³  μ§κ΄€μ μ΄μ§€λ§Œ
크둜슀 μ‚¬μ΄νŠΈ μŠ€ν¬λ¦½νŒ… 곡격에 μ·¨μ•½ν•˜λ‹€λŠ” 단점이 있음

HTML μƒˆλ‹ˆν‹°μ œμ΄μ…˜ 크둜슀 μ‚¬μ΄νŠΈ μŠ€ν¬λ¦½νŒ… 곡격을 μ˜ˆλ°©ν•˜κΈ° μœ„ν•΄ 잠재적 μœ„ν—˜μ„ μ œκ±°ν•˜λŠ” κΈ°λŠ₯. DOMPurify 라이브러리 μ‚¬μš© ꢌμž₯

DOMPurify.sanitize('<img src="x" onerror="alert(document.cookie)" />');

=> <img src="x">

또 λ‹€λ₯Έ 단점 : μš”μ†Œ λ…Έλ“œμ˜ innerHTML ν”„λ‘œνΌν‹°μ— HTML λ§ˆν¬μ—… λ¬Έμžμ—΄μ„ ν• λ‹Ήν•˜λ©΄ μš”μ†Œ λ…Έλ“œμ˜ λͺ¨λ“  μžμ‹ λ…Έλ“œλ₯Ό μ œκ±°ν•˜κ³  ν• λ‹Ήν•œ HTML λ§ˆν¬μ—… λ¬Έμžμ—΄μ„ νŒŒμ‹±ν•˜μ—¬ DOM을 λ³€κ²½

39-46

<!DOCTYPE html>
<html>
  <body>
    <ul id="fruits">
      <li class="apple">Apple</li>
    </ul>
  </body>
  <script>
    const $fruits = document.getElementById('fruits');

    // λ…Έλ“œ μΆ”κ°€
    $fruits.innerHTML += '<li class="banana">Banana</li>';
  </script>
</html>

=> li.banana μš”μ†Œ λ…Έλ“œλ§Œ μƒμ„±ν•˜μ—¬ μžμ‹ μš”μ†Œλ‘œ μΆ”κ°€ν•  것 κ°™μ§€λ§Œ
#fruits μš”μ†Œμ˜ λͺ¨λ“  μžμ‹ λ…Έλ“œ(li.apple)λ₯Ό μ œκ±°ν•˜κ³ 
μƒˆλ‘­κ²Œ μš”μ†Œ λ…Έλ“œ li.apple, li.bananaλ₯Ό μƒμ„±ν•˜μ—¬ μžμ‹ μš”μ†Œλ‘œ 좔가함

39-47

39-48 μ½”λ“œμ˜ μΆ•μ•½ ν‘œν˜„

$fruits.innerHTML += '<li class="banana">Banana</li>';

39-48

$fruits.innerHTML = $fruits.innerHTML + '<li class="banana">Banana</li>';
// '<li class="apple">Apple</li>' + '<li class="banana">Banana</li>'

λΉ„νš¨μœ¨μ  : 기쑴의 μžμ‹ λ…Έλ“œκΉŒμ§€ λͺ¨λ‘ μ œκ±°ν•˜κ³  λ‹€μ‹œ μ²˜μŒλΆ€ν„° μƒˆλ‘­κ²Œ μžμ‹ λ…Έλ“œλ₯Ό 생성해 DOM에 반영

39-49

또 λ‹€λ₯Έ 단점 : μƒˆλ‘œμš΄ μš”μ†Œλ₯Ό μ‚½μž…ν•  λ•Œ μ‚½μž…λ  μœ„μΉ˜λ₯Ό μ§€μ •ν•  수 μ—†μŒ li.appleκ³Ό li.orange μš”μ†Œ 사이에 μƒˆλ‘œμš΄ μš”μ†Œλ₯Ό μ‚½μž…ν•˜κ³  싢은 경우 innerHTML ν”„λ‘œνΌν‹°λ₯Ό μ‚¬μš©ν•˜λ©΄ μ‚½μž… μœ„μΉ˜λ₯Ό μ§€μ •ν•  수 μ—†μŒ.

<ul id="fruits">
  <li class="apple">Apple</li>
  <li class="orange">Orange</li>
</ul>

=> innerHTML ν”„λ‘œνΌν‹°λŠ” λ³΅μž‘ν•˜μ§€ μ•Šμ€ μš”μ†Œλ₯Ό μƒˆλ‘­κ²Œ μΆ”κ°€ν•  λ•ŒλŠ” μœ μš©ν•˜μ§€λ§Œ
κΈ°μ‘΄ μš”μ†Œλ₯Ό μ œκ±°ν•˜μ§€ μ•ŠμœΌλ©΄μ„œ μœ„μΉ˜λ₯Ό μ§€μ •ν•΄ μƒˆλ‘œμš΄ μš”μ†Œλ₯Ό μ‚½μž…ν•΄μ•Ό ν•  λ•ŒλŠ” μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” 것이 μ’‹μŒ

39.6.2 insertAdjacentHTML λ©”μ„œλ“œ

Element.prototype.insertAdjacentHTML(position, DOMString) λ©”μ„œλ“œλŠ” κΈ°μ‘΄ μš”μ†Œ μ œκ±°ν•˜μ§€ μ•ŠμœΌλ©΄μ„œ μœ„μΉ˜λ₯Ό μ§€μ •ν•΄ μƒˆλ‘œμš΄ μš”μ†Œ μ‚½μž…

두 번째 인수둜 μ „λ‹¬ν•œ HTML λ§ˆν¬μ—… λ¬Έμžμ—΄(DOMString)을 νŒŒμ‹±ν•˜κ³ 
κ·Έ 결과둜 μƒμ„±λœ λ…Έλ“œλ₯Ό 첫 번째 인수둜 μ „λ‹¬ν•œ μœ„μΉ˜(position)에 μ‚½μž…ν•˜μ—¬ DOM에 반영

  • 첫 번쨰 인수둜 전달 κ°€λŠ₯ν•œ λ¬Έμžμ—΄
    • beforebegin
    • afterbegin
    • beforeend
    • afterend

39-50

<!DOCTYPE html>
<html>
  <body>
    <!-- beforebegin -->
    <div id="foo">
      <!-- afterbegin -->
      text
      <!-- beforeend -->
    </div>
    <!-- afterend -->
  </body>
  <script>
    const $foo = document.getElementById('foo');

    $foo.insertAdjacentHTML('beforebegin', '<p>beforebegin</p>');
    $foo.insertAdjacentHTML('afterbegin', '<p>afterbegin</p>');
    $foo.insertAdjacentHTML('beforeend', '<p>beforeend</p>');
    $foo.insertAdjacentHTML('afterend', '<p>afterend</p>');
  </script>
</html>

이 λ©”μ„œλ“œλŠ” κΈ°μ‘΄ μš”μ†Œμ—λŠ” 영ν–₯을 μ£Όμ§€ μ•Šκ³ , μƒˆλ‘­κ²Œ μ‚½μž…λ  μš”μ†Œλ§Œμ„ νŒŒμ‹±ν•˜μ—¬ μžμ‹ μš”μ†Œλ‘œ μΆ”κ°€ν•˜λ―€λ‘œ
innerHTML ν”„λ‘œνΌν‹°λ³΄λ‹€ 효율적이고 빠름

ν•˜μ§€λ§Œ, λ§ˆμ°¬κ°€μ§€λ‘œ HTML λ§ˆν¬μ—… λ¬Έμžμ—΄μ„ νŒŒμ‹±ν•˜λ―€λ‘œ 크둜슀 μ‚¬μ΄νŠΈ μŠ€ν¬λ¦½νŒ… 곡격에 μ·¨μ•½ν•œ 것은 동일

39.6.3 λ…Έλ“œ 생성과 μΆ”κ°€

innerHTML ν”„λ‘œνΌν‹°, insertAdjacentHTML λ©”μ„œλ“œλŠ” HTML λ§ˆν¬μ—… λ¬Έμžμ—΄μ„ νŒŒμ‹±ν•˜μ—¬ λ…Έλ“œ μƒμ„±ν•˜κ³  DOM에 반영

DOM은 λ…Έλ“œλ₯Ό 직접 생성/μ‚½μž…/μ‚­μ œ/μΉ˜ν™˜ν•˜λŠ” λ©”μ„œλ“œλ„ 제곡

39-51

<!DOCTYPE html>
<html>
  <body>
    <ul id="fruits">
      <li>Apple</li>
    </ul>
  </body>
  <script>
    const $fruits = document.getElementById('fruits');

    // 1. μš”μ†Œ λ…Έλ“œ 생성
    const $li = document.createElement('li');

    // 2. ν…μŠ€νŠΈ λ…Έλ“œ 생성
    const textNode = document.createTextNode('Banana');

    // 3. ν…μŠ€νŠΈ λ…Έλ“œλ₯Ό $li μš”μ†Œ λ…Έλ“œμ˜ μžμ‹ λ…Έλ“œλ‘œ μΆ”κ°€
    $li.appendChild(textNode);

    // 4. $li μš”μ†Œ λ…Έλ“œλ₯Ό #fruits μš”μ†Œ λ…Έλ“œμ˜ λ§ˆμ§€λ§‰ μžμ‹ λ…Έλ“œλ‘œ μΆ”κ°€
    $fruits.appendChild($li);
  </script>
</html>

=> μƒˆλ‘œμš΄ μš”μ†Œ λ…Έλ“œ μƒμ„±ν•˜κ³ , ν…μŠ€νŠΈ λ…Έλ“œ μƒμ„±ν•˜μ—¬, μš”μ†Œ λ…Έλ“œμ˜ μžμ‹ λ…Έλ“œλ‘œ μΆ”κ°€ν•˜κ³ , μš”μ†Œ λ…Έλ“œλ₯Ό DOM에 μΆ”κ°€

μš”μ†Œ λ…Έλ“œ 생성

Document.prototype.createElement(tagName) λ©”μ„œλ“œλŠ” μš”μ†Œ λ…Έλ“œλ₯Ό μƒμ„±ν•˜μ—¬ λ°˜ν™˜
tagNameμ—λŠ” νƒœκ·Έ 이름을 λ‚˜νƒ€λ‚΄λŠ” λ¬Έμžμ—΄μ„ 인수둜 전달

39-52

// 1. μš”μ†Œ λ…Έλ“œ 생성
const $li = document.createElement('li');

=> κΈ°μ‘΄ DOM에 μΆ”κ°€ν•˜μ§€ μ•Šκ³  ν™€λ‘œ μ‘΄μž¬ν•˜λŠ” μƒνƒœ. μš”μ†Œ λ…Έλ“œλ₯Ό 생성할 뿐, DOM에 μΆ”κ°€ν•˜μ§€λŠ” μ•ŠμŒ
μƒμ„±λœ μš”μ†Œ λ…Έλ“œλ₯Ό DOM에 μΆ”κ°€ν•˜λŠ” 별도 처리 ν•„μš”

39-53

// 1. μš”μ†Œ λ…Έλ“œ 생성
const $li = document.createElement('li');
// μƒμ„±λœ μš”μ†Œ λ…Έλ“œλŠ” μ•„λ¬΄λŸ° μžμ‹ λ…Έλ“œκ°€ μ—†λ‹€.
console.log($li.childNodes); // NodeList []

ν…μŠ€νŠΈ λ…Έλ“œ 생성

Element.prototype.createTextNode(text) λ©”μ„œλ“œλŠ” ν…μŠ€νŠΈ λ…Έλ“œλ₯Ό 생성해 λ°˜ν™˜
λ§€κ°œλ³€μˆ˜ textμ—λŠ” ν…μŠ€νŠΈ λ…Έλ“œμ˜ κ°’μœΌλ‘œ μ‚¬μš©ν•  λ¬Έμžμ—΄μ„ 인수둜 전달

39-54

// 2. ν…μŠ€νŠΈ λ…Έλ“œ 생성
const textNode = document.createTextNode('Banana');

ν…μŠ€νŠΈ λ…Έλ“œλŠ” μš”μ†Œ λ…Έλ“œμ˜ μžμ‹ λ…Έλ“œ. createTextNode λ©”μ„œλ“œλ‘œ μƒμ„±ν•œ ν…μŠ€νŠΈ λ…Έλ“œλŠ” ν™€λ‘œ μ‘΄μž¬ν•˜λŠ” μƒνƒœμ΄κΈ°μ— μš”μ†Œ λ…Έλ“œμ— μΆ”κ°€ν•˜λŠ” μ²˜λ¦¬κ°€ λ³„λ„λ‘œ ν•„μš”.

ν…μŠ€νŠΈ λ…Έλ“œλ₯Ό μš”μ†Œ λ…Έλ“œμ˜ μžμ‹ λ…Έλ“œλ‘œ μΆ”κ°€

Node.prototype.appendChild(childNode) λ©”μ„œλ“œλŠ” λ§€κ°œλ³€μˆ˜ childNodeμ—κ²Œ 인수둜 μ „λ‹¬ν•œ λ…Έλ“œλ₯Ό 이 λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ λ…Έλ“œμ˜ λ§ˆμ§€λ§‰ μžμ‹ λ…Έλ“œλ‘œ μΆ”κ°€

appendChild λ©”μ„œλ“œ 인수둜 createTextNode λ©”μ„œλ“œλ‘œ μƒμ„±ν•œ ν…μŠ€νŠΈ λ…Έλ“œλ₯Ό μ „λ‹¬ν•˜λ©΄ appendChild λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ λ…Έλ“œμ˜ λ§ˆμ§€λ§‰ μžμ‹ λ…Έλ“œλ‘œ ν…μŠ€νŠΈ λ…Έλ“œ 좔가됨

39-55

// 3. ν…μŠ€νŠΈ λ…Έλ“œλ₯Ό $li μš”μ†Œ λ…Έλ“œμ˜ μžμ‹ λ…Έλ“œλ‘œ μΆ”κ°€
$li.appendChild(textNode);

=> μš”μ†Œ λ…Έλ“œμ™€ ν…μŠ€νŠΈ λ…Έλ“œκ°€ λΆ€μž κ΄€κ³„λ‘œ 연결됨. κΈ°μ‘΄ DOM에 μΆ”κ°€λ˜μ§€λŠ” μ•Šμ€ μƒνƒœ
μš”μ†Œ λ…Έλ“œμ— μžμ‹ λ…Έλ“œκ°€ ν•˜λ‚˜λ„ μ—†λŠ” 경우, ν…μŠ€νŠΈ λ…Έλ“œλ₯Ό 생성해 μš”μ†Œ λ…Έλ“œμ˜ μžμ‹ λ…Έλ“œλ‘œ ν…μŠ€νŠΈ λ…Έλ“œλ₯Ό μΆ”κ°€ν•˜λŠ” 것보닀 textContent ν”„λ‘œνΌν‹°λ₯Ό μ‚¬μš©ν•˜λŠ” 편이 λ”μš± κ°„νŽΈ

39-56

// ν…μŠ€νŠΈ λ…Έλ“œλ₯Ό μƒμ„±ν•˜μ—¬ μš”μ†Œ λ…Έλ“œμ˜ μžμ‹ λ…Έλ“œλ‘œ μΆ”κ°€
$li.appendChild(document.createTextNode('Banana'));

// $li μš”μ†Œ λ…Έλ“œμ— μžμ‹ λ…Έλ“œκ°€ ν•˜λ‚˜λ„ μ—†λŠ” μœ„ μ½”λ“œμ™€ λ™μΌν•˜κ²Œ λ™μž‘ν•œλ‹€.
$li.textContent = 'Banana';

=> μš”μ†Œ λ…Έλ“œμ— μžμ‹ λ…Έλ“œκ°€ μžˆλŠ” 경우, μš”μ†Œ λ…Έλ“œμ˜ textContent ν”„λ‘œνΌν‹°μ— λ¬Έμžμ—΄μ„ ν• λ‹Ήν•˜λ©΄ μš”μ†Œ λ…Έλ“œμ˜ λͺ¨λ“  μžμ‹ λ…Έλ“œκ°€ 제거되고 ν• λ‹Ήν•œ λ¬Έμžμ—΄μ΄ ν…μŠ€νŠΈλ‘œ μΆ”κ°€λ˜λ―€λ‘œ μ£Όμ˜ν•΄μ•Ό 함

μš”μ†Œ λ…Έλ“œλ₯Ό DOM에 μΆ”κ°€

Node.prototype.appendChild λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•΄ ν…μŠ€νŠΈ λ…Έλ“œμ™€ λΆ€μž κ΄€κ³„λ‘œ μ—°κ²°ν•œ μš”μ†Œ λ…Έλ“œλ₯Ό #fruits μš”μ†Œ λ…Έλ“œμ˜ λ§ˆμ§€λ§‰ μžμ‹ μš”μ†Œλ‘œ μΆ”κ°€

39-57

// 4. $li μš”μ†Œ λ…Έλ“œλ₯Ό #fruits μš”μ†Œ λ…Έλ“œμ˜ λ§ˆμ§€λ§‰ μžμ‹ λ…Έλ“œλ‘œ μΆ”κ°€
$fruits.appendChild($li);

=> 이 κ³Όμ •μ—μ„œ λΉ„λ‘œμ†Œ μƒˆλ‘­κ²Œ μƒμ„±ν•œ μš”μ†Œ λ…Έλ“œκ°€ DOM에 좔가됨. 기쑴의 DOM에 μš”μ†Œ λ…Έλ“œλ₯Ό μΆ”κ°€ν•˜λŠ” μ²˜λ¦¬λŠ” 이 과정뿐.
DOM은 ν•œ 번 λ³€κ²½λ˜κ³ , μ΄λ•Œ λ¦¬ν”Œλ‘œμš°, λ¦¬νŽ˜μΈνŠΈκ°€ 싀행됨

39.6.4 볡수의 λ…Έλ“œ 생성과 μΆ”κ°€

39-58

<!DOCTYPE html>
<html>
  <body>
    <ul id="fruits"></ul>
  </body>
  <script>
    const $fruits = document.getElementById('fruits');

    ['Apple', 'Banana', 'Orange'].forEach((text) => {
      // 1. μš”μ†Œ λ…Έλ“œ 생성
      const $li = document.createElement('li');

      // 2. ν…μŠ€νŠΈ λ…Έλ“œ 생성
      const textNode = document.createTextNode(text);

      // 3. ν…μŠ€νŠΈ λ…Έλ“œλ₯Ό $li μš”μ†Œ λ…Έλ“œμ˜ μžμ‹ λ…Έλ“œλ‘œ μΆ”κ°€
      $li.appendChild(textNode);

      // 4. $li μš”μ†Œ λ…Έλ“œλ₯Ό #fruits μš”μ†Œ λ…Έλ“œμ˜ λ§ˆμ§€λ§‰ μžμ‹ λ…Έλ“œλ‘œ μΆ”κ°€
      $fruits.appendChild($li);
    });
  </script>
</html>

=> 3개의 μš”μ†Œ λ…Έλ“œ 생성해 DOM에 3번 μΆ”κ°€, DOM이 3번 λ³€κ²½λ˜λŠ” 것(λ¦¬ν”Œλ‘œμš°, 리페인트 3번 μ‹€ν–‰) => λΉ„νš¨μœ¨μ 
DOM을 λ³€κ²½ν•˜λŠ” 것은 높은 λΉ„μš©μ΄ λ“œλŠ” μ²˜λ¦¬μ΄λ―€λ‘œ, 가급적 횟수λ₯Ό μ€„μ΄λŠ” 편이 μ„±λŠ₯에 유리

39-59

μ»¨ν…Œμ΄λ„ˆ μš”μ†Œ μ‚¬μš©.
μ»¨ν…Œμ΄λ„ˆ μš”μ†Œ 미리 μƒμ„±ν•˜κ³ , DOM에 μΆ”κ°€ν•  3개의 μš”μ†Œ λ…Έλ“œλ₯Ό μ»¨ν…Œμ΄λ„ˆ μš”μ†Œμ— μžμ‹ λ…Έλ“œλ‘œ μΆ”κ°€ν•˜κ³ , μ»¨ν…Œμ΄λ„ˆ μš”μ†Œλ₯Ό #fruits μš”μ†Œμ— μžμ‹μœΌλ‘œ μΆ”κ°€ν•˜λ©΄ DOM은 ν•œ 번만 변경됨

<!DOCTYPE html>
<html>
  <body>
    <ul id="fruits"></ul>
  </body>
  <script>
    const $fruits = document.getElementById('fruits');

    // μ»¨ν…Œμ΄λ„ˆ μš”μ†Œ λ…Έλ“œ 생성
    const $container = document.createElement('div');

    ['Apple', 'Banana', 'Orange'].forEach((text) => {
      // 1. μš”μ†Œ λ…Έλ“œ 생성
      const $li = document.createElement('li');

      // 2. ν…μŠ€νŠΈ λ…Έλ“œ 생성
      const textNode = document.createTextNode(text);

      // 3. ν…μŠ€νŠΈ λ…Έλ“œλ₯Ό $li μš”μ†Œ λ…Έλ“œμ˜ μžμ‹ λ…Έλ“œλ‘œ μΆ”κ°€
      $li.appendChild(textNode);

      // 4. $li μš”μ†Œ λ…Έλ“œλ₯Ό μ»¨ν…Œμ΄λ„ˆ μš”μ†Œμ˜ λ§ˆμ§€λ§‰ μžμ‹ λ…Έλ“œλ‘œ μΆ”κ°€
      $container.appendChild($li);
    });

    // 5. μ»¨ν…Œμ΄λ„ˆ μš”μ†Œ λ…Έλ“œλ₯Ό #fruits μš”μ†Œ λ…Έλ“œμ˜ λ§ˆμ§€λ§‰ μžμ‹ λ…Έλ“œλ‘œ μΆ”κ°€
    $fruits.appendChild($container);
  </script>
</html>

=> DOM을 ν•œ 번만 λ³€κ²½ν•˜λ―€λ‘œ μ„±λŠ₯에 유리.

39-60

ν•˜μ§€λ§Œ λΆˆν•„μš”ν•œ μ»¨ν…Œμ΄λ„ˆ μš”μ†Œ(div)κ°€ DOM에 μΆ”κ°€λ˜λŠ” λΆ€μž‘μš©μ΄ 있음 => λ°”λžŒμ§ν•˜μ§€ μ•ŠμŒ

<ul id="fruits">
  <div>
    <li>apple</li>
    <li>banana</li>
    <li>orange</li>
  </div>
</ul>

DocumentFragment λ…Έλ“œλ₯Ό 톡해 ν•΄κ²°. DocumentFragment λ…Έλ“œλŠ” λ¬Έμ„œ, μš”μ†Œ, μ–΄νŠΈλ¦¬λ·°νŠΈ, ν…μŠ€νŠΈ λ…Έλ“œμ™€ 같은 λ…Έλ“œ 객체의 일쒅. λΆ€λͺ¨ λ…Έλ“œκ°€ μ—†μ–΄μ„œ κΈ°μ‘΄ DOMκ³ΌλŠ” λ³„λ„λ‘œ 쑴재.

μ»¨ν…Œμ΄λ„ˆ μš”μ†Œμ™€ 같이 μžμ‹ λ…Έλ“œλ“€μ˜ λΆ€λͺ¨ λ…Έλ“œλ‘œμ„œ λ³„λ„μ˜ μ„œλΈŒ DOM을 ꡬ성해 κΈ°μ‘΄ DOM에 μΆ”κ°€ν•˜κΈ° μœ„ν•œ μš©λ„λ‘œ μ‚¬μš©.

DocumentFragment λ…Έλ“œλŠ” κΈ°μ‘΄ DOMκ³ΌλŠ” λ³„λ„λ‘œ 쑴재. DocumentFragment λ…Έλ“œμ— μžμ‹ λ…Έλ“œλ₯Ό μΆ”κ°€ν•˜μ—¬λ„ κΈ°μ‘΄ DOMμ—λŠ” μ–΄λ– ν•œ 변경도 λ°œμƒν•˜μ§€ μ•ŠμŒ.
DocumentFragment λ…Έλ“œλ₯Ό DOM에 μΆ”κ°€ν•˜λ©΄ μžμ‹ μ€ 제거되고 μžμ‹ μ˜ μžμ‹ λ…Έλ“œλ§Œ DOM에 좔가됨

39-61

Document.prototype.createDocumentFragment λ©”μ„œλ“œλŠ” λΉ„μ–΄ μžˆλŠ” DocumentFragment λ…Έλ“œλ₯Ό μƒμ„±ν•˜μ—¬ λ°˜ν™˜

<!DOCTYPE html>
<html>
  <body>
    <ul id="fruits"></ul>
  </body>
  <script>
    const $fruits = document.getElementById('fruits');

    // DocumentFragment λ…Έλ“œ 생성
    const $fragment = document.createDocumentFragment();

    ['Apple', 'Banana', 'Orange'].forEach((text) => {
      // 1. μš”μ†Œ λ…Έλ“œ 생성
      const $li = document.createElement('li');

      // 2. ν…μŠ€νŠΈ λ…Έλ“œ 생성
      const textNode = document.createTextNode(text);

      // 3. ν…μŠ€νŠΈ λ…Έλ“œλ₯Ό $li μš”μ†Œ λ…Έλ“œμ˜ μžμ‹ λ…Έλ“œλ‘œ μΆ”κ°€
      $li.appendChild(textNode);

      // 4. $li μš”μ†Œ λ…Έλ“œλ₯Ό DocumentFragment λ…Έλ“œμ˜ λ§ˆμ§€λ§‰ μžμ‹ λ…Έλ“œλ‘œ μΆ”κ°€
      $fragment.appendChild($li);
    });

    // 5. DocumentFragment λ…Έλ“œλ₯Ό #fruits μš”μ†Œ λ…Έλ“œμ˜ λ§ˆμ§€λ§‰ μžμ‹ λ…Έλ“œλ‘œ μΆ”κ°€
    $fruits.appendChild($fragment);
  </script>
</html>
  • DocumentFragment λ…Έλ“œλ₯Ό μƒμ„±ν•˜κ³ 
  • DOM에 μΆ”κ°€ν•  μš”μ†Œ λ…Έλ“œλ₯Ό μƒμ„±ν•˜μ—¬
  • DocumentFragment λ…Έλ“œμ— μžμ‹ λ…Έλ“œλ‘œ μΆ”κ°€ν•˜κ³ 
  • DocumentFragment λ…Έλ“œλ₯Ό κΈ°μ‘΄ DOM에 μΆ”κ°€

μ‹€μ œλ‘œ DOM 변경이 λ°œμƒν•˜λŠ” 것은 ν•œ 번뿐(λ¦¬ν”Œλ‘œμš°, λ¦¬νŽ˜μΈνŠΈλ„ ν•œ 번 μ‹€ν–‰). μ—¬λŸ¬ 개의 μš”μ†Œ λ…Έλ“œλ₯Ό DOM에 μΆ”κ°€ν•˜λŠ” 경우, DocumentFragment λ…Έλ“œλ₯Ό μ‚¬μš©ν•˜λŠ” 것이 더 효율적

39.6.5 λ…Έλ“œ μ‚½μž…

λ§ˆμ§€λ§‰ λ…Έλ“œλ‘œ μΆ”κ°€

Node.prototype.appendChild λ©”μ„œλ“œλŠ” 인수둜 전달받은 λ…Έλ“œλ₯Ό μžμ‹ μ„ ν˜ΈμΆœν•œ λ…Έλ“œμ˜ λ§ˆμ§€λ§‰ μžμ‹ λ…Έλ“œλ‘œ DOM에 μΆ”κ°€.
λ…Έλ“œλ₯Ό μΆ”κ°€ν•  μœ„μΉ˜ μ§€μ •ν•  수 μ—†μŒ. μ–Έμ œλ‚˜ λ§ˆμ§€λ§‰ μžμ‹ λ…Έλ“œλ‘œ μΆ”κ°€.

39-62

<!DOCTYPE html>
<html>
  <body>
    <ul id="fruits">
      <li>Apple</li>
      <li>Banana</li>
    </ul>
  </body>
  <script>
    // μš”μ†Œ λ…Έλ“œ 생성
    const $li = document.createElement('li');

    // ν…μŠ€νŠΈ λ…Έλ“œλ₯Ό $li μš”μ†Œ λ…Έλ“œμ˜ λ§ˆμ§€λ§‰ μžμ‹ λ…Έλ“œλ‘œ μΆ”κ°€
    $li.appendChild(document.createTextNode('Orange'));

    // $li μš”μ†Œ λ…Έλ“œλ₯Ό #fruits μš”μ†Œ λ…Έλ“œμ˜ λ§ˆμ§€λ§‰ μžμ‹ λ…Έλ“œλ‘œ μΆ”κ°€
    document.getElementById('fruits').appendChild($li);
  </script>
</html>

μ§€μ •ν•œ μœ„μΉ˜μ— λ…Έλ“œ μ‚½μž…

Node.prototype.insertBefore(newNode, childNode) λ©”μ„œλ“œλŠ” 첫 번째 인수둜 전달받은 λ…Έλ“œλ₯Ό 두 번째 인수둜 전달받은 λ…Έλ“œ μ•žμ— μ‚½μž….

39-63

<!DOCTYPE html>
<html>
  <body>
    <ul id="fruits">
      <li>Apple</li>
      <li>Banana</li>
    </ul>
  </body>
  <script>
    const $fruits = document.getElementById('fruits');

    // μš”μ†Œ λ…Έλ“œ 생성
    const $li = document.createElement('li');

    // ν…μŠ€νŠΈ λ…Έλ“œλ₯Ό $li μš”μ†Œ λ…Έλ“œμ˜ λ§ˆμ§€λ§‰ μžμ‹ λ…Έλ“œλ‘œ μΆ”κ°€
    $li.appendChild(document.createTextNode('Orange'));

    // $li μš”μ†Œ λ…Έλ“œλ₯Ό #fruits μš”μ†Œ λ…Έλ“œμ˜ λ§ˆμ§€λ§‰ μžμ‹ μš”μ†Œ μ•žμ— μ‚½μž…
    $fruits.insertBefore($li, $fruits.lastElementChild);
    // Apple - Orange - Banana
  </script>
</html>

39-64

두 번째 인수둜 전달받은 λ…Έλ“œλŠ” λ°˜λ“œμ‹œ insertBefore λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ λ…Έλ“œμ˜ μžμ‹ λ…Έλ“œμ΄μ–΄μ•Ό ν•œλ‹€. κ·Έλ ‡μ§€ μ•ŠμœΌλ©΄ DOMException μ—λŸ¬ λ°œμƒ.

<!DOCTYPE html>
<html>
  <body>
    <div>test</div>
    <ul id="fruits">
      <li>Apple</li>
      <li>Banana</li>
    </ul>
  </body>
  <script>
    const $fruits = document.getElementById('fruits');

    // μš”μ†Œ λ…Έλ“œ 생성
    const $li = document.createElement('li');

    // ν…μŠ€νŠΈ λ…Έλ“œλ₯Ό $li μš”μ†Œ λ…Έλ“œμ˜ λ§ˆμ§€λ§‰ μžμ‹ λ…Έλ“œλ‘œ μΆ”κ°€
    $li.appendChild(document.createTextNode('Orange'));

    // 두 번째 인수둜 전달받은 λ…Έλ“œλŠ” λ°˜λ“œμ‹œ #fruits μš”μ†Œ λ…Έλ“œμ˜ μžμ‹ λ…Έλ“œμ΄μ–΄μ•Ό ν•œλ‹€.
    $fruits.insertBefore($li, document.querySelector('div'));
    // DOMException
  </script>
</html>

39-65

두 번째 인수둜 전달받은 λ…Έλ“œκ°€ null이면 첫 번째 인수둜 전달받은 λ…Έλ“œλ₯Ό insertBefore λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ λ…Έλ“œμ˜ λ§ˆμ§€λ§‰ μžμ‹ λ…Έλ“œλ‘œ μΆ”κ°€. appendChild λ©”μ„œλ“œμ²˜λŸΌ λ™μž‘

<!DOCTYPE html>
<html>
  <body>
    <ul id="fruits">
      <li>Apple</li>
      <li>Banana</li>
    </ul>
  </body>
  <script>
    const $fruits = document.getElementById('fruits');

    // μš”μ†Œ λ…Έλ“œ 생성
    const $li = document.createElement('li');

    // ν…μŠ€νŠΈ λ…Έλ“œλ₯Ό $li μš”μ†Œ λ…Έλ“œμ˜ λ§ˆμ§€λ§‰ μžμ‹ λ…Έλ“œλ‘œ μΆ”κ°€
    $li.appendChild(document.createTextNode('Orange'));

    // 두 번째 인수둜 전달받은 λ…Έλ“œκ°€ null이면 $li μš”μ†Œ λ…Έλ“œλ₯Ό #fruits μš”μ†Œ λ…Έλ“œμ˜ λ§ˆμ§€λ§‰ μžμ‹ λ…Έλ“œλ‘œ μΆ”κ°€
    $fruits.insertBefore($li, null);
  </script>
</html>

39.6.6 λ…Έλ“œ 이동

DOM에 이미 μ‘΄μž¬ν•˜λŠ” λ…Έλ“œλ₯Ό appendChild λ˜λŠ” insertBefore λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ DOM에 μΆ”κ°€ν•˜λ©΄ ν˜„μž¬ μœ„μΉ˜μ—μ„œ λ…Έλ“œλ₯Ό μ œκ±°ν•˜κ³  μƒˆλ‘œμš΄ μœ„μΉ˜μ— λ…Έλ“œλ₯Ό μΆ”κ°€. λ…Έλ“œκ°€ μ΄λ™ν•œλ‹€.

39-66

<!DOCTYPE html>
<html>
  <body>
    <ul id="fruits">
      <li>Apple</li>
      <li>Banana</li>
      <li>Orange</li>
    </ul>
  </body>
  <script>
    const $fruits = document.getElementById('fruits');

    // 이미 μ‘΄μž¬ν•˜λŠ” μš”μ†Œ λ…Έλ“œλ₯Ό 취득
    const [$apple, $banana] = $fruits.children;

    // 이미 μ‘΄μž¬ν•˜λŠ” $apple μš”μ†Œ λ…Έλ“œλ₯Ό #fruits μš”μ†Œ λ…Έλ“œμ˜ λ§ˆμ§€λ§‰ λ…Έλ“œλ‘œ 이동
    $fruits.appendChild($apple); // Banana - Orange - Apple

    // 이미 μ‘΄μž¬ν•˜λŠ” $banana μš”μ†Œ λ…Έλ“œλ₯Ό #fruits μš”μ†Œμ˜ λ§ˆμ§€λ§‰ μžμ‹ λ…Έλ“œ μ•žμœΌλ‘œ 이동
    $fruits.insertBefore($banana, $fruits.lastElementChild);
    // Orange - Banana - Apple
  </script>
</html>

39.6.7 λ…Έλ“œ 볡사

Node.prototype.cloneNode([deep: true | false]) λ©”μ„œλ“œλŠ” λ…Έλ“œμ˜ 사본을 생성해 λ°˜ν™˜.

λ§€κ°œλ³€μˆ˜ deep에 trueλ₯Ό 인수둜 μ „λ‹¬ν•˜λ©΄ λ…Έλ“œλ₯Ό κΉŠμ€ 볡사(deep clone)ν•˜μ—¬ λͺ¨λ“  μžμ† λ…Έλ“œκ°€ ν¬ν•¨λœ 사본을 생성
falseλ₯Ό 인수둜 μ „λ‹¬ν•˜κ±°λ‚˜ μƒλž΅ν•˜λ©΄ 얕은 볡사(shallow copy)ν•˜μ—¬ λ…Έλ“œ μžμ‹ λ§Œμ˜ 사본 생성. 얕은 λ³΅μ‚¬λ‘œ μƒμ„±λœ μš”μ†Œ λ…Έλ“œλŠ” μžμ† λ…Έλ“œλ₯Ό λ³΅μ‚¬ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ ν…μŠ€νŠΈ λ…Έλ“œλ„ μ—†μŒ

39-67

<!DOCTYPE html>
<html>
  <body>
    <ul id="fruits">
      <li>Apple</li>
    </ul>
  </body>
  <script>
    const $fruits = document.getElementById('fruits');
    const $apple = $fruits.firstElementChild;

    // $apple μš”μ†Œλ₯Ό 얕은 λ³΅μ‚¬ν•˜μ—¬ 사본을 생성. ν…μŠ€νŠΈ λ…Έλ“œκ°€ μ—†λŠ” 사본이 μƒμ„±λœλ‹€.
    const $shallowClone = $apple.cloneNode();
    // 사본 μš”μ†Œ λ…Έλ“œμ— ν…μŠ€νŠΈ μΆ”κ°€
    $shallowClone.textContent = 'Banana';
    // 사본 μš”μ†Œ λ…Έλ“œλ₯Ό #fruits μš”μ†Œ λ…Έλ“œμ˜ λ§ˆμ§€λ§‰ λ…Έλ“œλ‘œ μΆ”κ°€
    $fruits.appendChild($shallowClone);

    // #fruits μš”μ†Œλ₯Ό κΉŠμ€ λ³΅μ‚¬ν•˜μ—¬ λͺ¨λ“  μžμ† λ…Έλ“œκ°€ ν¬ν•¨λœ 사본을 생성
    const $deepClone = $fruits.cloneNode(true);
    // 사본 μš”μ†Œ λ…Έλ“œλ₯Ό #fruits μš”μ†Œ λ…Έλ“œμ˜ λ§ˆμ§€λ§‰ λ…Έλ“œλ‘œ μΆ”κ°€
    $fruits.appendChild($deepClone);
  </script>
</html>

39.6.8 λ…Έλ“œ ꡐ체

Node.prototype.replaceChild(newChild, oldChild) λ©”μ„œλ“œλŠ” μžμ‹ μ„ ν˜ΈμΆœν•œ λ…Έλ“œμ˜ μžμ‹ λ…Έλ“œλ₯Ό λ‹€λ₯Έ λ…Έλ“œλ‘œ ꡐ체함

첫 번째 λ§€κ°œλ³€μˆ˜ newChildμ—λŠ” ꡐ체할 μƒˆλ‘œμš΄ λ…Έλ“œλ₯Ό 인수둜 전달,
두 번째 λ§€κ°œλ³€μˆ˜ oldChildμ—λŠ” 이미 μ‘΄μž¬ν•˜λŠ” ꡐ체될 λ…Έλ“œλ₯Ό 인수둜 전달

oldChild λ§€κ°œλ³€μˆ˜μ— 인수둜 μ „λ‹¬ν•œ λ…Έλ“œλŠ”, replaceChild λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ λ…Έλ“œμ˜ μžμ‹ λ…Έλ“œμ΄μ–΄μ•Ό 함

즉, replaceChild λ©”μ„œλ“œλŠ” μžμ‹ μ„ ν˜ΈμΆœν•œ λ…Έλ“œμ˜ μžμ‹ λ…Έλ“œμΈ oldChild λ…Έλ“œλ₯Ό newChild λ…Έλ“œλ‘œ ꡐ체.
μ΄λ•Œ oldChild λ…Έλ“œλŠ” DOMμ—μ„œ 제거됨

39-68

<!DOCTYPE html>
<html>
  <body>
    <ul id="fruits">
      <li>Apple</li>
    </ul>
  </body>
  <script>
    const $fruits = document.getElementById('fruits');

    // κΈ°μ‘΄ λ…Έλ“œμ™€ ꡐ체할 μš”μ†Œ λ…Έλ“œλ₯Ό 생성
    const $newChild = document.createElement('li');
    $newChild.textContent = 'Banana';

    // #fruits μš”μ†Œ λ…Έλ“œμ˜ 첫 번째 μžμ‹ μš”μ†Œ λ…Έλ“œλ₯Ό $newChild μš”μ†Œ λ…Έλ“œλ‘œ ꡐ체
    $fruits.replaceChild($newChild, $fruits.firstElementChild);
  </script>
</html>

39.6.9 λ…Έλ“œ μ‚­μ œ

Node.prototype.removeChild(child) λ©”μ„œλ“œλŠ” child λ§€κ°œλ³€μˆ˜μ— 인수둜 μ „λ‹¬ν•œ λ…Έλ“œλ₯Ό DOMμ—μ„œ μ‚­μ œ.

인수둜 μ „λ‹¬ν•œ λ…Έλ“œλŠ” removeChild λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ λ…Έλ“œμ˜ μžμ‹ λ…Έλ“œμ΄μ–΄μ•Ό 함.

39-69

<!DOCTYPE html>
<html>
  <body>
    <ul id="fruits">
      <li>Apple</li>
      <li>Banana</li>
    </ul>
  </body>
  <script>
    const $fruits = document.getElementById('fruits');

    // #fruits μš”μ†Œ λ…Έλ“œμ˜ λ§ˆμ§€λ§‰ μš”μ†Œλ₯Ό DOMμ—μ„œ μ‚­μ œ
    $fruits.removeChild($fruits.lastElementChild);
  </script>
</html>