[day-28] DOM

Joohyung Park·2024년 2월 6일
0

[모두연] 오름캠프

목록 보기
42/95

DOM API

DOM API는 쉽게 말해서 DOM 설명서인데 여기서 DOM은 Document Object Model의 약자로 문서 객체 모델이다. 여기서 문서 객체는 여러 html 문서의 태그들을 자바스크립트가 이용할 수 있는 객체로 만들면 그것을 문서 객체(Document Object)라고 한다.

모델은 여기서는 '인식하는 방식' 그러니까 문서 객체를 인식하는 방식이 DOM이다. 넓은 의미로는 웹이 HTML 페이지를 인식하는 방식이고 좁은 의미로는 문서 객체와 관련된 객체의 집합을 의미한다. API는 Application Programming Interface의 약자로 통신하는데 필요한 설명서라고 봐도 될 것 같다.

DOM은 트리 구조로 이루어져 있는데 이 트리 각각의 요소를 노드라고 한다.


이러한 DOM 트리에 접근 하는 다양한 방법이 존재한다.

DOM 트리에 접근하기

document(문서) 객체를 통해 HTML 문서에 접근이 가능하다.

// 해당하는 Id를 가진 요소에 접근하기
document.getElementById();

// 해당하는 모든 요소에 접근하기
document.getElementsByTagName();

// 해당하는 클래스를 가진 모든 요소에 접근하기
document.getElementsByClassName();

// css 선택자로 단일 요소에 접근하기
document.querySelector("selector");

// css 선택자로 여러 요소에 접근하기
document.querySelectorAll("selector");

DOM 제어 명령어

이벤트 삽입

사용자가 클릭과 같은 이벤트를 발생시키면 그에 따른 결과를 출력한다.

<button>HELLO!</button>
// 이벤트의 타입에는 click, mouseover, mouseout, wheel 등 다양한 이벤트를 감지합니다.
// listener 함수의 인수에는 이벤트에 대한 정보가 담겨있습니다.

const myBtn = document.querySelector("button");

myBtn.addEventListener('click', function(){
	console.log("hello world");
})

클래스 제어

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");   해당하는 클래스가 있는지 확인합니다.
})


버튼을 누르고 클래스가 blue로 바꼈음을 알 수 있다.

요소 제어

요소를 새롭게 생성하고, 위치하고, 제거할 수 있다.

  • 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);
	}
})


버튼을 누르면 반복되는 만큼 li(순서가 없는 리스트)가 생성된다.

  • element.append(target) : target 요소를 element의 자식으로 위치시킨다. appendChild와 다르게 노드 뿐만 아니라 여러개의 노드, 텍스트도 자식 노드로 포함 가능하다.

  • target.remove(): target 요소를 제거한다. removeChild는 자식 요소만 제거하지만 이건 그 요소의 전부를 제거한다.

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);

부모노드.insertBefore(타겟, 기준 점 노드)를 사용하여 기준 점 노드 앞에 타겟요소를 삽입할 수도 있다. 참고로 알아두자.

span 태그가 새로 생겼다.

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

요소 안의 값에 접근하여 값을 가져오거나 변경할 수 있다.

<p></p>
<input type="text">
<button>Write Something!</button>
const myBtn = document.querySelector("button");
const myP = document.querySelector("p");
const myInput = document.querySelector("input");

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

// input 요소에 'input' 이벤트를 연결하면 실시간으로 값이 반영되게 만들 수도 있습니다.
myInput.addEventListener('input', ()=>{
  myP.textContent = myInput.value;
});

myP.innerHTML = "<strong>I'm Strong!!</strong>";



기본 상태는 위와 같고 무언가 입력하는 대로 p태그에 추가됨을 알 수 있다.

속성 제어하기

자바스크립트로 요소의 속성을 제어할 수도 있다.

  • style 객체
    요소는 그 안에 CSSStyleDeclaration이라 불리는 객체가 존재하기에 스타일과 관련한 프로퍼티와 메서드를 지원한다.
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 객체의 속성 식별자는 규칙이 존재한다. 속성이 대쉬로 나누어져 있으면 카멜 케이스로 사용한다. 또한 float속성은 cssFloat로 사용한다.

CSS를 통해 수정될 여지가 있는 스타일에는 style 대신 classList를 이용한 클래스 제어가 더 효과적이다.

  • Attribute 메서드

<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>

getAttribute 메서드를 통해 idAttrp태그의 id값에 접근하고 있다. 그리고, myimg 객체를 setAttribute를 사용하여 다른 이미지로 값을 수정해주고 있다.

  • data 속성

data로 시작하는 속성을 사용하면 HTML 요소에 추가적인 정보를 저장하여 마치 프로그램 가능한 객체처럼 사용할 수 있게 한다.

<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>

이러한 data-로 시작하는 속성들은 dataset 맵에 모아져 저장되며 객체 프로퍼티 접근 방법으로 접근할 수 있다.

요소 노드를 인접한 곳에 배치하기

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>');

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);  

cont 클래스의 내용을 찾아 cont객체를 생성하고 있다. cont클래스는 article태그라는 것을 충분히 알 수 있으리라 생각한다.
이후 첫번째 여러 형제, 자식, 부모 요소를 찾아서 출력하는 코드이다.

피드백

나만 막막한가 했는데 같이 듣는 다른 수강생분도 비슷한 것 같다. 강사님 말씀으로는 이런게 있다~~ 라고 알아두고 나중에 프론트 할일이 생길때 찾아보는 식으로 하라고 하셨다. 마음이 좀 편해진 것 같다.

저번주에 과제로 내주셨던 1만 시간의 법칙 이라는 페이지 만들기를 같이 해보았는데 같이 하니깐 또 괜찮은 것 같기도 하고 다시 하면 또 오래걸릴 것 같기도 하고 그렇다. 프론트쪽을 하다 오신분들은 뚝딱뚝딱 잘 하시던데 너무 신경쓰지말고 지식을 쌓으면서 나만의 페이스로 달려가겠다. 수료까지 화이팅!

profile
익숙해지기 위해 기록합니다

0개의 댓글