HTML 페이지에 있는 html, head, body, title, h1, div, span 등을 HTML에서는 요소, JavaScript에서는 문서 객체라고 부른다.
즉 문서 객체를 조작한다는 것은 h1, div, span과 같은 HTML 요소를 조작한다는 의미로,
문서 객체를 조합하여 만든 전체적인 형태를 문서 객체 모델이라고 한다.*
* 문서 객체 모델의 넓은 의미는 웹 브라우저가 HTML 문서를 인식하는 방식, 문서 객체 모델의 좁은 의미는 문서 객체의 집합으로, 간단히 이해하면 HTML 문서가 곧 문서 객체 모델인 것 같다.
DOMContentLoaded 이벤트
DOMContentLoaded 이벤트는 웹 브라우저가 문서 객체를 모두 읽어들인 뒤 발생하는 이벤트로,
문서 객체를 조작할 때는 DOMContentLoaded 이벤트를 사용해야 한다.
일반적으로 문서 객체 조작은 <head> 태그 내부의 <script> 태그에서 이루어지지만
위에서 아래로 실행되는 HTML 문서 특성 상 <script> 태그를 읽어들인 후에야 <body> 태그를 읽어들이기 때문에
<script> 태그에서 <body> 태그 내부의 문서 객체를 조작하려면 <body> 태그를 다 읽어들일 때까지 기다려야 한다.
이러한 이유로 문서 객체 조작 시 DOMContentLoaded 이벤트를 사용하고, 그 방법은 아래와 같다.
document.addEventListener('DOMContentLoaded', () => {})
document라는 문서 객체에 DOMContentLoaded 이벤트가 발생했을 때 매개변수로 지정된 콜백 함수를 실행하라는 의미로,
이는 곧 document라는 문서 객체를 모두 읽어들인 뒤 콜백 함수를 실행하라는 의미와 같다.
이때 문서 객체 조작에 대한 내용은 콜백 함수에 포함된다.
문서 객체 접근
문서 객체 접근 방법은 접근하고자 하는 문서 객체가 head, body, title인가 아닌가에 따라 구분할 수 있다.
접근하고자 하는 문서 객체가 head, body, title인 경우 아래와 같이 접근할 수 있고
document.head
document.body
document.title
그 외 문서 객체인 경우 CSS 선택자를 이용해 접근할 수 있다.
document.querySelector(선택자)
document.querySelectorAll(선택자)
이때 querySelector() 메소드는 하나의 요소를, querySelectorAll() 메소드는 여러 개의 요소를 추출한다.
<script>
document.addEventListener('DOMContentLoaded', () => {
const header = document.querySelector('h1')
const headers = document.querySelectorAll('h2')
header.textContent = 'HEADER'
header.style.color = 'white'
header.style.backgroundColor = 'black'
header.style.padding = '10px'
headers.forEach((header) => {
header.textContent = 'HEADERS'
header.style.color = 'white'
header.style.backgroundColor = 'black'
header.style.padding = '10px'
})
})
</script>
<body>
<h1></h1>
<h2></h2>
<h2></h2>
<h2></h2>
</body>
문서 객체 조작
문서 객체 조작 방법은 조작하고자 하는 대상이 글자인가 속성인가 스타일인가에 따라 구분할 수 있다.
글자 조작
속성 이름 | 설명 |
문서 객체.textContent | 입력된 문자열을 문자열 형식으로 넣는다. |
문서 객체.innerHTML | 입력된 문자열을 HTML 형식으로 넣는다. |
<script>
document.addEventListener('DOMContentLoaded', () => {
const a = document.querySelector('#a')
const b = document.querySelector('#b')
a.textContent = '<h1>textContent 속성</h1>'
b.innerHTML = '<h1>innerHTML 속성</h1>'
})
</script>
<body>
<div id="a"></div>
<div id="b"></div>
</body>
속성 조작
속성 이름 | 설명 |
문서 객체.setAttribute(속성, 값) | 특정 속성에 값을 지정한다. |
문서 객체.getAttribute(속성) | 특정 속성을 추출한다. |
<script>
document.addEventListener('DOMContentLoaded', () => {
const rects = document.querySelectorAll('.rect')
rects.forEach((rect, index) => {
const width = (index + 1) * 100
const src = `http://placekitten.com/${width}/250`
rect.setAttribute('src', src)
})
})
</script>
<body>
<img class="rect">
<img class="rect">
<img class="rect">
<img class="rect">
</body>
HTML 표준에 정의된 속성의 경우, setAttribute() 메소드와 getAttribute() 메소드를 사용하지 않고 앞서 배운 객체의 속성 값에 접근하는 방법을 사용해 속성을 추출하고 값을 지정할 수 있다.
rects.forEach((rect, index) => {
const width = (index + 1) * 100
const src = `http://placekitten.com/${width}/250`
rect.src = src
})
스타일 조작
문서 객체의 스타일을 조작할 때는 style 속성을 사용한다.
이때 style 속성은 객체로, 내부에 다양한 스타일 속성을 가진다.
스타일 속성으로는 color, background-color, font-size 등이 있는데,
CSS와 달리 JavaScript에서는 -를 식별자에 사용할 수 없으므로 캐멀 케이스를 사용한다.
예를 들어 h1의 background-color를 조작하는 방법은 아래와 같다.
h1.style.backgroundColor
h1.style['backgroundColor']
h1.style['background-color']
style 속성은 객체, background-color는 스타일 속성임을 이해한다면
객체 ① 객체 기본에서 배운 객체의 속성 값에 접근하는 방법과 다를 바가 없음을 알 수 있다.
일반적으로 첫번째 형태를 가장 많이 사용한다.
<script>
document.addEventListener('DOMContentLoaded', () => {
const divs = document.querySelectorAll('body > div')
divs.forEach((div, index) => {
const val = index * 10
div.style.height = '10px'
div.style.backgroundColor = `rgba(${val}, ${val}, ${val})`
})
})
</script>
<body>
<div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div>
</body>
문서 객체 생성
지금까지는 <body> 태그 내부에 있는 특정 문서 객체를 읽어들이고 이를 조작하였다면 사용자가 직접 문서 객체를 생성할 수도 있다.
document.createElement(문서 객체)
문서 객체를 생성했다면 반드시 해당 문서 객체의 위치를 지정해주어야 하는데
문서 객체는 트리 구조를 가지므로 부모 객체를 지정해줌으로써 위치를 지정할 수 있다.
부모 객체.appendChild(자식 객체)
<script>
document.addEventListener('DOMContentLoaded', () => {
const h1 = document.createElement('h1')
h1.textContent = 'HEADER'
h1.style.color = 'white'
h1.style.backgroundColor = 'black'
document.body.appendChild(h1)
})
</script>
<body>
</body>
문서 객체 이동
이때 각각의 문서 객체는 단 하나의 부모 객체를 가지므로 다른 부모 객체를 지정해줌으로써 위치를 이동할 수 있다.
다른 부모 객체를 지정해주는 것 또한 appendChild() 메소드를 사용한다.
<script>
document.addEventListener('DOMContentLoaded', () => {
const first = document.querySelector('#first')
const second = document.querySelector('#second')
const h1 = document.createElement('h1')
h1.textContent = 'moving h1'
const toFirst = () => {
first.appendChild(h1)
setTimeout(toSecond, 1000)
}
const toSecond = () => {
second.appendChild(h1)
setTimeout(toFirst, 1000)
}
toFirst()
})
</script>
<body>
<div id="first">
<h1>first div</h1>
</div>
<div id="second">
<h1>second div</h1>
</div>
</body>
문서 객체 제거
문서 객체를 제거할 때는 removeChild() 메소드를 사용한다.
문서 객체의 부모 객체.removeChild(문서 객체)
위의 방법을 사용할 경우 제거하고자 하는 문서 객체의 부모 객체를 직접 명시해야 한다는 불편함이 있는데,
부모 객체와 연결이 완료된 문서 객체의 경우 parentNode 속성을 사용해 부모 객체에 접근할 수 있으므로
일반적으로는 아래와 같은 방법을 사용해 문서 객체를 제거한다.
문서 객체.parentNode.removeChild(문서 객체)
<script>
document.addEventListener('DOMContentLoaded', () => {
setTimeout(() => {
const h1 = document.querySelector('h1')
h1.parentNode.removeChild(h1)
}, 3000)
})
</script>
<body>
<hr>
<h1>HEADER</h1>
<hr>
</body>
이벤트 설정
모든 문서 객체에는 이벤트가 발생한다.
이때 이벤트란 문서 객체가 생성되는 것, 문서 객체가 클릭되는 것, 문서 객체 위에 마우스를 올리는 것 모두를 포함하는 것으로
addEventListener() 메소드를 사용해 특정 이벤트가 발생할 때 특정 함수가 실행되도록 할 수 있다.
이벤트가 발생할 때 실행될 특정 함수를 이벤트 리스너 또는 이벤트 핸들러라고도 한다.
문서 객체.addEventListener(이벤트 이름, 콜백 함수)
이벤트를 제거할 때는 removeEventListener() 메소드를 사용한다.
문서 객체.removeEventListener(이벤트 이름, 콜백 함수)
일반적으로 변수 또는 상수로 이벤트 리스너를 미리 정의해두고 이를 이벤트 연결과 제거에 사용한다.
<script>
document.addEventListener('DOMContentLoaded', () => {
const h1 = document.querySelector('h1')
const connectButton = document.querySelector('#connect')
const disconnectButton = document.querySelector('#disconnect')
const p = document.querySelector('p')
let count = 0
let isConnect = false
const listener = (event) => {
h1.textContent = `클릭 횟수: ${++count}`
}
connectButton.addEventListener('click', () => {
if (isConnect === false) {
h1.addEventListener('click', listener)
p.textContent = '이벤트 연결 상태: 연결'
isConnect = true
}
})
disconnectButton.addEventListener('click', () => {
if (isConnect === true) {
h1.removeEventListener('click', listener)
p.textContent = '이벤트 연결 상태: 해제'
isConnect = false
}
})
})
</script>
<body>
<h1>클릭 횟수: 0</h1>
<button id="connect">이벤트 연결</button>
<button id="disconnect">이벤트 제거</button>
<p>이벤트 연결 상태: 해제</p>
</body>
이 글은 혼자 공부하는 자바스크립트 (윤인성 저)를 바탕으로 공부한 내용을 작성한 글입니다.
'Frontend > JavaScript' 카테고리의 다른 글
예외 처리 ① 구문 오류와 예외 (0) | 2024.10.27 |
---|---|
문서 객체 모델 ② 이벤트 활용 (8) | 2024.10.26 |
객체 ③ 객체와 배열 고급 (1) | 2024.09.30 |
객체 ② 기본 자료형과 객체 자료형 (1) | 2024.09.27 |
객체 ① 객체 기본 (0) | 2024.09.22 |