Skip to content

Commit

Permalink
docs: DOM (39.4 ~ 39.6.2)
Browse files Browse the repository at this point in the history
  • Loading branch information
ccconac committed Jan 19, 2024
1 parent 6612380 commit 4f389a4
Showing 1 changed file with 115 additions and 0 deletions.
115 changes: 115 additions & 0 deletions docs/39_DOM/λ¬Έμ†Œν¬.md
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,121 @@ $elems.forEach((elem) => (elem.className = 'blue'));
</html>
```

## πŸ”Ž 4. λ…Έλ“œ 정보 취득

| ν”„λ‘œνΌν‹° | μ„€λͺ… |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| Node.prototype.nodeType | λ…Έλ“œ 객체의 μ’…λ₯˜, 즉 λ…Έλ“œ νƒ€μž…μ„ λ‚˜νƒ€λ‚΄λŠ” μƒμˆ˜λ₯Ό λ°˜ν™˜ν•˜λ©° μƒμˆ˜λŠ” Node에 μ €μž₯λ˜μ–΄ μžˆλ‹€. (ELEMENT_NODE: 1, TEXT_NODE:3, DOCUMENT_NODE: 9) |
| Node.prototype.nodeName | λ…Έλ“œ 이름을 λ¬Έμžμ—΄λ‘œ λ°˜ν™˜ν•œλ‹€. (μš”μ†Œ λ…Έλ“œ: UL/UI λ“±, ν…μŠ€νŠΈ λ…Έλ“œ: #text, λ¬Έμ„œ λ…Έλ“œ: #document) |

## πŸ”Ž 5. μš”μ†Œ λ…Έλ“œμ˜ ν…μŠ€νŠΈ μ‘°μž‘

### πŸ’¬ 1. nodeValue

> `Node.prototype.nodeValue` ν”„λ‘œνΌν‹°λŠ” 참쑰와 할당이 λͺ¨λ‘ κ°€λŠ₯ν•œ μ ‘κ·Όμž ν”„λ‘œνΌν‹°λ‹€. λ…Έλ“œ 객체의 nodeValue ν”„λ‘œνΌν‹°λ₯Ό μ°Έμ‘°ν•˜λ©΄ λ…Έλ“œ 객체의 κ°’<sup>ν…μŠ€νŠΈ λ…Έλ“œμ˜ ν…μŠ€νŠΈ</sup>을 λ°˜ν™˜ν•œλ‹€. λ”°λΌμ„œ, ν…μŠ€νŠΈ λ…Έλ“œκ°€ μ•„λ‹Œ λ¬Έμ„œ λ…Έλ“œλ‚˜ μš”μ†Œ λ…Έλ“œμ˜ nodeValue ν”„λ‘œνΌν‹°λ₯Ό μ°Έμ‘°ν•  경우 null을 λ°˜ν™˜ν•œλ‹€.
ν…μŠ€νŠΈ λ…Έλ“œμ˜ nodeValue ν”„λ‘œνΌν‹°μ— 값을 ν• λ‹Ήν•˜λ©΄ ν…μŠ€νŠΈλ₯Ό λ³€κ²½ν•  수 μžˆλŠ”λ°, λ‹€μŒκ³Ό 같은 μˆœμ„œμ˜ μ²˜λ¦¬κ°€ ν•„μš”ν•˜λ‹€.

1. ν…μŠ€νŠΈλ₯Ό λ³€κ²½ν•  μš”μ†Œ λ…Έλ“œλ₯Ό μ·¨λ“ν•œ λ‹€μŒ, μ·¨λ“ν•œ μš”μ†Œ λ…Έλ“œμ˜ ν…μŠ€νŠΈ λ…Έλ“œλ₯Ό νƒμƒ‰ν•œλ‹€. ν…μŠ€νŠΈ λ…Έλ“œλŠ” μš”μ†Œ λ…Έλ“œμ˜ μžμ‹ λ…Έλ“œμ΄λ―€λ‘œ firstChild ν”„λ‘œνΌν‹°λ₯Ό μ‚¬μš©ν•΄ νƒμƒ‰ν•œλ‹€.
2. νƒμƒ‰ν•œ ν…μŠ€νŠΈ λ…Έλ“œμ˜ nodeValue ν”„λ‘œνΌν‹°λ₯Ό μ‚¬μš©ν•΄ ν…μŠ€νŠΈ λ…Έλ“œμ˜ 값을 λ³€κ²½ν•œλ‹€.

```html
<!doctype html>
<html>
<body>
<div id="foo">Hello</div>
</body>
<script>
const $textNode = document.getElementById('foo').firstChild; // 1.
$textNode.nodeValue = 'World'; // 2.
console.log($textNode.nodeValue); // World
</script>
</html>
```

### πŸ’¬ 2. textContent

> `Node.prototype.textContent` ν”„λ‘œνΌν‹°λŠ” μš”μ†Œ λ…Έλ“œμ˜ ν…μŠ€νŠΈμ™€ λͺ¨λ“  μžμ† λ…Έλ“œμ˜ ν…μŠ€νŠΈλ₯Ό λͺ¨λ‘ μ·¨λ“ν•˜κ±°λ‚˜ λ³€κ²½ν•˜λŠ” μ ‘κ·Όμž ν”„λ‘œνΌν‹°μ΄λ‹€. μš”μ†Œ λ…Έλ“œμ˜ textContent ν”„λ‘œνΌν‹°λ₯Ό μ°Έμ‘°ν•˜λ©΄ μš”μ†Œ λ…Έλ“œμ˜ μ½˜ν…μΈ  μ˜μ—­ λ‚΄<sup>μ‹œμž‘ νƒœκ·Έμ™€ μ’…λ£Œ νƒœκ·Έ 사이</sup>의 ν…μŠ€νŠΈλ₯Ό λͺ¨λ‘ λ°˜ν™˜ν•œλ‹€. μ΄λ•Œ, HTML λ§ˆν¬μ—…μ€ λ¬΄μ‹œλœλ‹€.
만일 μš”μ†Œ λ…Έλ“œμ˜ μ½˜ν…μΈ  μ˜μ—­μ— μžμ‹ μš”μ†Œ λ…Έλ“œκ°€ μ—†κ³  ν…μŠ€νŠΈλ§Œ μ‘΄μž¬ν•œλ‹€λ©΄ `firstChild.nodeValue`와 `textContent` ν”„λ‘œνΌν‹°λŠ” 같은 κ²°κ³Όλ₯Ό λ°˜ν™˜ν•˜λ―€λ‘œ `textContent`λ₯Ό μ‚¬μš©ν•˜λŠ” 편이 μ½”λ“œκ°€ 더 κ°„λ‹¨ν•˜λ‹€. πŸ‘€

μš”μ†Œ λ…Έλ“œμ˜ textContent ν”„λ‘œνΌν‹°μ— λ¬Έμžμ—΄μ„ ν• λ‹Ήν•˜λ©΄ μš”μ†Œ λ…Έλ“œμ˜ λͺ¨λ“  μžμ‹ λ…Έλ“œκ°€ 제거되고 ν• λ‹Ήν•œ λ¬Έμžμ—΄μ΄ ν…μŠ€νŠΈλ‘œ μΆ”κ°€λœλ‹€. μ΄λ•Œ ν• λ‹Ήν•œ λ¬Έμžμ—΄μ— HTML λ§ˆν¬μ—…μ΄ ν¬ν•¨λ˜μ–΄ μžˆλ”λΌλ„ λ¬Έμžμ—΄ κ·ΈλŒ€λ‘œ μΈμ‹λ˜μ–΄ ν…μŠ€νŠΈ 취급을 ν•˜λ―€λ‘œ _HTML λ§ˆν¬μ—…μ΄ νŒŒμ‹±λ˜μ§€ μ•ŠλŠ”λ‹€._

```html
<!doctype html>
<html>
<body>
<div id="foo">Hello</div>
<div id="bar">Hello <span>world!</span></div>
</body>
<script>
const $foo = document.getElementById('foo');
console.log($foo.textContent === $foo.firstChild.nodeValue); // true
console.log(document.getElementById('bar').textContent); // Hello World!
</script>
</html>
```

`textContent` ν”„λ‘œνΌν‹°μ™€ μœ μ‚¬ν•œ λ™μž‘μ„ ν•˜λŠ” `innerText` ν”„λ‘œνΌν‹°κ°€ μžˆλŠ”λ° λ‹€μŒκ³Ό 같은 이유둜 μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” 것이 μ’‹λ‹€.

- innertText ν”„λ‘œνΌν‹°λŠ” CSS에 μˆœμ’…μ μ΄λ‹€. (e.g. CSS에 μ˜ν•΄ λΉ„ν‘œμ‹œλ‘œ μ§€μ •λœ μš”μ†Œ λ…Έλ“œμ˜ ν…μŠ€νŠΈλ₯Ό λ°˜ν™˜ν•˜μ§€ μ•ŠμŒ)
- innerText ν”„λ‘œνΌν‹°λŠ” CSSλ₯Ό κ³ λ €ν•΄μ•Ό ν•˜λ―€λ‘œ textContent ν”„λ‘œνΌν‹°λ³΄λ‹€ λŠλ¦¬λ‹€.

## πŸ”Ž 6. DOM μ‘°μž‘

> DOM μ‘°μž‘<sup>DOM manipulation</sup>은 μƒˆλ‘œμš΄ λ…Έλ“œλ₯Ό μƒμ„±ν•˜μ—¬ DOM에 μΆ”κ°€ν•˜κ±°λ‚˜ κΈ°μ‘΄ λ…Έλ“œλ₯Ό μ‚­μ œ λ˜λŠ” κ΅μ²΄ν•˜λŠ” 것을 λ§ν•œλ‹€.
### πŸ’¬ 1. innerHTML λ©”μ„œλ“œ

> `Element.prototype.innerHTML` ν”„λ‘œνΌν‹°λŠ” μ ‘κ·Όμž ν”„λ‘œνΌν‹°λ‘œμ„œ μš”μ†Œ λ…Έλ“œμ˜ μ½˜ν…μΈ  μ˜μ—­<sup>μ‹œμž‘ νƒœκ·Έμ™€ μ’…λ£Œ νƒœκ·Έ 사이</sup> 내에 ν¬ν•¨λœ λͺ¨λ“  HTML λ§ˆν¬μ—…μ„ λ¬Έμžμ—΄λ‘œ λ°˜ν™˜ν•œλ‹€. 취득과 λ³€κ²½ λͺ¨λ‘ κ°€λŠ₯ν•˜λ‹€.
innerHTML ν”„λ‘œνΌν‹°μ— ν• λ‹Ήν•œ HTML λ§ˆν¬μ—… λ¬Έμžμ—΄μ€ λ Œλ”λ§ 엔진에 μ˜ν•΄ νŒŒμ‹±λ˜μ–΄ μš”μ†Œ λ…Έλ“œμ˜ μžμ‹μœΌλ‘œ DOM에 λ°˜μ˜λœλ‹€. μ΄λ•Œ μ‚¬μš©μžλ‘œλΆ€ν„° μž…λ ₯받은 데이터<sup>untrusted input data</sup>λ₯Ό κ·ΈλŒ€λ‘œ innerHTML ν”„λ‘œνΌν‹°λ₯Ό ν• λ‹Ήν•˜λŠ” 것은 **크둜슀 μ‚¬μ΄νŠΈ μŠ€ν¬λ¦½νŒ… 곡격<sup>XSS: Cross-Site Scripting Attacks</sup>에 μ·¨μ•½ν•˜λ―€λ‘œ μœ„ν—˜ν•˜λ‹€.**

λ˜ν•œ, μš”μ†Œ λ…Έλ“œμ˜ innerHTML ν”„λ‘œνΌν‹°μ— HTML λ§ˆν¬μ—… λ¬Έμžμ—΄μ„ ν• λ‹Ήν•  경우 μš”μ†Œ λ…Έλ“œμ˜ λͺ¨λ“  μžμ‹ λ…Έλ“œλ₯Ό μ œκ±°ν•˜κ³  ν• λ‹Ήν•œ HTML λ§ˆν¬μ—… λ¬Έμžμ—΄μ„ νŒŒμ‹±ν•΄ DOM을 λ³€κ²½ν•œλ‹€λŠ” 단점이 μžˆλ‹€. 즉, _기쑴의 μžμ‹ λ…Έλ“œκΉŒμ§€ λͺ¨λ‘ μ œκ±°ν•œ ν›„ λ‹€μ‹œ μ²˜μŒλΆ€ν„° μƒˆλ‘­κ²Œ μžμ‹ λ…Έλ“œλ₯Ό 생성해 DOM에 λ°˜μ˜ν•΄ νš¨μœ¨μ μ΄μ§€ μ•Šλ‹€._

#### ✨ HTML μƒˆλ‹ˆν‹°μ œμ΄μ…˜<sup>HTML sanitization</sup>

> μ‚¬μš©μžλ‘œλΆ€ν„° μž…λ ₯받은 데이터에 μ˜ν•΄ λ°œμƒν•  수 μžˆλŠ” 크둜슀 μ‚¬μ΄νŠΈ μŠ€ν¬λ¦½νŒ… 곡격을 μ˜ˆλ°©ν•˜κΈ° μœ„ν•΄ 잠재적 μœ„ν—˜μ„ μ œκ±°ν•˜λŠ” κΈ°λŠ₯을 λ§ν•œλ‹€. DOMPurify λΌμ΄λΈŒλŸ¬λ¦¬λŠ” μ•„λž˜μ™€ 같이 잠재적 μœ„ν—˜μ„ λ‚΄ν¬ν•œ HTML λ§ˆν¬μ—…μ„ μ‚΄κ· <sup>sanitization</sup>ν•˜μ—¬ 잠재적 μœ„ν—˜μ„ μ œκ±°ν•œλ‹€.
```javascript
DOMPurify.sanitize('<img src="x" onerror="alert(document.cookie)">');
```

### πŸ’¬ 2. insertAdjacentHTML λ©”μ„œλ“œ

> `Element.prototype.insertAdjacentHTML(position, DOMString)` λ©”μ„œλ“œλŠ” κΈ°μ‘΄ μš”μ†Œλ₯Ό μ œκ±°ν•˜μ§€ μ•ŠμœΌλ©΄μ„œ μœ„μΉ˜λ₯Ό 지정해 μƒˆλ‘œμš΄ μš”μ†Œλ₯Ό μ‚½μž…ν•œλ‹€. μ΄λ•Œ 두 번째 인수둜 μ „λ‹¬ν•œ HTML λ§ˆν¬μ—… λ¬Έμžμ—΄μ„ νŒŒμ‹±ν•˜κ³  κ·Έ 결과둜 μƒμ„±λœ λ…Έλ“œλ₯Ό 첫 번째 인수둜 μ „λ‹¬ν•œ μœ„μΉ˜μ— μ‚½μž…ν•΄ DOM에 λ°˜μ˜ν•œλ‹€.
첫 번째 인수둜 전달할 수 μžˆλŠ” λ¬Έμžμ—΄μ€ `beforebegin, afterbegin, beforeend, afterend` 4가지닀.

![](https://velog.velcdn.com/images/gnsdh8616/post/85d046ee-0b99-4cd8-80c6-4a409005d3f4/image.png)

`insertAdhacentHTML` λ©”μ„œλ“œλŠ” κΈ°μ‘΄ μš”μ†Œμ— 영ν–₯을 주지 μ•Šκ³  μƒˆλ‘­κ²Œ μ‚½μž…λ  μš”μ†Œλ§Œμ„ νŒŒμ‹±ν•΄ μžμ‹ μš”μ†Œλ‘œ μΆ”κ°€ν•˜λ―€λ‘œ `innerHTML` ν”„λ‘œνΌν‹°λ³΄λ‹€ 효율적이고 λΉ λ₯΄λ‹€. 단, HTML λ§ˆν¬μ—… λ¬Έμžμ—΄μ„ νŒŒμ‹±ν•˜λ―€λ‘œ 크둜슀 μ‚¬μ΄νŠΈ μŠ€ν¬λ¦½νŒ… 곡격에 μ·¨μ•½ν•˜λ‹€.

```html
<!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>
```

## πŸ‘€ REFERENCE

λͺ¨λ˜ μžλ°”μŠ€ν¬λ¦½νŠΈ Deep Dive 39μž₯ DOM

0 comments on commit 4f389a4

Please sign in to comment.