혼복필 2024. 2. 9. 19:37
728x90
300x250
SMALL

 

DOM (Document Object Model)

HTML 문서의 내용을 트리형태로 구조화하여 웹페이지와 프로그래밍 언어를 연결시켜 주는 역할

각각의 요소와 속성, 콘텐츠를 표현하는 단위를 노드 (Node)라고 함

+ API (Application Programming Interface) : 설명서

 

DOM 트리에 접근

document 객체를 통해 HTML 문서에 접근이 가능

(document : 브라우저가 불러온 웹페이지)

= DOM 트리의 진입점 역할을 수행

 

// 해당하는 Id를 가진 요소에 접근
document.getElementById();
// 해당하는 모든 요소에 접근
document.getElementsByTagName();
// 해당하는 클래스를 가진 모든 요소에 접근
document.getElementsByClassName();
// css 선택자로 단일 요소에 접근
document.querySelector("selector");
// css 선택자로 여러 요소에 접근
document.querySelectorAll("selector");

 

+ HTMLCollection과 NodeList

getElementsBy 메서드와 querySelectorAll 메서드

= 모두 조건에 일치하는 모든 요소를 찾는다는 공통적인 기능을 수행

하지만 결과물을 콘솔창에서 확인하면 다름

<article id="container">
    <ul>
        <li>탕수육</li>
        <li class="item-second">유산슬</li>
        <li>짜장면</li>
    </ul>
</article>
<script>
const cont = document.getElementById('container');
const item1 = cont.getElementsByTagName('li');
const item3 = cont.querySelectorAll('li');
</script>

 

+ item1과 item3을 콘솔에 찍은 결과

item1 : HTMLCollection(3) [li, li.item-second, li]

item3 : NodeList(3) [li, li.item-second, li]

 

HTMLCollection과 NodeList는 모두 배열과 비슷한 객체 (array-like object) 형태

공통점

안에 있는 데이터에 접근하기 위해서 배열처럼 원소의 인덱스로 접근

차이점

1. 해당 객체에 포함될 수 있는 DOM 요소의 유형

HTMLCollection은 HTML만 포함하지만 NodeList는 모든 유형의 DOM 요소 즉, text, 주석 등을 모두 포함

2. 객체를 구성하는 값이 변경 가능한지 여부

HTMLCollection은 실시간으로 업데이트되며 해당 객체의 각 속성에 대한 변경 사항이 즉시 반영

NodeList는 정적이므로 해당 객체에 대한 변경 사항은 즉시 반영되지 않음

3. 사용할 수 있는 메서드

NodeList는 forEach 같은 배열 메서드를 사용할 수 있지만 HTMLCollection은 또 다른 기능을 지원

 

DOM 제어 명령어

1. 이벤트 삽입

= target.addEventListener(type, listener)의 문법 형태

<button>HELLO!</button>

// 이벤트의 타입에는 click, mouseover, mouseout, wheel 등 다양한 이벤트를 감지
// listener 함수의 인수에는 이벤트에 대한 정보가 있음
const myBtn = document.querySelector("button");
myBtn.addEventListener('click', function(){
    console.log("hello world");
})

2. 클래스 제어 

= classList 객체를 통해 요소의 class 속성 제어

<button>Make me BLUE!</button>

const myBtn = document.querySelector("button");
myBtn.addEventListener('click', function(){
    // blue라는 클래스의 속성 값을 지정
    myBtn.classList.add("blue");
    // myBtn.classList.remove("blue"); 클래스를 제거
    // myBtn.classList.toggle("blue"); 클래스를 토글함 없으면 넣어주고 있으면 제거
    // myBtn.classList.contains("blue"); 해당하는 클래스가 있는지 확인
})

3. 요소 제어

= DOM api를 이용하면 요소를 새롭게 생성하고 위치시키며 제거할 수 있음

ㄱ. document.createElement(target) : target 요소를 생성

ㄴ. document.createTextNode(target) : target 텍스트를 생성

ㄷ. element.appendChild(target) : target 요소를 element의 자식으로 위치

ㄹ. element.removeChild(target) : element의 target 자식 요소를 제거

<ul></ul>
<button>Make me MORE!</button>

const myBtn = document.querySelector("button");
const myUl = document.querySelector("ul");
myBtn.addEventListener('click', function(){
    for(let i=0; i < 5; i++){
        const myLi = document.createElement('li');
        myUl.appendChild(myLi);
    }
})

ㅁ. element.append(target) : target 요소를 element의 자식으로 위치

appendChild와 다른 점은 노드뿐만 아니라 여러 개의 노드를 한 번에 그리고 텍스트도 자식 노드로 포함시킬 수 있음

ㅂ. target.remove() : target 요소를 제거

const myBtn = document.querySelector("button");
const myUl = document.querySelector("ul");
myBtn.addEventListener('click', function(){
    for(let i=0; i < 5; i++){
        const myLi = document.createElement('li');
        const btnDel = document.createElement('button');
        const btnTxt = document.createTextNode('버튼');
        btnDel.append(btnTxt);
        btnDel.addEventListener('click', ()=>{
            myLi.remove();
        });
        myLi.append('삭제하기: ', btnDel);
        myUl.appendChild(myLi);
        }
});

<div id="parentElement">
    <span id="childElement">hello guys~</span>
</div>

// parentElement.insertBefore(target, location); target요소를 parentElement의 자식인 location 위치 앞으로 이동
var span = document.createElement("span");
var sibling = document.getElementById("childElement");
var parentDiv = document.getElementById("parentElement");
parentDiv.insertBefore(span, sibling);

4. JavaScript 문자열을 사용해 element, text 노드를 생성하거나 추가

= DOM api를 이용하면 요소 안의 값에 접근하여 값을 가져오거나 변경할 수 있음

<p></p>
<input type="text">
<button>Write Something!</button>

const myBtn = document.querySelector("button");
const myP = document.querySelector("p");
const myInput = document.querySelector("input");

// ex) 1 : input 창에 글자를 써넣고 버튼을 누르면 글자를 p 태그에 삽입하는 코드

myBtn.addEventListener('click', function(){
    myP.textContent = myInput.value;
});

// ex) 2 : input 창에 글자를 쓰면 실시간으로 p 태그에 반영되는 코드
// input 요소에 'input' 이벤트를 연결하면 실시간으로 값이 반영되게 만들 수도 있음
myInput.addEventListener('input', ()=>{
    myP.textContent = myInput.value;
});
myP.innerHTML = "<strong>I'm Strong!!</strong>";
// innerHTML : 요소(element) 내에 포함된 HTML 마크업을 가져오거나 설정

// 중요한 기능은 innerHTML로 값을 할당할 때 마크업으로 변환할 수 있는 문자열이 있다면 마크업으로 만들어 보여준다는 것

// 만약 그런 문자열이 없다면 그냥 문자열만 콘텐츠로 설정
// innerText 속성 : 요소의 렌더링 된 텍스트 콘텐츠

// (렌더링된에 주목, innerText는 텍스트 내에 문법적으로 처리가 가능한 텍스트가 있으면 처리가 끝난 결과물을 텍스트로 전달)
// textContent 속성은 노드의 텍스트 콘텐츠를 표현, 콘텐츠를 단순히 텍스트로만 다룸

참고 : (innerHTML 사용 시 주의 사항) https://developer.mozilla.org/ko/docs/Web/API/Element/innerHTML#security_considerations

참고 : (innerText와 textContent의 차이) https://developer.mozilla.org/ko/docs/Web/API/HTMLElement/innerText#예제

5. 속성 제어

= 자바스크립트를 사용하여 요소의 속성을 제어하는 방법

ㄱ. 요소의 스타일을 제어하는 style 객체

= 요소는 그 안에 CSSStyleDeclaration 객체라 불리는 style 객체가 존재

요소의 스타일 정보를 가지고 있으며 스타일과 관련한 프로퍼티와 메서드를 지원함

const target = document.querySelector("p");
const txtColor = target.style.color; // 현재 스타일 정보를 가져옴
target.style.color = "red"; // 현재 스타일 정보를 변경
target.style.fontWeight = "bold"; // 현재 스타일 정보에 font-weight 속성이 없다면 추가
target.style.color = null; // 현재 스타일 정보를 제거 (초기화)

+ style 객체의 속성 식별자 규칙

1. 속성 이름이 한 글자라면 그대로 사용 (height, color ...)

2. 속성 이름이 대시(-)를 통해 여러 단어로 나눠져 있는 경우는 카멜케이스로 사용 (background-image를  backgroundImage로 사용)

3. float 속성의 경우 이미 자바스크립트의 예약어로 존재하기 때문에 cssFloat로 사용

ㄴ. 속성에 접근하고 수정할 수 있는 Attribute 메서드

= getAttribute 메서드는 요소의 특정 속성 값에 접근할 수 있도록 함

= setAttribute 메서드는 요소의 특정 속성 값에 접근하여 값을 수정 <p id='myTxt'>hello lions</p>
<img src='https://static.ebs.co.kr/images/public/lectures/2014/06/19/10/bhpImg/44deb98d-1c50-4073-9bd7-2c2c28d65f9e.jpg'>
<script>
    const target = document.querySelector('p');
    const myimg = document.querySelector('img');
    const idAttr = target.getAttribute('id');
    console.log(idAttr);
    myimg.setAttribute("src", "https://img.wendybook.com/image_detail/img159/159599_01.jpg");
</script>

ㄷ. 요소에 데이터를 저장하도록 도와주는 data 속성

= data 속성을 사용하면 HTML 요소에 추가적인 정보를 저장하여 마치 프로그램 가능한 객체처럼 사용 가능

(data 속성의 이름에는 콜론(:)이나 영문 대문자가 들어가면 안 됨)

<img
    class="terran battle-cruiser"
    src="battle-cruiser.png"
    data-ship-id="324"
    data-weapons="laser"
    data-health="400"
    data-mana="250"
    data-skill="yamato-cannon"
/>
<script>
    const img = document.querySelector('img')
    console.log(img.dataset);
    console.log(img.dataset.shipId);
</script>

6. 더 인접한 곳 (Adjacent)으로 정밀하게 배치

= insertAdjacentHTML : 요소 노드를 대상의 인접한 주변에 배치

<strong class="sayHi">
    반갑습니다.
</strong>

const sayHi = document.querySelector('.sayHi');
sayHi.insertAdjacentHTML('beforebegin', '<span>안녕하세요 저는</span>');
sayHi.insertAdjacentHTML('afterbegin', '<span>수현입니다</span>');
sayHi.insertAdjacentHTML('beforeend', '<span>댓글을 남겨주시면</span>');
sayHi.insertAdjacentHTML('afterend', '<span>답글을 적어드릴게요</span>');

= begin 여는 태그, end 닫는 태그를 의미

7. DOM 안에서 노드 탐색

<article class="cont">
    <h1>안녕하세요 저는 이런 사람입니다.</h1>
    <p>지금부터 자기소개 올리겠습니다</p>
    Lorem ipsum dolor sit amet consectetur adipisicing elit. Deserunt incidunt voluptates laudantium fugit, omnis
    dolore itaque esse exercitationem quam culpa praesentium, quisquam repudiandae aut. Molestias qui quas ea iure
    officiis.
    <strong>감사합니다!</strong>
</article>

const cont = document.querySelector(".cont");
console.log(cont.firstElementChild); // 첫 번째 자식을 찾음
console.log(cont.lastElementChild); // 마지막 자식을 찾음
console.log(cont.nextElementSibling); // 다음 형제요소를 찾음
console.log(cont.previousSibling); // 이전 형제노드를 찾음
console.log(cont.children); // 모든 자식요소를 찾음
console.log(cont.childNodes); // 모든 자식노드를 찾음
console.log(cont.parentElement); // 부모 요소를 찾음
// 자기 자신부터 시작해 부모로 타고 올라가며 가장 가까운 cont 클래스 요소를 찾음

// 단, 형제요소는 찾지 않음
console.log(cont.querySelector('strong').closest('.cont').innerHTML);

 

이벤트 객체

= 이벤트에서 호출되는 핸들러에는 이벤트와 관련된 모든 정보를 가지고 있는 매개변수가 전송

<article class="parent">
    <ol>
        <li><button class="btn-first" type="button">버튼 1</button></li>
        <li><button type="button">버튼 2</button></li>
        <li><button type="button">버튼 3</button></li>
    </ol>
</article>

const btnFirst = document.querySelector('.btn-first');
btnFirst.addEventListener('click', (event) => {
    console.log(event);
});

 

7일 글에 이어서 DOM의 이벤트 흐름부터 알아보겠습니다.

이번주는 스스로 컨디션이 많이 좋지 못해 미루었던 일들이 많은데 역시 사람은 할 일은 그때그때 다 해야겠어요.

미루다가 하려니 나 자신이 너무 힘들고 저랑은 안 맞는 스타일 같군요 x_X

정리한 파일은 GitHub에서 확인하실 수 있습니다.

이 글을 보시는 분은 즐거운 설 연휴 보내세요! 6일 정리글이 9일에 올라가는 마법..

https://github.com/soohyun020812/ormcamp

 

GitHub - soohyun020812/ormcamp: 오름캠프 교육에서 활용한 실습 내용들 정리

오름캠프 교육에서 활용한 실습 내용들 정리. Contribute to soohyun020812/ormcamp development by creating an account on GitHub.

github.com

728x90
300x250
LIST