본문 바로가기
혼공학습단 11기(完)

[혼공스] 07 - 1 '문서 객체 조작하기' 정리(2)

by jaeheon0520 2024. 2. 1.

 

오늘은 07 - 1장의 내용을 정리를 마무리 해보자.

 

07 - 1장의 뒷부분에는 문서 객체와 이벤트에 대해서 설명하고 있다.

 

화면을 구성하는 기본 내용이니 잘 익혀두어야 한다.

 

그럼 정리 시작!

 

문서 객체 생성하기

지금까지는 body 태그 내부에 있는 특정 문서 객체를 읽어들이고 이를 조작했다. 문서 객체를 생성하고 싶을 때에는 document.createElement() 메소드를 사용한다. 

 

document.createElement(문서 객체 이름)

 

그런데 문서 객체를 만들었다고 문서 객체가 배치되는 것은 아니다. 문서를 어떤 문서 아래에 추가 할지를 지정해줘야 한다. 프로그래밍에서는 트리라고 부른다.

 

문서 객체에는 appendChild() 메소드가 있으며, 이를 활용하면 어떤 부모 객체 아래에 자식 객체를 추가할 수 있다.

 

부모 객체.appendChild(자식 객체)

 

다음 코드는 document.createElement() 메소드로 h1 태그를 생성하고, 이를 document.body 태그 아래에 추가하는 코드이다.

 

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Document</title>
    <script>
        document.addEventListener('DOMContentLoaded', () => {
            // 문서 객체 생성하기
            const header = document.createElement('h1') // h1 태그를 생성한다

            // 생성한 태그 조작하기
            header.textContent = '문서 객체 동적으로 생성하기'
            header.setAttribute('data-custom', '사용자 정의 속성')
            header.style.color = 'white'
            header.style.backgroundColor = 'black'

            // h1 태그를 body 태그 아래에 추가하기
            document.body.appendChild(header)
        })
    </script>
</head>
<body>
   
</body>
</html>

 

문서 객체 생성하고 추가하기

 

문서 객체 이동하기

appendChild() 메소드는 문서 객체를 이동할 때도 사용할 수 있다. 문서 객체의 부모는 언제나 하나여야 한다. 따라서 문서 객체를 다른 문서 객체에 추가하면 문서 객체가 이동한다. 

 

다음 코드는 1초마다 <h1>이동하는 h1 태그</h1>라는 요소가 div#first(id 속성이 first인 div 태그)와 div#second로 움직이게 한다. 실질적으로 사용된 코드는 지금까지 모두 배운 내용이지만, setTimeout() 함수를 번갈아가면서 실행하는 코드가 익숙하지 않을 수 있다. 이 부분을 잘 익히도록 하자.

 

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Document</title>
    <script>
        document.addEventListener('DOMContentLoaded', () => {
            // 문서 객체 읽어들이고 생성하기
            const divA = document.querySelector('#first') // id 속성이 first인 div 태그를 선택한다
            const divB = document.querySelector('#second') // id 속성이 second인 div 태그를 선택한다
            const h1 = document.createElement('h1') // h1 태그를 생성한다
            h1.textContent = '이동하는 h1 태그'

            // 서로 번갈아가면서 실행하는 함수를 구현한다
            const toFirst = () => {
                divA.appendChild(h1) // h1을 divA에 추가한다
                setTimeout(toSecond, 1000) // 1초 뒤에 toSecond 함수를 실행한다
            }
            const toSecond = () => {
                divB.appendChild(h1) // h1을 divB에 추가한다
                setTimeout(toFirst, 10000) // 10초 뒤에 toFirst 함수를 실행한다
            }
            toFirst()
        })
    </script>
</head>
<body>
    <div id="first">
        <h1>첫 번째 div 태그 내부</h1>
    </div>
    <hr>
    <div id="second">
        <h1>두 번째 div 태그 내부</h1>
    </div>
</body>
</html>

 

문서 객체 이동하기(1초)
문서 객체 이동하기(10초)

 

코드를 실행하면 h1 태그가 hr 태그를 기준으로 위와 아래로 이동하는 것을 볼 수 있다.

 

문서 객체 제거하기

문서 객체를 제거할 때는 removeChild() 메소드를 사용한다.

 

부모 객체.removeChild(자식 객체)

 

appendChild() 메소드 등으로 부모 객체와 이미 연결이 완료된 문서 객체의 경우 parentNode 속성으로 부모 객체에 접근할 수 있으므로, 일반적으로 어떤 문서 객체를 제거할 때는 다음과 같은 형태의 코드를 사용한다.

 

문서 객체.parentNode.removeChild(문서 객체) // 부모 객체를 이런 방법으로 선택할 수 있다.

 

다음 코드는 특정 개체를 간단하게 실행하고, 3초후 화면에서 h1 태그를 제거하는 프로그램이다.

 

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Document</title>
    <script>
        document.addEventListener('DOMContentLoaded', () => {
            setTimeout(() => {
                const h1 = document.querySelector('h1')

                h1.parentNode.removeChild(h1) // h1 태그의 부모 객체 body 태그에 접근하여 제거한다
                //document.body.removeChild(h1) // h1.parentNode가 document.body이므로, 이런 형태도 가능하다
            }, 3000) // 3초 뒤에 제거
        })
    </script>
</head>
<body>
    <hr>
    <h1>제거 대상 문서 객체</h1>
    <hr>
</body>
</html>

 

프로그램을 실행하면 처음에는 <h1> 태그에 담긴 내용이 등장한다. 하지만 3초가 지나면 <h1> 요소가 제거된다.

 

이벤트 설정하기

지금까지 계속 document.addEventListener('DOMContentLoaded', () => {})라는 형태의 코드를 사용하고 있다. 이 코드는 "document라는 문서 객체의 DOMContentLoaded 이벤트가 발생했을 때, 매개변수로 지정한 콜백 함수를 실행해라"라는 의미이다.

 

모든 문서 객체는 생성되거나 클릭되거나 마우스를 위에 올리거나 할 때 이벤트라는 것이 발생한다. 그리고 이 이벤트가 발생할 때 실행할 함수는 addEventListener() 메소드를 사용한다.

 

문서 객체.addEventListener(이벤트 이름, 콜백 함수) // 이때 콜백 함수를 이벤트 리스너 또는 이벤트 핸들러 라고 부른다

 

이벤트가 발생할 때 실행할 함수를 이벤트 리스너(event listener) 또는 이벤트 핸들러(event handler)라고 부른다. 이벤트를 어떤 식으로 연결하는지 알아보자.

 

다음 코드는 addEventListener() 메소드를 사용해서 h1 태그를 클릭할 때 이벤트 리스너(콜백 함수)를 호출하는 예이다. 이벤트 리스너 내부에서 변수 counter를 증가시키고 출력하고 있다.

 

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Document</title>
    <script>
        document.addEventListener('DOMContentLoaded', () => {
            let counter = 0
            const h1 = document.querySelector('h1')

            h1.addEventListener('click', (event) => {
                counter++
                h1.textContent = `클릭 횟수: ${counter}`
            })
        })
    </script>
</head>
<style>
    h1 {
    /* 클릭을 여러번 했을 때
       글자가 선택되는 것을 막기 위한 스타일
       해당 태그를 마우스로 드래그 하지 못한다.*/
       user-select: none
    }
</style>
<body>
    <h1>클릭 횟수: 0</h1>
</body>
</html>

 

이벤트 연결하기

 

코드를 실행하고 h1 태그를 클릭해보면 클릭 횟수를 출력한다.

 

이벤트를 제거할 때는 다음과 같은 형태로 removeEventListener() 메소드를 사용한다.

 

문서 객체.removeEventListener(이벤트 이름, 이벤트 리스너)

 

이벤트 리스너 부분에는 연결할 때 사용했던 이벤트 리스너를 넣는다. 변수 또는 상수로 이벤트 리스너를 미리 만들고, 이를 이벤트 연결과 제거에 활용한다.

 

다음 코드는 버튼으로 이벤트 연결 상태를 제어하는 프로그램이다. 이벤트 리스너가 여러 번 연결되지 않게 inConnect라는 변수를 활용한다.

 

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Document</title>
    <script>
        document.addEventListener('DOMContentLoaded', () => {
            let counter = 0
            let isConnect = false

            const h1 = document.querySelector('h1')
            const p = document.querySelector('p')
            const connectButton = document.querySelector('#connect')
            const disconnectButton = document.querySelector('#disconnect')

            const listener = (event) => { // 이벤트를 제거하려면 이벤트 리스너를 변수 또는 상수로 가지고 있어야 한다
                h1.textContent = `클릭 횟수: ${counter++}`
            }

            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>
    <style>
        h1 {
        /* 클릭을 여러번 했을 때
           글자가 선택되는 것을 막기 위한 스타일
           해당 태그를 마우스로 드래그 하지 못한다.*/
           user-select: none;
        }
    </style>
</head>
<body>
    <h1>클릭 횟수: 0</h1>
    <button id="connect">이벤트 연결</button>
    <button id="disconnect">이벤트 제거</button>
    <p>이벤트 연결 상태: 해제</p>
</body>
</html>

 

이벤트 연결 제거하기

 

07 - 1장의 내용은 여기서 마무리 된다.

 

이벤트와 관련된 기본 내용을 학습해 보았다.

 

내일은 07- 2 장의 내용을 정리해보자.

 

오늘 하루도 쌓였다.