성장을 위한 기록

문서 객체 모델 DOM 본문

FE (Front End) (구)/javascript

문서 객체 모델 DOM

B_Tae 2022. 2. 10. 23:27

*제 개인적인 정리이기 때문에 다소 설명이 모호할 수 있습니다.
또한 "html,css,자바스크립트 do it" 책에 내용이 다소 포함되어 있습니다.

문서 객체 모델(DOM)

문서 객체 모델

document object model으로 자바스크립트를 이용하여 웹 문서에 접근하고 제어할 수 있도록 객체를 사용해 웹 문서를 체계적으로 정리하는 방법이다.

웹 문서를 하나의 객체로 정의하고 그 문서를 이루는 텍스트, 이미지, 표 등을 각각 객체로 정의한다.

 

DOM 트리

요소를 부모와 자식 구조로 표시하면 나무 형태가 된다 하여 DOM트리라 불르고, 가지처럼 갈라져 나간 항목을 노드라 말한다. html노드는 뿌리에 해당되기 때문에 루트(root) 노드라고 한다.
또한 관계에 따라 부모 노드에는 자식 노드가 있고 같은 부모 노드를 가지고 있는 형제 노드가 있다.

<!DOCTYPE  html>
<html  lang="en">
<head>
<meta  charset="UTF-8">
<meta  http-equiv="X-UA-Compatible"  content="IE=edge">
<meta  name="viewport"  content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>안녕하세요</h1>
<p>저는 텍스트 입니다.</p>
</body>
</html>

위 소스를 예로 들면 html 밑에 head와 body가 있있고 그 자식으로 각각 meta, title과 h1,p로 가지가 뻗어 나간다.

DOM을 구성하는 기본 원칙
모든 html태그는 요소 노드, 텍스트 내용은 텍스트 노드, 속성은 속성 노드, 주석은 주석 노드라 말한다.

 

요소에 접근하고 속성 가져오기

자바스크립트에서는 요소에 접근하고 속성을 가져올 수 있는데,

문서에 원하는 요소를 집어 내는 것을 접근한다고 볼 수 있다.
대표적으로 getElement(s)By, querySelector이 있다.

 

getElementBy

CSS에서 스타일을 각각 구분하기 위해 class, id, 태그 등을 선택자로 구분하여 정의했다. 여기서도 마찬가지로 선택자에 따라 접근하는 방법이 다르다.


기본형

요소명.getElementById("id명)"

html태그에서 id 선택자에 접근하기 위한 메서드이다. 문서에서 id명은 하나만 사용가능하므로 단수형태이다.

 


기본형

요소명.getElementsByClassName("class 명")

class 선택자에 접근하기 위한 메서드이다. class 선택자는 여러 요소에 사용할 수 있음으로 2개 이상의 반환 값이 나올 수 있다. 그래서 getElements라는 복수형을 사용한다.
이때는 배열 형식으로 반환되고 인덱스 값을 통해 배열처럼 사용은 가능하지만 배열은 아니다.

 


기본형

요소명.getElementsByTagName("태그명")

id나 class를 사용하지 않은 태그에 접근하기 위해 사용하는 메서드이다. 마찬가지로 2개 이상의 반환 값이 나올 수 있으며로 복수형 getElements를 사용했다.


 

getElement(s)By 메서드는 HTMLCollection 객체로 요소 즉 p나 a형태의만 저장된다.

 

querySelector

텍스트나 속성 노드까지 자유롭게 제어하기 위해서 사용하는 메서드이다.
반환하는 값이 id와 같이 하나라면 querySelector()를 사용하고 class나 태그 이름처럼 여러 값이 반환된다면 querySelectorAll()을 사용한다.


기본형

노드.querySelector(선택자) // querySelector("#hading")
노드.querySelectorAll(선택자 또는 태그) // querySlectorAll(".bright")

주석에 작성된 것 처럼 선택자나 태그를 작성할 때 CSS와 동일한 방식으로 #이나 점을 이용하여 작성한다.


querySelector메서드에 경우 노드나 노드 리스트를 반환한다. 노드 리스트에 경우 마찬가지로 배열과 비슷한 형태를 이룬다.

 

 

요소에 내용이나 속성을 가져오고 수정하는 프로퍼티, 메서드

 

웹 요소에 내용을 수정하는 프로퍼티

가장 쉬운 방법으로는 innerText, innerHTML 프로퍼티를 이용하는 방법이다.

 

기본형
요소명.innerText = 내용
요소명.innerHTML = 내용

 

두 방법에 차이점은 HTML에 경우 HTML 태그도 반영하여 표시할 수 있다는 점이다.
예를 들어 내용 부분에 "<em> 안녕하세요</em>" 이렇게 작성한다면
innerText 프로퍼티에 경우 태그까지 포함하여 "<em> 안녕하세요</em>" 이렇게 작성이되고
innerHTML 프로퍼티에 경우 태그를 반영하여 안녕하세요이렇게 표기가 된다.

속성을 가져오거나 수정하는 메서드

기본형
getAttribute("속성명"
setAttribute("속성명", "값"

setAttribute() 메서드에 경우 속성에 값이 지정되어 있다면 새로운 속성값으로 수정하고, 속성이 없다면 새로 추가한다.

DOM에서 이벤트 처리

자바스크립트에서 함수를 활용하여 이벤트를 처리 할 수 있다.
이때 함수가 간단하다면 요소에 직접 연결하여 사용할 수 있고,
함수를 이름으로 사용해 연결 할 수도 있다.

const cup = document.querySelector("#cup");
cup.onclick = function(){....} // 함수 이름을 지정해 연결 할 수 있다

 

DOM의 event 객체

DOM에는 이벤트 정보를 저장하는 다양한 event객체가 있다.

 

event 프로퍼티 (/표시는 둘 중 하나만 표기)

종류 설명
altKey 이벤트 발생 시 alt키를 눌렀는지 불린 값으로 반환
button 마우스에서 누른 버튼의 키값을 반환
charCode 키보드 이벤트가 발생 시 어떤 키를 눌렀는지 유니코드 값으로 반환
clientX/Y 이벤트가 발생한 가로/세로 위치 반환
ctrlKey 이벤트 발생 시 ctrl키를 눌렀는지 불린 값으로 반환
pageX/Y 현재 문서 기준으로 이벤트가 발생한 가로/세로 위치 반환
screenX/Y 현재 화면 기준으로 이벤트가 발생한 가로/세로 위치 반환
shiftKey 이벤트 발생 시 shift키를 눌렀는지 불린 값으로 반환
target 이벤트가 최초 발생한 대상을 반환
timeStamp 이벤트가 발생한 시간을 반환
type 발생한 이벤트 이름을 반환
which 키보드 관련 이벤트 발생시 키의 유니코드 값 반환
 

event 메서드

종류 설명
preventDefault 이벤트를 취소할 수 있는 경우 취소

 

addEventListener() 메서드

DOM을 함수와 연결하는 방법과 역할은 동일하지만, 더 많이 사용되고 몇 가지 이점이 있다.

 

기본형
요소, addEventListener(이벤트, 함수, 캡처 여부);

 

이벤트 - 이벤트 유형을 지정한다. 단 onclick> click과 같이 on을 붙이지 않고 사용

 

함수 - 이벤트 발생시 실행할 함수나 명령을 지정하고 함수를 정의할 때 event 객체를 인수로 받는다.

 

캡처 여부 - 이벤트를 캡처할 것인지 여부 false가 기본값으며 버블링(DOM의 자식 노드에서 부모 노드로 전달)을 한다는 의미이며, true 값은 캡처링(DOM의 부모 노드에서 자식 노드로 전달)을 한다는 의미이다.

const cup = document.querySelctor("#cup") ;

cup.onclick = function(event){ .....} // 기본적인 DOM에 함수 연결
cup.addEventlistener("click", function(){....}) // addEvnetListener을 이용 

 

위 두 방식에 결과는 함수가 동일하다면 같다. 역할은 동일하지만 여러 이유로 addEventlistener이 현대적이다는 평가를 받고 있는데, 그 중 가장 중요한게 한 요소에 여러 이벤트 처리기를 연결 할 수 있다는 점이다.

 

const cup = document.querySelctor("#cup") ;

cup.onclick = function(event){ .....} // 기본적인 DOM에 함수 연결
cup.onclick = function(event){,,,,,,} // 다른 함수를 연결

 

이 소스에 경우 같은 이벤트 발생시 실행할 명령이 2가지이다. 이럴 경우 기존에 읽었던 첫 번째 함수 명령은 초기화 되고, 두 번째 다른 함수의 명령만 실행하게 된다.

 

const cup = document.querySelctor("#cup") ;

cup.addEventlistener("click", function(){....}) // addEvnetListener을 이용 
cup.addEventlistener("click", function(){,,,,,}) // 다른 함수 연결

 

이 소스 즉 addEventListener메서드를 이용할 경우 두 함수의 명령을 다 실행 할 수 있다는 이점이 있다.

추가적으로 기존에 사용한 addEventListener메서드가 있다면, removeEventListener메서드를 통해 삭제할 수 있다는 장점도 있다.

다만, addEventListener를 사용 못하는 브라우저가 있는데, 이때는 attachEvent메소드를 사용하면 해결이 가능하다.
따라서 이런 경우를 방지하려면 조건문을 통해 구분을 해주면 좋은데 라이브러리를 이용하면 이 부분은 알아서 해준다. (참고로 attachEvent메소드에서 이벤트는 on을 붙여 작성한다)

 

CSS 속성 접근하기

자바스크립트를 통해 스타일 속성값을 변경할 수 있다.

 

기본형과 예시

document.요소명.style.속성명 

const cup = document.querySelctor("#cup") ;
cup.style.color = "blue"; // 변수 선언 없으 document를 직접 입력할 수 있다. 

여기서 color와 같은 단어는 그냥 작성하지만 background-color와 같이 하이픈(-)이 있는 속성은 backgroundColor와 같이 붙이고 대문자로 구분한다.

DOM에 노드 추가, 삭제

클릭 시 나타나는 이벤트에 경우 CSS에서 display 속성을 통해 실행 할 수 있지만 DOM트리에 새로운 노드를 추가하여 실행하는 방법이 있다.

노드를 추가하게 되면 요소 노드만 추가가 된다. 따라서 텍스트 노드나 속성 노드도 추가해야한다. 예시로 img 노드를 추가하게 되면 따라오는 src alt인 속성 노드가 필요하다.

 

노드를 추가하는 방법

  1. 요소 노드 생성
  2. 텍스트 또는 속성 노드 생성
  3. 요소 노드와 텍스트 또는 속성 노드를 연결(자식 노드로 연결)
  4. 요소 노드를 문서에 있는 부모 노드와 연결

 

요소 노드 생성 방법

document.createElement(노드명) 의 형태에 createElement() 메소드를 사용한다.
p 노드를 만들려면 노드명 부분에 "p"를 작성하면 된다.

텍스트 노드 또는 속성 노드 생성 방법

텍스트와 속성은 다른 메서드를 사용한다.
텍스트 노드 - createTextNode()메서드를 사용하며 document.createTextNode("여기에 작성하세요")형태로 사용하면 된다.


속성 노드 - createAttribute()메서드를 사용하며

let srcNode = document.createTextNode("src");
srcNode.value = "images/practice.jpg" ;

이런 형식으로 어떤 속성을 사용할 것인지 속성값은 무엇인지 작성하면 된다.

노드 연결 방법

텍스트나 요소 노드에 연결과 속성 노드에 연결은 다른 메서드를 사용한다.

텍스트 또는 요소 노드 - appendChild()메서드를 사용하며 부모노드.appendChild(자식노드)형태로 사용하면 된다.
속성 노드 연결 - setAttributeNode()메서드를 사용하며, 요소명.setAttributeNode(속성노드)형태를 사용한다.

 

예시 소스

//생략된 <div id = sample> 태그 안에 p요소와 텍스트 추가하기
let ele = document.createElement("p") ; // p 요소 노드 생성
let tex = document.createTextNode("이것은 예시입니다.") // 텍스트 노드 생성
ele.appendChild(tex) ; // 생성된 텍스트 노드를 p 요소 노드와 연결
document.querySelector("#sample").appendChild(ele); // 생략된 div요소와 p요소 노드 연결

// 생략된 <div id = smaple> 태그 안에 img 요소와 속성 추가하기
let newImg = document.createElement("img"); // img 요소 생성
let srcNode = document.createAttribute("src"); // src 속성 노드 생성
let altNode = document.createAttribute("alt"); // alt 속성 노드 생성
srcNode.value = "images/sample.jpg" ; // src 속성 노드 값 할당
altNode.value = "샘플 이미지"; // alt 속성 노드 값 할당
newImg.setAttributeNode(srcNode); // src 속성 노드 img 요소 노드와 연결
newImg.setAttributeNode(altNode); // alt 속성 노드 img 요소 노드와 연결
document.queryselector("#sample").appendChild(newImg); div 요소와 img 요소 연결

 

노드 삭제 방법

노드 삭제할 때는 removeChild()메서드를 사용한다. 다만 삭제할 때는 부모 노드에서 삭제를 하기 때문에, 삭제할 노드가 있다면 부모 노드를 찾아야한다.

parentNode , childNode 프로퍼티

parentNode프로퍼티는 부모 노드를 찾는 역할이며
childNode 프로퍼티는 자식 노드를 찾는 역할이다.

삭제할 때 부모를 찾는 parentNode프로퍼티를 사용하고 노드.parentNode형태로 사용한다. 이 값을 콘솔창에 입력하면 부모 노드를 찾을 수 있다.

removeChild() 메서드

말그대로 자식 노드를 삭제하는 역할이며 부모노드.removeChild(자식노드)형태로 사용한다.

Comments