document

primav·2024년 9월 20일

Javascript

목록 보기
6/14
post-thumbnail

DOM Node

document는 브라우저에서 실행되는 프론트 웹 애플리케이션에서 이용할 수 있는 내장 객체로 브라우저에 출력되는 HTML 문서 자체를 지칭하는 객체이다.

document에 HTML 문서가 파싱되어 만들어진 다양한 DOM 노드 객체가 만들어지며, 코드에서 document 객체를 이용하여 이 노드에 접근해 다양한 작업을 한다.

  • 요소 노드 - 태그를 지칭하는 노드
  • 속성 노드 - 태그의 속성을 지칭하는 노드
  • 텍스트 노드 - 태그의 바디에 작성된 글을 지칭하는 노드
  • 주석 노드 - 문서의 주석을 지칭하는 노드

Node selector

HTML 문서의 태그를 지칭하는 DOM 노드를 선택하여 그 노드에 있는 값을 획득하거나 그 노드에 값을 출력해 주어야 한다.

자바스크립트에서 원하는 노드를 선택하는 기능이 있어야 하는데 이 부분을 노드 선택자라고 한다.

  • getElementById()

    id 값을 이용하여 획득하는 방법
let oneNode = document.getElementById('one')
  • getElementsByTagName()

    태그명을 이용하여 태그명에 해당되는 노드를 획득하는 함수
    함수의 반환 값 : 획득한 노드 객체 여러개가 담겨있는 HTMLColleciton 객체
let divNodes = document.getElementsByTagName('div')
  • getElementsByClassName()

    태그와 상관없이 CSS에 의해 동일한 화면 효과가 적용된 노드를 획득하는 경우이다.
    이 클래스 명이 선언된 ㅁ든 노드 객체가 HTMLCollection 타입으로 반환된다.
let enableNodes = document.getElementsByTagName('enable')
  • getElementsByName()

    태그에 name 속성을 설정하고 . 그값으로 노드를 획득하는 함수이다.
    반환 값은 HTMLCollection 이다.
let idInput = document.getElementsByName('id')

querySelector() vs querySelectorAll()

두 함수는 모두 document 객체 혹은 element 객체의 함수이다.

  • document - HTML 문서 자체를 지칭
    (document.querySelector() - 전체
    HTML 문서내의 원하는 노드)
  • element - HTML 문서내의 특정 노드를 지칭
    (element.querySelector() - 특정 노드 하위에 있는 노드 중 조건에 맞는 노드)
querySelector()querySelectorAll()
조건에 맞는 첫 노드를 반환조건에 맞는 모든 노드 배열로 반환

innterHTML vs innerText

노드 객체 하위에 선언된 자식 노드를 이용할 때 사용한다. (동적으로 변경 가능)

innerHTMLinnerText
어떤 노드의 하위에 선언된 모든 구성 요소텍스트 노드만 포함
HTML parser가 파싱을 함 (태그를 태그로 인지)문자열 내에 태그가 있더라도 태그로 인지x 문자열로 인지o (태그가 화면에 출력!!)

Node 이용

속성 이용 함수

노드의 속성 값을 획득하거나 변경, 삭제해야하는 경우가 있다.

함수설명
getAttribute()노드의 속성 값 획득
setAttribute()노드의 속성 값 변경
removeAttribute()노드의 속성 삭제
hasAttribute()노드에 속성이 있는지 판단
console.log(link.href) // http://www.google.com
console.log(link.getAttribute('href') // http://www.google.com

타겟팅과 버블링

이벤트가 발생한 노드를 찾아들어가는 것을 타겟팅이라고 한다.
중첩 구조에서 여러 노드에서 이벤트 핸들러를 등록하게 되는 경우가 있다.

노드는 트리구조로 구성되고, 트리구조의 여러 노드에 이벤트 핸들러가 등록되면 실행 순서를 신경써야하거나 이벤트 실행을 취소 시켜야 하는 경우가 있다.

💡 캡쳐링 & 버블링

  • 캡쳐링 - 이벤트가 발생했을 때 상위 노드부터 하위노드로 이벤트 전파되는 단계
  • 버블링 - 이벤트 발생한 노드부터 상위 노드로 이벤트 전파되는 단계

하나의 이벤트가 발생하면, 캡처링과 버블링을 거치면서 여러 노드에 등록된 이벤트 핸들러가 실행되는데, 이때 캡처링 단계에서 실행될 것인지, 버블링 단계에서 실행될 것인지를 제어할 수 있다.

➡️ addEventListener() 사용

addEventListener(type, listener, useCapture)
// 3번째 매개변수 --> true/false
// false - 버블링 단계에서 이벤트 처리됨
// true - 캡처링 단계에서 이벤트 처리됨 
// 기본 값은 false

이벤트 중단

이벤트를 중단시키는 방법은 preventDefault()stopProgation() 함수를 이용하는 방법이 있다.

preventDefault()

노드에 기본으로 등록된 이벤트가 처리되지 않게 하기 위해서 사용된다.

link1.addEventListener('click' function(e) {
  console.log('link click..')
  e.prevaentDefault()
})

stopPropagation()

노드에 발생한 이벤트는 캡처링과 버블링 단계를 거쳐 여러 이벤트 핸들러가 실행될 수 있는데 stopPropagation()은 이 캡처링과 버블링을 중단시키는 함수이다.

스타일 속성 이름

자바스크립트에서 노드에 적용된 스타일 값을 획득하거나 변경해야하는 경우가 있다.

이름 표기 (css vs js)

  • CSS
    대소문자를 구분하지 않으므로 두 단어가 연결될 때 -로 두 단어를 연결하는 snake case 규칙을 따른다.

  • JS
    대소문자를 구분하므로 두 단어가 연결될때 첫글자를 대문자로 하는 camel case 규칙을 따른다.

  • ex (CSS --> JS)
    border-color - borderColor
    font-size - fontSize

스타일 이용 - node.style vs getComputedStyle()

node.style

❗️node tree에 유지되는 css 정보는 inline 스타일만 유지된다!
이때는 노드 트리에 css 정보가 딸려오므로 js에서 node.style을 사용 가능하다.

✔️ inline 스타일 사용


  <head>
    <style>
      #area2 {
        width: 200px;
        height: 200px;
        background-color: red;
      }
      .my-style {
        width: 200px;
        height: 200px;
        background-color: blue;
      }
    </style>
  </head>
  <body>
    <div
      id="area1"
      style="width: 200px; height: 200px; background-color: green"
    ></div>
    <div id="area2"></div>
    <div id="area3" class="my-style"></div>
    <script src="main.js"></script>
  </body>
let area1 = document.getElementById("area1");
let area2 = document.getElementById("area2");
let area3 = document.getElementById("area3");

console.log(area1.style.width);
console.log(area2.style.width);
console.log(area3.style.width);

이런 코드를 진행하면 첫번째 노드인 area1만 로그에 찍히고 나머지는 찍히지 않는데 이유가 무엇일까?

왼쪽 그림과 같이 inline 스타일은 js에서 노드 트리에 접근할 때 스타일이 유지되어 가져올 수 있지만, 오른쪽 그림과 같이 외부에서 선언된 css 스타일은 노드 트리에 스타일이 없어 가져올 수가 없다.

❗️ 외부에서 선언된 css 스타일은 DOM Node Tree에 올라가지 않아서 Node.style.?를 진행할 수가 없다.

그렇다면 이렇게 외부에 선언된 css 스타일을 사용하고 싶다면 어떻게 해야할까?
getComputedStyle() 함수를 사용하면 외부 스타일을 이용할 수 있다.

이 함수를 사용하면 Dom Node를 가져오는 거

getComputedStyle()

style 프로퍼티는 태그 내에서 style로 지정한 스타일만 이용할 수 있다.

외부에서 정의해서 적용된 스타일을 획득하고자 한다면 style 속성을 이용할 수 없으며 getComputedStyle() 함수를 이용해 주어야 한다.

console.log(getComputedStyle(area2).width) // 200px

innerHTML / innerText 단점

HTML 파일에서 파싱(HTML 파서를 이용)을 진행하여 JS Node 객체로 변환한 후 css 파일에 접근하여 돔 트리가 만들어지는 것이 일반적인 방법이다.

이때 만약 innerHTML / innerText 를 사용하게 된다면 노드를 추가할 때마다 전체 노드에 접근하여 돔 트리를 만들어 내므로 성능 면에서 매우 안좋아진다. 특히, 여러 노드를 반복적으로 추가하거나 갱신해야하는 상황에서 innerHTML 을 사용하면 DOM 트리가 계속해서 재구성되기 때문에 성능 저하가 발생한다.

이를 방지하기 위해서는 개별적으로 노드 객체를 생성한 후, 한꺼번에 DOM에 추가하는 방법을 사용하는 것이 좋다.

✔️ JS에서 따로 노드 객체를 생성한 후 연결하기

한 덩어리들이 하나하나 추가가 되는 경우에는 innerHTML 을 사용하여 노드를 추가하는 것 보다 따로 노드를 추가하는 것이 좋다.

그렇다면 개별적으로 노드 객체를 어떻게 생성하는가?
아래의 함수들을 사용하면 쉽게 노드 객체를 생성, 삭제할 수 있다.

Node 추가

HTML 문서에 새로운 노드를 추가하는 방법은 innerHTML을 사용할 수 있다.
이 방식은 코드에서 문자열을 추가하고, 이 문자열을 브라우저에서 노드로 만드는 방식이다.
이렇게 진행하면 복잡한 구조의 노드를 추가하거나 동적으로 변경하면서 추가하기 불편하다.

➡️ document 객체에는 자바스크립트 코드에서 노드 객체를 직접 만들고 추가할 수 있는 함수를 제공한다.

❗️ DOM Node를 획득하는 방법이 innerHTML/innerText 라면 body 속 모든 노드를 가져온 다음에 필요한 부분을 바꾸고 다시 수정된 전체 노드를 반환하기 때문에 불필요하다.

노드 객체 생성

  • createElement() - 요소 노드 생성
  • createAttribute() - 속성 노드 생성
  • createTextNode() - 텍스트 노드 생성

appendChild() - 노드 추가

노드 객체는 노드 트리로 구성되므로, 어떤 노드를 다른 노드에 추가해서 화면을 구성할 때 사용하는 함수이다.

insertBefore() - 노드 추가

appendChild() 함수를 이용하면 새로 추가하는 노드는 마지막 부분에 추가가 된다.

새로운 노드를 특정 위치에 추가하고 싶다면 insertBefore() 함수를 이용하여 첫번째 매개변수에는 새로 추가하고자 하는 노드를, 두번째 매개변수는 추가되는 위치를 지정한다.

list.insertBefore(newItem, list.childNodes[0]) // 추가하고자 하는 노드 & 추가되는 위치

removeChild() - 노드 삭제

특정 노드를 삭제하고 싶을 때 사용하는 함수이다.
부모노드에서 자식 노드를 삭제하기 위한 함수로, 매개변수에 삭제하고 싶은 노드를 지정해주면 된다.

newItem.addEventListener('click', function() {
	console.log('11')
  	list.removeChild(this)
}                        

0개의 댓글