문서 객체 모델 DOM(Document Object Model)
1. DOM의 개념
HTML 요소를 Object(JavaScript Object)처럼 조작(Manipulation)할 수 있는 Model
- HTML의 구조와 관계를 객체로 표현한 모델로 document라는 전역변수를 통해 HTML에 접근 가능
- 자바스크립트를 이용해 DOM에 접근하여 엘리먼트의 속성값을 얻거나 변경할 수 있음
2. DOM의 구조
- 자바스크립트의 객체와 같이 트리 구조이기 때문에 자바스크립트의 DOM이 브라우저에 접근하기 가장 용이
*다른 언어도 DOM을 가지고 있지만 자바스크립트가 가장 안정적
3. console.dir()로 콘솔에서 엘리먼트 조회하기
- console.log(document): html문서 형식으로 보여줌
- console.dir(document): 객체의 형태로 보여줌
*자바스크립트로 접근할 수 있는 key와 value를 조회할 수 있기에 더 용이
DOM으로 HTML 요소 분석하기
1. .tagName
- 태그 이름 조회 가능
2. .id
- id 조회 가능
3. class
3-1 .className
- className 조회 가능(문자열로 출력)
3-2. .classList
- class 목록 조회 가능(유사 배열로 출력)
- classList[idx]로 조회 가능
4. .attibute
- 속성 객체 조회 가능
5. .style
- 스타일 객체 조회 가능
6. .innerHTML, .innerText, .textContent
- 엘리먼트에 담긴 내용 조회 가능
- innerHTML, textContent: 값을 할당하여 내용까지 변경 가능
- innerHTML: 태그까지 모두 함께 보여줌(html형식), 태그까지 적용하여 변경 가능
*보안상 해킹에 노출될 문제를 가지고 있어 지양(xss공격) - textContent: 실제 포함되어 있는 공백까지 적용되어 보여줌, 내용만 변경 가능
- innerText: 화면에 렌더링되고 있는 텍스트를 보여줌
7. .value
function getInputValue() {
let elUsername = document.querySelector("#username") //input 태그
console.log(elUsername.value) //input 창에 사용자가 입력한 내용 조회
}
let registerBtn = document.querySelector(".register")
registerBtn.addEventListener("click", getInputValue)
//등록버튼을 누르면 input 창에 사용자가 입력한 내용을 가져옴
//함수이름만 적는 것 주의
registerBtn.onclick = getInputValue
//위와 동일
- value: 사용자가 form에 입력한 값을 의미
- form 입력 값 조회 가능
*form 입력 창: input태그 등
8. .parentElement: 부모 엘리먼트 조회
let newsContents = document.body.children[1]
console.log(newsContents.parentElement)
- document.body.children[1]의 부모 엘리먼트 조회
9. .children: 자식 엘리먼트 조회
console.log(document.body.children)
- 가지고있는 자식 태그 조회 가능
10. .childNodes
- 자식 노드 조회 가능
*node: 태그뿐 아니라 자식 태그가 가지고있는 textContent까지 포함
Node: 태그 노드와 텍스트 노드, 공백 노드 등 노드 전체을 의미하며 Element의 상위 개념으로 DOM 관련 객체는 대부분 Node에서 파생
Element: Node의 기능을 적용(implements)한 객체 타입으로 텍스트 노드를 제외하고, 흔히 생각하는 태그만을 의미
11. .dataset
- date-* 속성에 담긴 값 조회 가능
- HTML문서에서, 화면에 보이지 않지만 태그 자체에 데이터를 심어놓고싶을 때 용이
DOM으로 HTML 조작하기
1. createElement
document.createElement('div')
새로운 div태그 element를 생성한 후 변수에 할당
2. append / appendChild
function appendNewTweet() {
let li = document.createElement('li')
li.textContent = "대충 리스트라는 글"
let tweetContainer = document.querySelector('#tweetContainer')
tweetContainer.appendChild(li)
}
- createElement로 생성한 li는 아무것과도 연결이 안된 상태이므로 트리 구조에 연결 필요
- 원하는 부모 엘리먼트인 #tweetContainer에 appendChild
- append: 마지막 자식으로 들어감, 자바스크립트 메소드로 한번에 여러개의 자식 설정 가능
*문자열 노드를 추가로 지원함 - appendChild: 마지막 자식으로 들어감, DOM 메소드로 한번에 하나의 자식만 설정 가능
*노드 객체만 가능 - prependChild: 첫번째 자식으로 올림
3. querySelector / querySelectorAll
document.querySelector('.tweet')
document.querySelectorAll('.tweet')
- 셀렉터: HTML 태그("div"), id("#tweetList"), class(.tweet)
- querySelector: 클래스 이름이 tweet인 HTML 엘리먼트를 조회
*oneTweet엔 최상단 엘리먼트 하나만 존재 - querySelectorAll: 클래스 이름이 tweet인 모든 HTML 엘리먼트를 조회
*oneTweet엔 모든 해당 엘리먼트 존재, 배열처럼 for문 사용 가능 - getElementsByTagName / getElementById / getElementsByClassName으로도 조회 가능
4. textContent / classList.add / setAttribute
4-1. textContent
document.querySelector('.tweet').textContent = 'dev';
tweetDiv.textContent = 'dev';
- querySelector로 위치 지정 후 textContent로 문자열('dev')을 삽입
- querySelector로 지정한 경로를 담은 변수를 선언해주면 더욱 간편
- 기존에 textContent가 없었다면 새롭게 추가, 있었다면 교체
4-2. classList.add
document.querySelector('.tweet').classList.add('tweet')
tweetDiv.classList.add('tweet')
- classList.add를 이용해 'tweet' 클래스를 추가
*.classList.remove('tweet')를 하면 'tweet' 클래스 삭제
4-3. setAttribute
let sominElement = document.createElement('span')
sominElement.setAttribute('id', 'hope')
sominElement.textContent = 'I love hope'
- 새로운 span태그 sominElement 생성
- setAttribute를 활용하여 id를 "hope"로 지정
- textContent를 활용하여 sominElement에 문자열('I love hope')를 삽입
5. remove / removeChild
document.querySelector('.tweet').remove()
tweetDiv.remove()
//tweetDiv를 삭제
document.querySelector('#container').innerHTML = '';
//id가 container인 엘리먼트의 모든 자식 엘리먼트 삭제
//innerHTML의 사용은 지양
while (container.firstChild) {
container.removeChild(container.firstChild);
}
//container의 첫 번째 자식 엘리먼트가 존재하면, 첫 번째 자식 엘리먼트를 제거
//결과적으로 id가 container인 엘리먼트 아래의 모든 엘리먼트 삭제
while (container.children.length > 1) {
container.removeChild(container.lastChild);
}
//container의 자식 엘리먼트가 1개만 남을 때까지, 마지막 자식 엘리먼트를 제거
document.querySelectorAll('.tweet').forEach(function(tweet){
tweet.remove();
})
//클래스 이름이 tweet인 엘리먼트만 찾아서 제거
for (let tweet of document.querySelectorAll('.tweet')){
tweet.remove()
}
//클래스 이름이 tweet인 엘리먼트만 찾아서 제거
- classList.remove(): 필요에 따라 제거/삽입 가능
- remove(): 영구 삭제
HTML에 자바스크립트 적용하기
1. 적용 방법
<script src="script.js"></script>
- script 태그 이용
2. script 태그
웹브라우저는 script 태그를 만나면 HTML 해석을 멈추고 script 요소를 실행
*script 요소는 등장과 함께 실행
2-1. head 태그 안쪽에 삽입
- body를 만나기 전 script 태그를 먼저 만나기 때문에 HTML 해석을 멈추고 script 요소를 실행
- HTML 해석이 멈췄기 때문에 자바스크립트에서 document.querySelector를 사용한 경우 콘솔에 null이 출력
*DOM 트리가 생성되기전에 자바스크립트가 존재하지 않는 DOM 요소에 접근하게 됨 - HTML문서는 하향식으로 읽기 때문에 script 태그를 읽느라 body를 읽지 못해 Display에 표시되는 것이 지연
2-2. body 태그가 끝나기 전에 삽입
- body 내부를 모두 읽은 후 script 태그를 만나 script 요소를 실행
- 자바스크립트에서 document.querySelector를 사용한 경우에도 DOM 요소가 모두 존재하기에 정상적으로 출력
- head 태그 안쪽에 삽입하는 방법보다 지향
- HTML을 모두 읽은 뒤에 script 요소를 실행하기 때문에 html의 코드가 자바스크립트에 의존적이라면 사용자에게 의미 없는 Display를 노출하게 됨
References
반응형
'CodeStates > React' 카테고리의 다른 글
[React] State & Props (0) | 2022.02.21 |
---|---|
[React] Single-Page Application (0) | 2022.02.21 |
[React] React 기초와 프로젝트 시작방법 (0) | 2022.02.16 |
[CSS] Cascading Style Sheets (0) | 2021.12.20 |
[HTML] HyperText Markup Language (0) | 2021.12.20 |
댓글