diff --git a/2-ui/99-ui-misc/01-mutation-observer/article.md b/2-ui/99-ui-misc/01-mutation-observer/article.md index 3cf6f53977..40b6b5e872 100644 --- a/2-ui/99-ui-misc/01-mutation-observer/article.md +++ b/2-ui/99-ui-misc/01-mutation-observer/article.md @@ -1,82 +1,82 @@ -# Mutation observer +# 뮤테이션 옵저버 -`MutationObserver` is a built-in object that observes a DOM element and fires a callback when it detects a change. +`MutationObserver`는 DOM 요소를 관찰하다가 변경이 감지되면 콜백을 실행하는 내장 객체입니다. -We'll first take a look at the syntax, and then explore a real-world use case, to see where such thing may be useful. +먼저 문법을 알아본 다음 실제 사례를 보면서 뮤테이션 옵저버가 어디에 유용한지 살펴보겠습니다. -## Syntax +## 문법 -`MutationObserver` is easy to use. +`MutationObserver` 사용법은 간단합니다. -First, we create an observer with a callback-function: +먼저 콜백 함수를 넘겨 옵저버를 만듭니다. ```js let observer = new MutationObserver(callback); ``` -And then attach it to a DOM node: +그리고 만든 옵저버를 DOM 노드에 붙입니다. ```js observer.observe(node, config); ``` -`config` is an object with boolean options "what kind of changes to react on": -- `childList` -- changes in the direct children of `node`, -- `subtree` -- in all descendants of `node`, -- `attributes` -- attributes of `node`, -- `attributeFilter` -- an array of attribute names, to observe only selected ones. -- `characterData` -- whether to observe `node.data` (text content), +`config`는 '어떤 종류의 변경에 반응할지'를 나타내는 불린값 옵션이 담긴 객체입니다. +- `childList` -- `node`의 직계 자식에서 일어나는 변경 +- `subtree` -- `node`의 모든 자손에서 일어나는 변경 +- `attributes` -- `node`의 속성 변경 +- `attributeFilter` -- 선택한 속성만 관찰하도록 속성 이름을 담은 배열 +- `characterData` -- `node.data`(텍스트 콘텐츠)를 관찰할지 여부 -Few other options: -- `attributeOldValue` -- if `true`, pass both the old and the new value of attribute to callback (see below), otherwise only the new one (needs `attributes` option), -- `characterDataOldValue` -- if `true`, pass both the old and the new value of `node.data` to callback (see below), otherwise only the new one (needs `characterData` option). +이 외에 다음 옵션도 있습니다. +- `attributeOldValue` -- `true`이면 속성의 이전 값과 새 값을 모두 콜백에 전달하고(아래 참고) 그렇지 않으면 새 값만 전달함(`attributes` 옵션 필요) +- `characterDataOldValue` -- `true`이면 `node.data`의 이전 값과 새 값을 모두 콜백에 전달하고(아래 참고) 그렇지 않으면 새 값만 전달함(`characterData` 옵션 필요) -Then after any changes, the `callback` is executed: changes are passed in the first argument as a list of [MutationRecord](https://dom.spec.whatwg.org/#mutationrecord) objects, and the observer itself as the second argument. +실제 변경이 생길 때마다 `callback`이 실행됩니다. 이때 콜백 함수의 첫 번째 인수로 [MutationRecord](https://dom.spec.whatwg.org/#mutationrecord) 객체 목록이, 두 번째 인수로 옵저버 자신이 전달됩니다. -[MutationRecord](https://dom.spec.whatwg.org/#mutationrecord) objects have properties: +[MutationRecord](https://dom.spec.whatwg.org/#mutationrecord) 객체에는 다음과 같은 프로퍼티가 있습니다. -- `type` -- mutation type, one of - - `"attributes"`: attribute modified - - `"characterData"`: data modified, used for text nodes, - - `"childList"`: child elements added/removed, -- `target` -- where the change occurred: an element for `"attributes"`, or text node for `"characterData"`, or an element for a `"childList"` mutation, -- `addedNodes/removedNodes` -- nodes that were added/removed, -- `previousSibling/nextSibling` -- the previous and next sibling to added/removed nodes, -- `attributeName/attributeNamespace` -- the name/namespace (for XML) of the changed attribute, -- `oldValue` -- the previous value, only for attribute or text changes, if the corresponding option is set `attributeOldValue`/`characterDataOldValue`. +- `type` -- 뮤테이션 타입으로 다음 중 하나 + - `"attributes"`: 속성이 수정됨 + - `"characterData"`: 데이터가 수정됨. 텍스트 노드에 사용됨 + - `"childList"`: 자식 요소가 추가되거나 삭제됨 +- `target` -- 변경이 일어난 곳. `"attributes"` 뮤테이션이면 요소, `"characterData"` 뮤테이션이면 텍스트 노드, `"childList"` 뮤테이션이면 요소 +- `addedNodes/removedNodes` -- 추가되거나 삭제된 노드 +- `previousSibling/nextSibling` -- 추가되거나 삭제된 노드의 이전·다음 형제 노드 +- `attributeName/attributeNamespace` -- 변경된 속성의 이름과 (XML의) 네임스페이스 +- `oldValue` -- 이전 값. 속성이나 텍스트가 변경되었고 해당 옵션 `attributeOldValue`/`characterDataOldValue`가 설정된 경우에만 전달됨 -For example, here's a `
- // here's the code
+ // 여기에 코드가 들어갑니다.
let hello = "world";
...
```
-For better readability and at the same time, to beautify it, we'll be using a JavaScript syntax highlighting library on our site, like [Prism.js](https://prismjs.com/). To get syntax highlighting for above snippet in Prism, `Prism.highlightElem(pre)` is called, which examines the contents of such `pre` elements and adds special tags and styles for colored syntax highlighting into those elements, similar to what you see in examples here, on this page.
+가독성을 높이는 동시에 보기 좋게 꾸미기 위해 [Prism.js](https://prismjs.com/) 같은 자바스크립트 구문 강조(syntax highlighting) 라이브러리를 사이트에 사용해 본다고 가정하겠습니다. Prism에서 위 예시에 구문 강조를 적용하려면 `Prism.highlightElem(pre)`를 호출합니다. 이 메서드는 `pre` 요소의 내용을 검사해서 색을 입히는 특별한 태그와 스타일을 해당 요소 안에 추가합니다. 지금 보고 있는 이 페이지의 예시 코드와 비슷한 결과물이 만들어지죠.
-When exactly should we run that highlighting method? Well, we can do it on `DOMContentLoaded` event, or put the script at the bottom of the page. The moment our DOM is ready, we can search for elements `pre[class*="language"]` and call `Prism.highlightElem` on them:
+그렇다면 구문 강조 메서드는 정확히 언제 실행해야 할까요? `DOMContentLoaded` 이벤트에서 실행할 수도 있고 스크립트를 페이지 맨 아래에 넣을 수도 있습니다. DOM이 준비되면 `pre[class*="language"]`에 해당하는 요소를 찾아 `Prism.highlightElem`을 호출하면 됩니다.
```js
-// highlight all code snippets on the page
+// 페이지에 있는 코드 예시를 전부 강조 표시합니다.
document.querySelectorAll('pre[class*="language"]').forEach(Prism.highlightElem);
```
-Everything's simple so far, right? We find code snippets in HTML and highlight them.
+여기까진 문제 될 게 없습니다. HTML에서 코드 예시를 찾아 강조 표시하면 끝이죠.
-Now let's go on. Let's say we're going to dynamically fetch materials from a server. We'll study methods for that [later in the tutorial](info:fetch). For now it only matters that we fetch an HTML article from a webserver and display it on demand:
+이제 한 걸음 더 나아가 봅시다. 서버에서 자료를 동적으로 가져와야 한다고 해봅시다. 자료를 가져오는 메서드는 [튜토리얼 뒷부분](info:fetch)에서 다룰 예정이라 지금은 웹 서버에서 HTML로 된 글을 받아와 요청이 있을 때 화면에 표시한다는 점만 알면 됩니다.
```js
-let article = /* fetch new content from server */
+let article = /* 서버에서 새 콘텐츠를 가져옴 */
articleElem.innerHTML = article;
```
-The new `article` HTML may contain code snippets. We need to call `Prism.highlightElem` on them, otherwise they won't get highlighted.
+새로 받아온 `article` HTML엔 코드 예시가 들어 있을 수 있습니다. `Prism.highlightElem`을 호출하지 않으면 이 코드는 강조 표시되지 않습니다.
-**Where and when to call `Prism.highlightElem` for a dynamically loaded article?**
+**그럼 동적으로 불러온 글엔 `Prism.highlightElem`을 어디서, 언제 호출해야 할까요?**
-We could append that call to the code that loads an article, like this:
+다음처럼 글을 불러오는 코드 뒤에 호출을 덧붙일 수 있을 겁니다.
```js
-let article = /* fetch new content from server */
+let article = /* 서버에서 새 콘텐츠를 가져옴 */
articleElem.innerHTML = article;
*!*
@@ -162,38 +162,38 @@ snippets.forEach(Prism.highlightElem);
*/!*
```
-...But, imagine if we have many places in the code where we load our content - articles, quizzes, forum posts, etc. Do we need to put the highlighting call everywhere, to highlight the code in content after loading? That's not very convenient.
+그런데 글, 퀴즈, 게시판 글처럼 콘텐츠를 불러오는 곳이 코드 곳곳에 많다고 상상해 봅시다. 불러온 콘텐츠 속 코드를 강조 표시하려고 위와 같은 코드를 모든 곳에 붙여야 할까요? 그다지 편리한 방법이 아닙니다.
-And what if the content is loaded by a third-party module? For example, we have a forum written by someone else, that loads content dynamically, and we'd like to add syntax highlighting to it. No one likes patching third-party scripts.
+콘텐츠를 서드파티 모듈이 불러온다면 어떨까요? 예를 들어 다른 사람이 만든 게시판이 콘텐츠를 동적으로 불러오는데 여기에 구문 강조를 적용하고 싶을 수 있습니다. 서드파티 스크립트에 패치를 덧대는 일은 누구도 반기지 않습니다.
-Luckily, there's another option.
+다행히 다른 방법이 있습니다.
-We can use `MutationObserver` to automatically detect when code snippets are inserted into the page and highlight them.
+`MutationObserver`를 사용하면 코드 예시가 페이지에 삽입되는 순간을 자동으로 감지해 강조 표시할 수 있습니다.
-So we'll handle the highlighting functionality in one place, relieving us from the need to integrate it.
+이렇게 하면 강조 기능을 한곳에서 처리할 수 있어 통합 작업을 일일이 할 필요가 없어집니다.
-### Dynamic highlight demo
+### 동적 구문 강조 데모
-Here's the working example.
+동작하는 예시를 봅시다.
-If you run this code, it starts observing the element below and highlighting any code snippets that appear there:
+아래 코드를 실행하면 하위 요소를 관찰하기 시작해서 그곳에 나타나는 코드 예시를 강조 표시합니다.
```js run
let observer = new MutationObserver(mutations => {
for(let mutation of mutations) {
- // examine new nodes, is there anything to highlight?
+ // 강조 표시할 새 노드가 있는지 검사합니다.
for(let node of mutation.addedNodes) {
- // we track only elements, skip other nodes (e.g. text nodes)
+ // 요소(노드)만 추적하고 다른 노드(예: 텍스트 노드)는 건너뜁니다.
if (!(node instanceof HTMLElement)) continue;
- // check the inserted element for being a code snippet
+ // 삽입된 요소가 코드 예시인지 확인합니다.
if (node.matches('pre[class*="language-"]')) {
Prism.highlightElement(node);
}
- // or maybe there's a code snippet somewhere in its subtree?
+ // 서브트리 어딘가에 코드 예시가 있을 수 있으니 확인합니다.
for(let elem of node.querySelectorAll('pre[class*="language-"]')) {
Prism.highlightElement(elem);
}
@@ -207,67 +207,67 @@ let demoElem = document.getElementById('highlight-demo');
observer.observe(demoElem, {childList: true, subtree: true});
```
-Here, below, there's an HTML-element and JavaScript that dynamically fills it using `innerHTML`.
+바로 아래에 HTML 요소가 하나 있고 `innerHTML`을 사용해 이 요소를 동적으로 채우는 자바스크립트가 있습니다.
-Please run the previous code (above, observes that element), and then the code below. You'll see how `MutationObserver` detects and highlights the snippet.
+먼저 위 코드(해당 요소를 관찰함)를 실행한 다음 아래쪽 코드를 실행해 보세요. `MutationObserver`가 코드만 찾아내 강조 표시하는 모습을 볼 수 있습니다.
-A demo-element with id="highlight-demo", run the code above to observe it.
id="highlight-demo"가 붙은 데모 요소입니다. 위 코드를 실행해 이 요소를 관찰해 보세요.
let hello = "world!";
- .class { margin: 5px; }