혼자서 공부하는 자바스크립트 완독하기! (Chapter_07 문서 객체 모델)

운동하는 개발자·2022년 11월 17일
0
post-thumbnail

07. 문서 객체 모델

07-1. 문서 객체 조작하기

  • HTML = 요소
  • Javascript = 문서 객체 (Document Object)

DOMContentLoaded 이벤트

문서 객체를 조작할 때는 DOMContentLoaded 이벤트를 사용합니다.
<body> 태그가 생성되기 이전에 <head> 태그에서 <body>태그에 무언가 출력하려고 하면 아래와 같은 문제가 발생한다.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script>
            // HTML 태그를 쉽게 만들 수 있는 콜백 함수를 선언합니다.
            const h1 = (text) => `<h1>$(text)<h1>`
        </script>
        <script>
            document.body.innerHTML += h1('1번째 script 태그')
        </script>
    </head>
    <body>
        <script>
            document.body.innerHTML += h1('2번째 script 태그')
        </script>
        <h1>1번째 h1태그</h1>
        <script>
            document.body.innerHTML += h1('3번째 script 태그')
        </script>
        <h1>2번째 h1태그</h1>
    </body>
</html>

기본적으로 <head> 태그 내부에 script 태그를 배치하면 <body> 태그에 있는 문서 객체(요소)에 접근할 수 없습니다.

DOMContentLoaded 이벤트는 웹 브라우저가 문서 객체를 모두 읽고 나서 실행하는 이벤트 입니다.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script>
            document.addEventListener('DOMContentLoaded', () =>{
                const h1 = (text) => `<h1>${text}<h1>`
                    document.body.innerHTML += h1(`DOMcontentLoaded 이벤트 발생`)
            })
        </script>
    </head>
    <body>
        
    </body>
</html>

문서 객체 가져오기

선택자에 접근하는 메소드는 다음과 같다.

document.querySelector(선택자)
document.querySelectorAll(선택자)

글자 조작하기

예제들을 통해 innerHTML 속성과 textContent 속성을 사용하여 문서 객체 내부의 글자를 조작하였습니다.

  • 문서객체.textContent : 입력된 문자열을 그대로 넣습니다.
  • 문서객체.innerHTML : 입력된 문자열을 HTML 형식으로 넣습니다.
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <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>
    </head>
    <body>
        <div id="a"></div>
        <div id="b"></div>
        
    </body>
</html>

속성 조작하기

  • 문서객체.setAttribute(속성 이름, 값) : 특성 속성에 값을 지정합니다.
  • 문서객체.getAttribute(속성 이름) : 특정 속성을 추출합니다.

getAttribute() 메소드를 사용하지 않고도 '온점(.)'을 찍고 속성을 바로 읽어들이거나 지정할 수 있다.

스타일 조작하기

객체는 다음과 같은 방법으로 스타일을 조정할 수 있습니다.

h1.style.backgroundColor
h1.style['backgroundColor]
h1.style['background-color']

문서 객체 생성하기

문서 객체를 생성하기 위해서는 document.createElement() 메소드를 사용한다.

document.createElement(문서 객체 이름)

문서를 어떤 문서에 아래에 추가 할지를 지정 해줘야 한다. 이러한 그림을 프로그래밍에선 트리라고 부른다. 어떤 문서 객체가 있을때 위의 있는 것을 부모라고 하고 아래에 있는 것을 자식이라고 부릅니다.

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

부모객체.appendChild(자식객체)
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script>
            document.addEventListener('DOMContentLoaded', () => {
                const header = document.createElement('h1')

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

                document.body.appendChild(header)
            })
        </script>
    </head>
    <body>
        
    </body>
</html>

문서 객체 이동하기

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

문서 객체 제거하기

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

부모객체.removeChild(자식객체)
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script>
            document.addEventListener('DOMContentLoaded', () => {
                setTimeout(() => {
                    const h1 = document.querySelector('h1')

                    h1.parentNode.removeChild(h1)
                    // document.body.removeChild(h1)
                }, 3000)
            })
        </script>
    </head>
    <body>
        <hr>
        <h1>제거 대상 문서 객체</h1>
        <hr>
    </body>
</html>

이벤트 설정하기

document.addEventListener('DOMContentLoaded', () =>{})

위의 형태는 'document라는 문서 객체의 DOMContentLoaded 이벤트가 발생했을 때, 매게변수로 지정한 콜백 함수를 실행하라' 라는 의미이다.

이벤트를 발생하기 위해서는

문서객체.addEventListener(이벤트 이름, 콜백 함수)

07-2. 이벤트 활용

이벤트 모델

  • 이벤트를 연결하는 방법을 이벤트 모델이라고 부릅니다.
  • addEventListener()는 표준 이벤트 모델이다.
  • onOO는 고전 이벤트 모델이다.
  • HTML요소에 직접 넣어서 이벤트를 연결하는 것을 인라인 이벤트 모델이라 한다.

키보드 이벤트

  • keydown : 키가 눌릴 때 실행
  • keypress : 키가 입력 되었을 때 실행
  • keyup : 키보드에서 키가 떨어질 때 실행

'keydown', 'keypress' 이벤터는 웹 브라우저에 따라서 아시아권의 문자를 제대로 처리하지 못하는 문제가 있어 'keyup' 이벤트를 사용

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script>
            document.addEventListener('DOMCotnetLoaded', () => {
                const textarea = document.querySelector('textarea')
                const h1 = document.querySelector('h1')

                textarea.addEventListener('keyup', (event) => {
                    const length = textarea.value.length
                    h1.textContent = `글자 수: ${length}`
                })
            })    
        </script>
        
    </head>
    <body>
        <h1></h1>
        <textarea></textarea>
    </body>
</html>

키보드 키 코드 사용하기

키보드 이벤트가 발생할 때는 이벤트 객체로 어떤 키를 눌렀는지와 곤련된 속성들이 따라옵니다.

  • code : 입력한 키
  • keyCode : 입력한 키를 나타내는 숫자
  • altKey : Alt키를 눌렀는지
  • ctrlKey : Ctrl키를 눌렀는지
  • shiftKey : Shift키를 눌렀는지

이벤트 발생 객체

상황에 따라서는 이벤트 리스너 내부에서 그러한 변수에 접급할 수 없는 경우가 생긴다. 이럴경우 2가지 방법을 통해 외부의 변수에 접근한다.

    1. event.currentTarget 속성을 사용한다.
      이는 () =>{}와 function() {} 형태 모두 사용 가능
    1. this 키워드를 사용
      function() {} 형태에서만 사용 가능

글자 입력 양식 이벤트

입력 양식을 기반으로 inch를 cm단위로 변환하는 프로그램

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script>
            document.addEventListener('DOMContentLoaded', () => {
                const input = document.querySelector('input')
                const button = document.querySelector('button')
                const p = document.querySelector('p')

                button.addEventListener('click', ()=> {
                    const inch = Number(input.value)

                    if(isNaN(inch)){
                        p.textContent = '숫자를 입력하세요'
                        return
                    }

                    const cm = inch * 2.54
                    p.textContent = `${cm}cm`
                })
            })
        </script>
        
    </head>
    <body>
        <input type="text"> inch<br>
        <button>계산</button>
        <p></p>
    </body>
</html>

드롭다운 목록 활용하기

드롭다운 목록은 기본적으로 select 태그로 구현합니다. select 태그는 사용 방법이 조금 특이하다.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script>
            document.addEventListener('DOMContentLoaded', () => {
                const select = document.querySelector('select')
                const p = document.querySelector('p')

                select.addEventListener('change', (event) => {
                    const options = event.currentTarget.options
                    const index = event.currentTarget.options.selectedIndex

                    p.textContent = `선택: ${options[index].textContent}`
                })
            })
        </script>
        
    </head>
    <body>
        <select name="" id="">
            <option value="">떡볶이</option>
            <option value="">김밥</option>
            <option value="">튀김</option>
            <option value="">순대</option>
        </select>
        <p>선택: 떡볶이</p>
    </body>
</html>

코드를 실행하고 드롭다운 목록에서 항목을 선택하면 options[index]에서 선택한 option 태그가 출력이된다.

select 태그에 nultiple 속성을 부여하면 Ctrl 또는 Shift키를 누르고 여러 항목을 선택할 수 있다.

multiple select 손코딩 해보기

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script>
            document.addEventListener('DOMContentLoaded', () => {
                const select = document.querySelector('select')
                const p = document.querySelector('p')

                select.addEventListener('change', (event) => {
                    const options = event.currentTarget.options
                    const list = []

                    for (const option of options){
                        if (option.selected){
                            list.push(option.textContent)
                        }
                    }

                    p.textContent = `선택: ${list.join(',')}`
                })
            })
        </script>
        
    </head>
    <body>
        <select multiple>
            <option value="">떡볶이</option>
            <option value="">김밥</option>
            <option value="">튀김</option>
            <option value="">순대</option>
        </select>
        <p>선택: 떡볶이</p>
    </body>
</html>
profile
강인한 체력이 최고의 무기다.

0개의 댓글