Javascript : window(브라우저)와 dom
by 담담이담1. window 객체
window 객체는 브라우저 창을 의미하며
자바스크립트에서 최상단에 존재하는 객체이다.
console.log(window)를 하면
수 많은 프로퍼티들이 출력된다.
예) console, document
자바스크립트 코드 어느 곳에서나 항상 접근할 수 있는 객체이기 때문에
전역 객체, 영어로는 Global Object라고 부른다.
어떤 프로퍼티나 메소드를 사용하든 결국 전역 객체 내부의 것이기 때문에
앞에 window.을 생략할 수도 있다.
(원칙적으로는 window.console.log("hello")이다.)
2. DOM
1) DOM의 의미
window 객체의 프로퍼티 중 하나
Document Object Model의 줄임말이며
(웹)문서 객체 모델이라고 해석된다.
웹 페이지에 나타나는 HTML 문서 전체를 객체로 표현한 것
// DOM (Document Object Model)
console.log(document);
console.log(typeof document);
console.dir(document);
console.log를 이용해서 dom 객체에 접근하면
객체가 아니라 dom에 해당하는 html 태그가 출력이 된다.
객체로 접근하고 싶다면 console.dir을 사용하면 된다.
즉,
콘솔에서 값 자체를 확인하고 싶다면 log메소드를,
객체의 속성들을 살펴보고 싶다면 dir 메소드를 활용하면 좋다.
2) DOM 트리
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>JS with Codeit</title>
</head>
<body>
<h1 id="title">DOM(Document Object Model)</h1>
<h2 id="sub-title">문서 객체 모델</h2>
<script src="index.js"></script>
</body>
</html>
DOM은 html 문서를 객체화한 것이기에
document 객체를 최상위로 해서 계층 구조를 이루고
이를 나무에 비유해서 DOM 트리라고 한다.
DOM 트리에서는 각 객체를 노드라고 표현한다.
각 노드에는 부모, 자식, 형제 노드 관계가 존재한다.
태그(html, head, body, h1, h2, script)를 표현하는 노드는
'요소 노드'라고 하고,
문자를 표현하는 노드는 '텍스트 노드'라고 한다.
3) 요소 노드 간 이동에 대한 프로퍼티
태그 이동에 대한 프로퍼티들을 나열해봤다.
이는 프로퍼티이지 함수가 아니다.
프로퍼티 | 유형 | 결과 |
element.children | 자식 요소 노드 | element의 자식 요소 모음 (HTMLCollection) |
element.firstElementChild | 자식 요소 노드 | element의 첫 번째 자식 요소 하나 |
element.lastElementChild | 자식 요소 노드 | element의 마지막 자식 요소 하나 |
element.parentElement | 부모 요소 노드 | element의 부모 요소 하나 |
element.previousElementSibling | 형제 요소 노드 | element의 이전(previous) 혹은 좌측(left)에 있는 요소 하나 |
element.nextElementSibling | 형제 요소 노드 | element의 다음(next) 혹은 우측(right)에 있는 요소 하나 |
4) 요소 노드 프로퍼티
1. element.innerHTML
요소 노드 내부의 HTML 코드를 문자열로 리턴해 준다.
(내부에 있는 줄 바꿈이나 들여쓰기 모두 포함)
요소 안의 정보를 확인할 수도 있지만,
내부의 HTML 자체를 수정할 때 좀 더 자주 활용된다.
(내부에 있던 값을 완전히 새로운 값으로 교체하기 때문에 주의해서 사용해야한다.)
덧셈 할당 연산자를 이용해 마지막에 요소를 추가할 수도 있다.
2. element.outerHTML
요소 노드 자체의 전체적인 HTML 코드를 문자열로 리턴해준다.
(내부에 있는 줄 바꿈이나 들여쓰기 모두 포함)
outerHTML은 새로운 값을 할당할 경우
요소 자체가 교체되어 버리기 때문에 주의해야 한다.
3. element.textContent
요소 안의 내용들 중에서
HTML 태그 부분은 제외하고 텍스트만 가져온다.
(내부에 있는 줄 바꿈이나 들여쓰기 모두 포함)
새로운 값을 할당하면
innerHTML과 마찬가지로 내부의 값을
완전히 새로운 값으로 교체한다.
하지만 textContent는 말그대로 텍스트만 다루기 때문에,
특수문자도 그냥 텍스트로 처리한다.
(즉, 새 값을 할당할 때 태그도 포함해서 작성하더라도,
태그 자체도 텍스트로 반영된다)
5) 요소 노드 추가하기
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>JS with Codeit</title>
</head>
<body>
<div>
<h1>오늘 할 일</h1>
<ol id="today">
<li>자바스크립트 공부</li>
<li>고양이 화장실 청소</li>
<li>고양이 장난감 쇼핑</li>
</ol>
<h1>내일 할 일</h1>
<ol id="tomorrow">
<li>자바스크립트 공부</li>
<li>뮤지컬 공연 예매</li>
<li>유튜브 시청</li>
</ol>
</div>
<script src="index.js"></script>
</body>
</html>
여기에
const today = document.querySelector('#today');
today.innerHTML = '<li>처음</li>' + today.innerHTML;
today.innerHTML = today.innerHTML + '<li>마지막</li>';
today.outerHTML = '<p>이전</p>' + today.outerHTML;
const newToday = document.querySelector('#today');
newToday.outerHTML = newToday.outerHTML + '<p>다음</p>';
이런 식으로
innerHTML이나 outerHTML에
덧셈을 이용해서 요소를 추가하면,
기존의 값을 활용해야하기에 기존 값을 계속 호출해야하고,
잘못하면 덮어써버려서 요소가 사라지기도 함
특히 outerHTML은 덧셈을 이용해서 수정 시
아예 다른 요소가 되기 때문에 다시 불러와야함
대안
// 요소 노드 추가하기
const tomorrow = document.querySelector('#tomorrow');
// 1. 요소 노드 만들기: document.createElement('태그이름')
const first = document.createElement('li');
// 2. 요소 노드 꾸미기: textContent, innerHTML, ...
first.textContent = '처음';
// 3. 요소 노드 추가하기: NODE.prepend, append, after, before
tomorrow.prepend(first);
const last = document.createElement('li');
last.textContent = '마지막';
tomorrow.append(last);
const prev = document.createElement('p');
prev.textContent = '이전';
tomorrow.before(prev);
const next = document.createElement('p');
next.textContent = '다음';
tomorrow.after(next);
요소 노드 만들기 함수: document.createElement('태그이름')
요소 노드 꾸미기 위한 프로퍼티 : element.textContent, element.innerHTML, ...
요소 노드 추가하기 함수 : element.prepend, element.append, element.after, element.before
6) 요소 노드 이동 및 삭제하기
// 노드 삭제와 이동
const today = document.querySelector('#today');
const tomorrow = document.querySelector('#tomorrow');
// 노드 삭제하기: Node.remove()
tomorrow.remove();
today.children[2].remove();
// 노드 이동하기: prepend, append, before, after
today.append(tomorrow.children[1]);
tomorrow.children[1].after(today.children[1]);
tomorrow.children[2].before(today.children[1]);
tomorrow.lastElementChild.before(today.children[1]);
요소 노드 이동하기 함수 : element.prepend, element.append, element.after, element.before
요소 노드 삭제하기 함수: element.remove()
7) HTML 속성 다루기
대부분의 HTML 속성은
DOM 객체의 프로퍼티로 변환된다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="style.css">
<title>JS with Codeit</title>
</head>
<body>
<div>
<h1 class="title">오늘 할 일</h1>
<ol id="today" class="list today">
<li class="item">자바스크립트 공부</li>
<li class="item">고양이 화장실 청소</li>
<li class="item">고양이 장난감 쇼핑</li>
</ol>
<h1 class="title">내일 할 일</h1>
<ol id="tomorrow" class="list tomorrow">
<li class="item">자바스크립트 공부</li>
<li class="item">뮤지컬 공연 예매</li>
<li class="item">유튜브 시청</li>
</ol>
</div>
<script src="index.js"></script>
</body>
</html>
일단 HTML 속성이란..
HTML 태그 안에 "attribute = value" 형식에서
attribute 부분에 해당하는 값이다.
이 코드를 예를 들면,
id, class, href, src 등이 해당된다.
이러한 HTML 속성들이
요소 노드의 프로퍼티가 된다는 것은
(요소 노드가 무엇이었는가?
각각의 HTML 태그이지 않는가!)
// HTML 속성 (HTML attribute)
const tomorrow = document.querySelector('#tomorrow');
const item = tomorrow.firstElementChild;
const link = item.firstElementChild;
// id 속성
console.log(tomorrow);
console.log(tomorrow.id);
// class 속성
console.log(item);
console.log(item.className);
// href 속성
console.log(link);
console.log(link.href);
console.log(tomorrow.href);
각 요소 노드에 접근해서
tommorrow, item, link라는 변수에 담았을 때,
HTML 태그 속성에 "." 으로 접근할 수 있다는 것이다.
주의 : 모든 HTML 속성이 요소 노드의 프로퍼티로 생성되지는 않는다.
사실
HTML "표준" 속성만 요소 노드의 프로퍼티로 생성된다.
뿐만 아니라, "."으로 접근할 때 class는 className으로 접근해야한다.
그렇다면 HTML 비표준 속성에는 어떻게 접근하지?
// elem.getAttribute('속성'): 속성에 접근하기
console.log(tomorrow.getAttribute('href'));
console.log(item.getAttribute('class'));
// elem.setAttribute('속성', '값'): 속성 추가(수정)하기
tomorrow.setAttribute('class', 'list'); // 추가
link.setAttribute('href', 'https://20002100.tistory.com/'); // 수정
// elem.removeAttribute('속성'): 속성 제거하기
tomorrow.removeAttribute('href');
tomorrow.removeAttribute('class');
8) 스타일 다루기
(1) style property 사용하기
// 스타일 다루기
const today = document.querySelector('#today');
const tomorrow = document.querySelector('#tomorrow');
// style 프로퍼티
today.children[0].style.textDecoration = 'line-through';
today.children[0].style.backgroundColor = '#DDDDDD';
today.children[2].style.textDecoration = 'line-through';
today.children[2].style.backgroundColor = '#DDDDDD';
style 프로퍼티를 이용해서 css 속성을 다룰 때
여러 단어를 -으로 연결해서 만든 속성은
카멜 표기법으로 바꿔서 써줘야함
그런데 이 방법은 잘 사용하지 않음
왜?
이렇게 HTML의 style 속성에 추가되어버리기에
style 우선순위가 바뀌어버리고,
같은 style을 다른 여러 태그에 적용해야할 때
불필요하게 같은 코드를 여러 번 나열하게됨
(2) 태그의 class를 변경
미리 done이라는 클래스에
css style을 정의해놓았다고 가정했을 때,
// elem.className
today.children[1].className = 'done';
1. className 프로퍼티를 사용하기
문제점 : 클래스 속성값 자체가 바뀐다.
즉, 위의 코드로 가정했을 때
원래 있던 클래스가 사라지고
done 클래스만 남는다.
2. classList 프로퍼티 사용하기
원래 있는 클래스들을 유지하고 싶다면
classList 사용
classList는 class "속성값"을 유사배열로 관리함
console.log(today.classList);
console.log(today.children[1].classList);
따라서 클래스 속성을 하나씩 다룰 수 있고,
아래와 같은 메소드들도 사용 가능함
// elem.classList: add, remove, toggle
const item = tomorrow.children[1];
item.classList.add('done', 'other');
item.classList.remove('done');
item.classList.toggle('done');
toggle은 있으면 제거하고, 없으면 추가하는 메소드
'Javascript' 카테고리의 다른 글
Javascript : AND와 OR의 동작방식 (feat. truthy, falsy한 값) (2) | 2023.09.30 |
---|---|
Javascript : 이벤트 핸들러 (0) | 2023.09.27 |
Javascript : document 프로퍼티를 이용해 태그 선택하기 (0) | 2023.09.25 |
Javascript : 객체의 property 삭제와 배열의 요소 삭제 방법 차이 (0) | 2023.09.20 |
Javascipt : 숫자형 메소드 (0) | 2023.09.20 |
블로그의 정보
유명한 담벼락
담담이담