TIL_DOM의 접근과 수정, Event

DOM

1. Dom tree

  1. 문서노드 (Document Node)
  2. 요소노드 (Element Node)
  3. 속성노드 (Attribute Node)
  4. 텍스트노드 (Text Node)

2. DOM Query (접근)

  • 실무에서는 잘 사용X -> but, 제이쿼리/앵귤러등을 활용하는 기본원리는 같음 (기본 이론)
  • 여러개를 가지고 올때는 ‘유사배열 객체’로 반환
  • 따라서 여러개 중, 특정 하나를 가지고 오고 싶다면 [0] 인덱스값 설정해주어야
  • 선택하여 어트리뷰트를 변경할 수는 있으나, 아예 마크업되지 않은 어트리뷰트를 추가할순 X –> setAttribute로 가능

    1) 하나 선택

  • document.getElementById(id)
  • document.querySelector(cssSelector)

2) 여러개 선택

  • document.getElementsByClassName(class)
  • document.getElementsByTagName(tagName)
  • document.querySelectorAll(selector) : Non-live*

3. DOM Traversing (탐색)

  • parentNode: 부모 노드 탐색 (자식까지 포함)
  • firstChild / lastChild: 자식 노드 탐색
  • previousSibling / nextSibling: 형제 노드 탐색

주의

  • 단, 코드가독성을 위한 줄바꿈, 인덴트까지 자식으로 여김
  • 1) jQuery: .prev()와 jQuery: .next()를 사용
  • 2) 자식 노드가 있는지 (hasChildNodes)확인 후 적용

[참고] JQeury를 사용하는 이유*

  • Cross browsing
  • Live 객체에 대한 고민 필요X -> 사용 편의성
  • 서로가 긴밀하게 연결되어 있어 Html,CSS가 바뀌는순간 다 로직을 변경해줘야한다는 불편함

4. DOM Manipulation (조작)

1) 텍스트 노드 조작

  • nodeValue : 텍스트노드의 유일한 프로퍼티

2) 어트리뷰트 노드 조작

  1. className
    -어트리뷰트가 존재하지 않을 시, 생성하고 지정된 값 설정.
    -여러개일 경우, 공백으로 구분된 문자열 반환 (split(‘’)사용 배열 변경하여 사용)

  2. hasAttribute(attribute)

  3. getAttribute(attribute) -> 문자열 반환
  4. setAttribute(attribute, value) -> 어트리뷰트와 값을 설정

[참고]*

HTML의 attribute가 객체화 됐을 떄 property로 모두 1:1 매핑되는 것은 아님.
이런 때에는 getAttribute(attribute)하면 attribute의 ‘값’을 반환

3) HTML 콘텐츠 조작

콘텐츠
:<오픈></클로징>태그 안에 있는 모든 것 (태그, 텍스트)

  1. textContent
    -마크업을 포함시켜도 텍스트로 인식
  2. innerText
    -CSS순종적(느림, visibility:hidden반환X),비표준 -> 잘 사용X (비추)
  3. innerHTML
    -textContent와 달리 태그의 기능을 가진 콘텐츠로 변경 가능
    -XSS위험: 사용자의 입력을 innerHTML로 받으면 X (입력문구에 스크립트가 있는지 걸러줘야함)

동기식 vs 비동기식 처리모델 (Synchronous vs Asynchronous processing model)

  1. 동기식: 코딩하기 편하고, 직관적이나 순차적으로 실행되므로 대기시간이 소요
  2. 비동기식: 대기시간이 없어 빠르나 순차적X (코딩 어렵고 직관적X)

비동기

  1. Event(대부분)
  2. Timer함수 (eg: setTimeout, interval…)
  3. Ajax

Event Binding (3가지)

1) 이벤트 핸들러

  • 이벤트 프로퍼티에 함수를 할당하는 방식
  • 자바스크립트를 html Attribute로 할당 (섞여있어서 비추)

    2) 전통적 이벤트 핸들러

  • 자바스크립트와 html을 분리엔 성공
  • but, 하나의 이벤트 당, 하나의 함수만 할당할 수 있음
  • btn.onclick이 호출문이되므로 인자를 전달할 수 X(엄청난 단점)

    3) Dom Level 2 Event Listener

  • addEventListener(‘click’, 함수명): 대상 요소에 이벤트 바인딩, 해당 이벤트가 발생할때 실행될 콜백함수를 지정
  • 콜백함수는 정의만 (함수명()를 써서 호출문 X, 따라서 인자 전달X)
  • 인자전달 하고싶다면: 함수를 하나 더 만들어 콜백함수 내부에 그 함수를 호출하는 식으로 가능
  • 콜백함수의 인자엔 기본으로 브라우저가 이벤트객체 (이벤트 정보)가 암묵적으로 전달
  • 하나의 이벤트에 하나 이상의 핸들러 추가 가능
  • ie9 이상 (ie8이하는 attachEvent함수 사용)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    //인자전달을 하기위한 콜백함수 내부에서 그 함수를 호출하는 방식 예
    var MIN_USER_NAME_LENGTH = 2; // 이름 최소 길이
    var elem = document.getElementById('username');
    var msg = document.getElementById('message');
    function checkUserNameLength(n) {
    if(elem.value.length < n) {
    msg.innerHTML = '이름은 ' + n + '자 이상이어야 합니다';
    } else {
    msg.innerHTML = '';
    }
    }
    elem.addEventListener('blur', function() {
    checkUserNameLength(MIN_USER_NAME_LENGTH);
    });

핸들러 함수 내부의 this

기본적으로 콜백함수 내의 this는 전역객체(window)이나, addEventListener함수에서 지정한 이벤트 핸들러 내부의 this는 바인딩된 요소 임 즉, 호출한 객체

Event 프로퍼티

1) Event.target, Event.currentTarget

  • 이벤트를 발생시킨 요소
  • 이벤트 핸들러 함수 내의 this - addEventListener를 호출한 요소가 바인딩
  • 이벤트 핸들러 함수 내에서 currentTarget과 this는 언제나 일치한다.

2) Event.cancelable

  • 태그가 가진 기본 동작을 중단할 수 있는가?
  • 할수있다고 판단되면, event.preventDafault 메소드 사용
  • Ajax사용할때 a태그 기능 삭제할때 자주 사용

Event Delegation(위임)

  • 동적으로 li요소가 추가될 때, 아직 추가되지 않은 요소는 이벤트 핸들러 못씀 (DOM에 없으므로)
  • 이런 때 버블링 사용, 상위요소에 핸들러를 달아줌
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    <!DOCTYPE html>
    <html>
    <body>
    <ul id="parent-list">
    <li id="post-1">Item 1</li>
    <li id="post-2">Item 2</li>
    <li id="post-3">Item 3</li>
    <li id="post-4">Item 4</li>
    <li id="post-5">Item 5</li>
    <li id="post-6">Item 6</li>
    </ul>
    <div id="msg">
    <script>
    var msg = document.getElementById('msg');
    document.getElementById('parent-list').addEventListener('click', function (e) {
    console.log('[target]: ' + e.target);
    console.log('[target.nodeName]: ' + e.target.nodeName);
    // list item이면 그중에서 LI인것만 이라고 필터링 해줌
    if (e.target && e.target.nodeName == 'LI') {
    msg.innerHTML = 'li#' + e.target.id + ' was clicked!';
    }
    });
    </script>
    </body>
    </html>

오늘의 느낀점

  • 이제 javascript만을 다루던 이론을 벗어나, html과 연계된 이론으로 진입. 고로, 아직 정확하게 자리잡히지 않은 개념들 때문에 더욱 혼동이 올수 있음.
  • 그때 그때 검색해보자! 일단은 검색을 할 수 있는 단계(~가 있었던것같은데?)라고 머리에 잔상을 남기는 게 중요할 듯
  • 포스팅만 계속해서 보다보니 아무래도 읽었던 부분이라고 그냥 넘어가는 일이 생기고 하는 것같다. 좀더 꼼꼼하게 읽도록 한뒤 이제는 다른 책으로도 익혀봐야겠다 (인사이드 자바스크립트 주문!)