[learning javascript] chapter 18. 브라우저의 자바스크립트

브라우저의 자바스크립트

ES5와 ES6

문서 객체 모델

Simple HTML

Simple HTML

This is a simple HTML file.

This is as fancy as we'll get!

IDs (such as #content) are unique (there can only be one per page).

Classes (such as .callout) can be used on many elements.

</p>

A single HTML element can have multiple classes.

- 모든 노드에는 `nodeType`, `nodeName`프로퍼티가 있음
- `nodeType`은 그 노드가 어떤 타입인지 나타내는 정수
- 이 장에서는 HTML요소인 `Node.ELEMENT_NODE`(nodeType 1)과 보통 HTML 요소의 텍스트 컨텐츠로 쓰이는 `Node.TEXT_NODE`(nodeType 3)를 주로 설명함
- `document`에서 시작해 DOM 전체를 순회(traverse)하면서 콘솔에 출력하는 함수 예제
```javascript
function printDOM(node, prefix) {
    console.log(prefix + node.nodeName);
    for(let i=0; i<node.childNodes.length; i++) {
        printDOM(node.childNodes[i], prefix + '\t');
    }
}
printDOM(document, '');

용어 사용

get 메서드

DOM 요소 쿼리

DOM 요소 조작

새 DOM 요소 만들기

요소 스타일링

데이터 속성

이벤트

const removeHighlightActions = document.querySelectorAll(‘[data-aciton=”removeHighlihgts”]’); for(let a of removeHighlightActions) { a.addEventListener(‘click’, evt => { evt.preventDefault(); removeParaHighlights(); }); }

- 모든 요소에는 `addEventListener`라는 메소드가 있음 
- 이 메소드를 통해 이벤트가 일어났을 때 호출할 함수를 지정할 수 있음 
- 호출할 함수는 `Event`타입의 객체 하나만 매개변수로 받음 
- 이벤트 객체에는 해당 이벤트에 관한 정보가 모두 포함(clientX, clientY, target등)
- 이벤트 모델은 이벤트 하나에 여러가지 함수(핸들러)를 연결할 수 있도록 설계
- 기본 핸들러가 지정된 이벤트도 많아 기본 핸들러 동작을 막고 다른 동작으로 변경할 수 있음 
- 예를 들어 `<a>`태그에서 클릭이벤트는 링크호출을 하게 되어 있는데 이를 막고(preventDefault()) 다른 동작을 하게 할 수 있음 

#### 이벤트 버블링과 캡처링
- HTML은 계층적이기 때문에 이벤트를 한 곳에서만 처리해야 하는 것은 아님
- 버튼이벤트 처리시 해당 버튼의 부모나 부모의 부모에서 처리해도 됨 
- 여러 요소에서 이벤트 처리할 수 있다면 그 이벤트에 응답하는 기회는 어떤 순서로 주어지는가?
- 확인 방법 첫 번째로 가장 먼 조상부터 시작하는 방법인 캡처링이 있음 
- HTML에서 버튼은 `<div id="content">`에 들어있고 `<div id="content">`는 `<body>`에 들어있다고 하면 `<body>`도 버튼에서 일어난 이벤트를 `캡처`할 수 있음 
- 다른 방법은 이벤트가 일어난 요소에서 거슬로 올라가는 방법인 버블링이 있음 
- HTML5 이벤트 모델에서는 두 방법을 모두 지원하기 위해 먼저 해당 요소의 가장 먼 조상에서 시작해 해당 요소까지 내려온 다음, 다시 해당 요소에서 시작해 가장 먼 조상까지 거슬러 올라가는 방법을 택함 
- 이벤트 핸들러에는 다른 핸들러가 어떻게 호출될지 영향을 주는 세 가지 방법이 있음 
- 첫 번째는 가장 많이 쓰이느 `preventDefault`. 이벤트를 취소함.
- 두 번째는 `stopPropagation`. 이벤트를 현재 요소에서 끝내고 더이상 전달되지 않게 막음 
- 즉, 해당 요소에 연결된 이벤트 핸들러는 동작하지만 다른 요소에 연결된 이벤트 핸들러는 동작하지 않음 
- 세 번째는 `stopImmediatePropagation` 다른 이벤트 핸들러, 심지어 현재 요소에 연결된 이벤트 핸들러도 동작하지 않게 막음 
```html
<!doctype html>
<html>
    <head>
        <title>Event Propagation</title>
        <meta charset="utf-8">
    </head>
    <body>
        <div>
            <button>Click Me!</button>
        </div>
        <script>
            // 이벤트 핸들러를 만들어 반환 
            function logEvent(handlerName, type, cancel, stop, stopImmediate) {
                // 실제 이벤트 핸들러 
                return function(evt) {
                    if(cancel) evt.preventDefault();
                    if(stop) evt.stopPropagation();
                    if(stopImmediate) evt.stopImmediatePropagation();
                    console.log(`${type}: ${handlerName}` +
                        (evt.defaultPrevented ? '(canceled)' : ''));
                }
            }
            // 이벤트 핸들러를 요소에 추가 
            function addEventLogger(elt, type, action) {
                const capture = type === 'capture';
                elt.addEventListener('click', 
                    logEvent(elt.tagName, type, action === 'cancel', action === 'stop', action === 'stop!'), capture);
            }
            const body = document.querySelector('body');
            const div = document.querySelector('div');
            const button = document.querySelector('button');
            addEventLogger(body, 'capture');
            addEventLogger(body, 'bubble');
            addEventLogger(div, 'capture');
            addEventLogger(div, 'bubble');
            addEventLogger(button, 'capture');
            addEventLogger(button, 'bubble');
        </script>
    </body>
</html>

이벤트 카테고리

드래그 이벤트

포커스 이벤트

폼 이벤트

입력 장치 이벤트

미디어 이벤트

진행(progress) 이벤트

터치 이벤트

Ajax

const server = http.createServer(function(req, res) { res.setHeader(‘Content-Type’, ‘application/json’); res.setHeader(‘Access-Control-Allow-Origin’, ‘*’); res.end(JSON.stringify({ platform: process.platform, nodeVersion: process.version, uptime: Math.round(process.uptime()), })); });

const port = 7070; server.listen(port, function() { console.log(Ajax server started on port ${port}); });

- 참고사항 

테스트 진행을 원할하게 하기 위해 CORS체크를 비활성화하고 함 res.setHeader(‘Access-Control-Allow-Origin’, ‘*’);

- 다음 명령어로 서버 시작 

$ babel-node ajaxServer.js

- 문서 바디에 Ajax로 받아올 정보를 표시할 플레이스 홀더 생성 
```html
<div class="serverInfo">
    Server is running on <span data-replace="platform">???</span>
    with Node <span data-replace="nodeVersion">???</span>. It has
    been up for <span data-replace="uptime">???</span> seconds.
</div>

요약