DOM(Document Object Model)

Jeenie /·2021년 4월 23일
0
post-thumbnail

웹 페이지는 DOM 이라는 모든 요소를 객체로 사용할수 있는 형식으로 작성된다. 웹 페이지의 모든 것이 객체로 이루어져 있기에 자바스크립트로 제어하는 것이 가능하다.

<html>
	<h3>닐스</h3> //자바스크립트 조작으로 인해 h3 태그는 보이지 않게 된다.
</html>
document.queryselector("h3").style.visibility='hidden'

위의 코드를 보면 자바스크립트로 웹 페이지를 제어한다. 이렇게 웹 페이지를 일일히 수정하는 것이 아닌 자바스크립트 코드로 조작이 가능하게 하는 방식이 DOM 모델이다.

document는 웹문서 자체를 나타내는 DOM 객체중에 하나이다. 웹문서 자체에 접근을 할때 항상 루트객체가 되는 객체이다.

DOM 트리

웹문서를 DOM 으로 표현할때는 트리형식으로 표현을 한다. html의 요소를 노드와 가지로 표현을 한다. 또한 DOM에서는 모든 html 요소들을 객체로 본다. 그렇기에 모든 노드들을 부모노드와 자식노드로 구분을한다. 이때 DOM 트리에서는 html 요소 외에도 요소내에 이미, 텍스트등 모든 것들을 노드로 간주하여 표현한다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <title>DOM 알아보기</title>
    <meta charset="UTF-8">
</head>
<body>
    <h1>DOM이란?</h1>
    <p><strong>Document Object Model</strong>의 줄임말입니다.</p>
</body>
</html>


이처럼 위의 html 코드를 DOM 트리로 나타낸 예제이다. 정리하면 DOM 트리에서는 다음과 같이 표현합니다.

  • 웹 문서의 태그는 요소(element)노드로 표헌한다.
  • 태그가 품고있는 텍스트는 해당 요소의 자식노드로 표현된다.(text 노드)
  • 태그의 속성은 모두 해당 요소노드의 자식노드로 표현한다. (attribute 노드)
  • 주석은 주석노드로 표현한다.

맨 위의 루트는 모든 노드가 시작되는 노드이기에 루트노드라고 합니다. 그리고 특정노드에서 위에 붙어있는 노드가 부모노드, 밑에 있는 노드가 자식노드입니다. 웹문서를 DOM 트리형식으로 보면 자바스크립트에서 원하는 요소에 어떻게 접근할지 쉽게 생각할수 있습니다.

DOM Element 접근하기

자바스크립트에서 html 문서를 조작할때는 자바스크립트로 html 요소에 접근해야합니다. 이를 DOM요소에 접근한다 라고 합니다.

DOM Element에 접근하는 방법

css에는 선택자(selector)라는 개념이 있습니다. html 요소의 스타일을 선택하여 수정할때 css 선택자를 이용합니다. 마찬가지로 자바스크립트에서도 요소에 접근할때 같은 방식으로 접근 합니다. 선택자를 가지고 접근 하는 방법에는 여러가지 방법이 있습니다.

  1. DOM 요소의 id를 선택자로 접근

    getElementbyid() 함수는 자바스크립트에서 요소의 id를 가지고 접근하게 해주는 함수입니다.

    <div id="container">
    	<h1 id="heading">에디오피아 게뎁</h1>
    	<div id="prod-img">
    </div>
    document.getElementbyid("heading")
    //<h1 id="heading">에디오피아 게뎁</h1>을 출력

    이렇게 요소의 id를 가지고 접근하여 해당 요소를 제어 및 변경하는 것이 가능합니다.

  2. DOM 요소를 class 값으로 접근

    getElementsbyClassName() 함수는 요소의 class 값을 가지고 접근하게 해주는 함수입니다.

    해당 함수는 class로 접근하기에 해당 클래스를 가진 모든 요소에 접근이 가능하다. 즉, 복수로 접근이 가능합니다. 그렇기에 HTMLCollection이라는 자료형식으로 값을 출력합니다.

    <p>
    2차 세계대전 이후 설립된 <span class="accent">게뎁농장</span>은 유기농 인증 농장으로 여성의 고용 창출과 지역사회 발전에 기여하며 3대째 이어져 내려오는 오랜 역사를 가진 농장입니다. 
    게뎁 농장은 <span class="accent">SCAA 인증</span>을 받은 커피 품질관리 실험실을 갖추고 있어 철처한 관리를 통해 스페셜티커피를 생산합니다.
    </p>
    document.getElementsByClassName("accent")
    //HTMLCollection(2) htmlcollection이라는 자료형식으로 출력, htmlcollection은
    //배열과 비슷하다고 생각하면 됩니다.
  1. DOM 요소를 태그 이름으로 접근

    getElementsByTagName() 함수는 id나 class 선택자가 아닌 태그 자체에 접근이 가능하게 해주는 함수입니다. 태그이름으로 접근하기에 복수의 태그요소에 접근이 가능합니다.

    <h2 class="bright">Information</h2>
    <p>2차 세계대전 이후 설립된 <span class="accent">게뎁농장</span>은 유기농 인증 농장으로 여성의 고용 창출과 지역사회 발전에 기여하며 3대째 이어져 내려오는 오랜 역사를 가진 농장입니다. 
    게뎁 농장은 <span class="accent">SCAA 인증</span>을 받은 커피 품질관리 실험실을 갖추고 있어 철처한 관리를 통해 스페셜티커피를 생산합니다.</p>
    <h2>Flavor Note</h2>
    <p class="bright">은은하고 다채로운 꽃향, 망고, 다크 체리, 달달함이 입안 가득.</p>
    document.getElementsByTagName("h2")
    //HTMLCollection(2) 마찬가지로 HTMLCollection 자료구조로 출력한다.
  2. DOM 요소를 다양한 방법으로 접근

    querySelector()함수는 하나의 함수로 모든 선택자를 이용하여 요소에 접근이 가능하게 해주는 함수입니다. 즉, 태그이름, id, class 모든 선택자 이용이 가능합니다.

    querySelectorAll() 함수는 선택자를 가진 태그가 복수개일 경우, 해당 선택자를 가진 모든 요소에 접근이 가능하게 해주는 함수입니다.

    id를 이용할때는 #을, 클래스를 이용할때는 이름앞에 .(점) 을 붙여주면 됩니다. 태그이름은 그대로 사용하면 됩니다.

    document.queryselector("#heading")
    //<h1 id="heading">에디오피아 게뎁</h1> 출력
    
    document.queryselectorAll(".accent")
    //NodeList(2) queryselectorAll 함수로 접근할 경우 HTMLCollection이 아닌
    //NodeList라는 형태의 자료구조를 출력한다. 마찬가지로 배열과 비슷한 방식이다.

getElementById 함수와 querySelector 함수의 차이

getElementByid, getElementsByClass, getElementsByTagName 이 함수들은 함수의 이름처럼 요소 노드까지만 접근이 가능합니다. 하지만 queryselector 함수는 요소노드 뿐만아니라 요소노드가 가진 텍스트노드, 속성노드에까지 모두 접근이 가능합니다.

Element의 태그속성에 접근하여 수정하기

이번에는 DOM element가 아닌 element의 속성노드에 접근하는 방법을 알아봅니다.

getAttribute()함수, setAttribute() 함수- HTML의 태그 속성을 가져오거나 수정하는 함수

위의 두함수는 (get)속성을 가져오고, (set) 가져온 속성을 수정하는 함수 입니다.

<div id="prod-img">
		<img src="images/coffee-pink.jpg" alt="에디오피아 게뎁">
</div>
document.queryselector("#prod-img > img").getAttribute("src")
// "images/coffee-pink.jpg" 지정한 element의 속성값을 가져와 출력한다. 
// > 은 자식 선택자로 해당 노드의 자식노드를 가리킬때 사용한다.
document.queryselector("#prod-img > img").setAttribute("src","images/coffee-blue.jpg")
//src의 속성을 images/coffee-blue.jpg로 변경한다.

DOM에서 이벤트 처리

자바스크립트에는 html 페이지의 이벤트를 처리하는데 두가지 방법이 있습니다.

  1. html 태그내에 이벤트 처리기 연결
    <body>
    	<div id="container">
    		<img id="pic" src="images/girl.png" alt="" onclick="changePic()">
    	</div>
    	<script>		
    		var pic = document.querySelector('#pic');
    		function changePic() {			
    			pic.src = "images/boy.png";
    		}
    	</script>
    </body>

html에 직접 이벤트를 연결해준다. 이는 html에 직접 이벤트를 연결하는 방식이기에 수정할 경우 매번 html 페이지를 직접 일일히 수정해주어야 하는 불편함이 있습니다. 현재는 거의 쓰이지 않는 방식입니다.

  1. DOM element에 이벤트 처리기 연결
    <body>
    	<div id="container">
    		<img id="pic" src="images/girl.png" alt="">
    	</div>
    	<script>		
        var pic = document.querySelector('#pic');
        pic.onclick = changePic;
        
    		function changePic() {			
    			pic.src = "images/boy.png";
    		}
    	</script>
    </body>

html이 아닌 자바스크립트에서 DOM element에 접근해서 이벤트를 처리하는 방식입니다. html 태그와 뒤섞이지 않고 자바스크립트에서만 처리할수 있는 장점이 있습니다. 하지만 이러한 방식은 하나의 요소에 하나의 이벤트처리기만 연결할수 있다는 단점이 있습니다. 현재는 거의 쓰이지 않는 방식입니다.

  1. addEventListener() 함수 이용

    html 페이지를 직접 건드리지 않으면서 DOM 요소에 접근하면서 한번에 여러 이벤트를 처리할수 있는 방식입니다. addEventListener함수는 이벤트가 발생한 요소에 이벤트 처리기를 연결해주는 함수입니다. 웹문서의 특정 요소뿐만 아닌 document 객체, window 객체 어디서든 사용이 가능합니다.

    <body>
    	<div id="container">
    		<img id="pic" src="images/girl.png" alt="">
    	</div>

    	<script src="js/domevent3.js"></script>
    </body>
    const pic = document.querySelector('#pic');
    pic.addEventListener("mouseover", changePic, false);  // mouseover 이벤트 발생하면 changePic 함수 실행
    pic.addEventListener("mouseover", changeStyle, false);// mouseover 이벤트 발생하면 changeStyle 함수 실행
    pic.addEventListener("mouseout", originPic, false); // mouseout 이벤트 발생하면 originPic 함수 실행
    pic.addEventListener("mouseout", originStyle, false); // mouseout 이벤트 발생하면 originStyle 함수 실행

    function changePic() {			
      pic.src = "images/boy.png";
    }
    function originPic() {
      pic.src = "images/girl.png";
    }
    function changeStyle() {
      pic.style.border = "1px solid #222";
    }
    function originStyle() {
      pic.style.border = "none";
    }

    //이처럼 여러 이벤트핸들러 사용이 가능하며, 하나의 이벤트에 여러 처리를 하는것이 가능합니다.

DOM에 요소 추가하기

이미 존재하는 element들을 수정 및 조작하는것 말고도 새로운 element를 추가하는 것도 가능하다.

element를 추가할때는 그저 태그만 추가하는것 뿐만 아니라 텍스트 노드와 속성노드도 같이 추가해주어야 한다. 그리고 태그와 텍스트노드, 속성노드를 서로 연결해 주어야 합니다.

  • createElement() 함수

    새 element를 생성합니다.

  • createTextNode() 함수

    텍스트를 추가할 경우, 새로운 텍스트 노드를 생성합니다.

  • appendChild() 함수

    특정노드를 다른 노드의 자식노드로 추가하는데 사용되는 함수입니다.

  • createAttribute() 함수

    속성 노드를 생성합니다.

  • setAttributeNode() 함수

    속성 노드를 element노드에 연결합니다.

<p class="accent">주문이 완료되었습니다.</p> <!--이 태그를 추가해봅니다.-->
const newP = document.createElement("p") // element p 생성
const newText = document.createTextNode("주문이 완료되었습니다.") //텍스트 노드를 생성
newP.appendChild(newText) //newP에 텍스트노드 newText노드를 연결

const newAttr = document.createAttribute("class") //class 속성 노드를 생성
newAttr.value= "accent" // 클래스에 accent 클래스값을 설정

newP.setAttributeNode(newAttr) // element newP에 속성노드를 연결
// 위의 html 태그를 똑같이 생성 완료
// 속성 설정시 setAttribute() 함수도 이용 가능하다.
// setAttribute("class", "accent")

노드 순서 변경 및 삭제하기

element 간의 위치를 변경하거나 이미 존재하는 element 를 삭제하는 것도 가능합니다.

  • hasChildNodes() 함수

    특정노드가 자식노드를 가지고 있는지를 확인하는 함수이다. boolean 값을 반환한다.

  • childNodes 속성

    자식노드가 있는경우, 특정 노드의 자식노드에 접근하게 해주는 속성이다. 이 속성을

    이용하면 element 뿐만 아니라 줄바꿈 노드도 텍스트 노드도 전부 자식노드로 인식합니다.

  • children 속성

    특정 노드의 자식노드에 접근하게 해주는 속성. 이 속성은 오직 element 노드에만 접근한다.

  • insertBefore() 함수

    자식 노드를 추가하면 언제나 가장 마지막에 새로 자식노드가 추가된다. 하지만 이 함수는

    기준이 되는 자식노드를 설정하여 해당 자식노드보다 앞에 오게 해준다.

  • removeChild() 함수

    DOM에서 특정 노드를 삭제할떄 사용한다. 이때 노드는 스스로를 삭제할수는 없다. 삭제하려는 노드의 부모노드에서만 삭제가 가능하다. 그렇기에 특정 노드를 삭제하려면 해당 노드의 부모노드에서 이 함수를 사용해야 한다.

0개의 댓글