Learn & Record

HTML CSS JS (버튼+함수, 이벤트핸들러, 연습문제, 이벤트핸들러 제거, DOMContentLoaded, 글자조작, 스타일조작, 속성조작, 문서객체생성, 문서객체이동, 문서객체삭제) 본문

Dev/HTML CSS JS

HTML CSS JS (버튼+함수, 이벤트핸들러, 연습문제, 이벤트핸들러 제거, DOMContentLoaded, 글자조작, 스타일조작, 속성조작, 문서객체생성, 문서객체이동, 문서객체삭제)

Walker_ 2024. 4. 2. 17:05

1. 버튼+함수

// // addEventListener 메서드는 동일한 요소에서 발생한 동일한 이벤트에 대해
// 하나 이상의 이벤트 핸들러를 등록할 수 있음
<body>
    <button>Click me!</button>
    <script>
        const btn = document.querySelector('button');

        // // addEventListener 메서드는 동일한 요소에서 발생한 동일한 이벤트에 대해
        // 하나 이상의 이벤트 핸들러를 등록할 수 있음
        btn.addEventListener('click', function () {
            console.log('[1] button click')
        })
        btn.addEventListener('click', function () {
            console.log('[2] button click')
        })
        function clickToCon() {
            console.log('[3] button click')
        }
        btn.addEventListener('click', clickToCon);
    </script>
</body>

 

2. 이벤트 핸들러 제거

 - addEventListener 메서드로 등록한 이벤트 핸들러를 제거할려면 EventTarget.prototype.removeEventListener() 메서드

 - removeEventListener 메서드에 전달할 인수는 addEventListener 메서드와 동일

 

 - 단, addEventListener 메서드에 전달된 인수와 removeEventListener 메서드에 전달한 인수가 일치하지 않으면

 - 이벤트 핸들러가 제거되지 않음

<body>
    <button>Click me!</button>
    <script>
        const btn = document.querySelector('button')

        const handleClick = () => console.log('button click')

        // 이벤트 핸들러 등록
        btn.addEventListener('click', handleClick)

        // 이벤트 핸들러 제거
        btn.removeEventListener('click', handleClick, true) // 실패
        btn.removeEventListener('click', handleClick) // 성공
    </script>
</body>

 

3. 연습문제

<body>
    <button id="plus">클릭</button>
    <button id="remover">제거</button>
    <button>Register!</button>
    <script>
        // 1. querySelector()로 요소 선택
        const plus = document.getElementById('plus')
        const remover = document.getElementById('remover')
        const btnRegister = document.querySelector('button:nth-child(3)');

        // 2. 클릭 버튼 이벤트 등록
        let count = 0;
        function handleClick() {
            ++count;
            alert(`${count}번 클릭했습니다.`)
        }
        plus.addEventListener('click',handleClick)

        // 3. 제거 버튼 이벤트 등록
        function handleRemove() {
            plus.removeEventListener('click', handleClick)
        }
        remover.addEventListener('click', handleRemove)

        // 4. 재등록 버튼 이벤트 등록
        btnRegister.addEventListener('click', () => {
            plus.addEventListener('click', handleClick)
        })
    </script>
</body>

 

 - 배경색 변경 + 초기화 문제

<body>
    <button>배경색 변경</button>
    <button>배경색 초기화</button>
</body>
<script>
    // 1. 요소 지정
    const colorChange = document.querySelector('button:nth-child(1)')
    const colorOne = document.querySelector('button:nth-child(2)')
    let color = ['white','red', 'orange', 'yellow', 'blue']

    // 2. 클릭 버튼 이벤트 등록
    let i = 1;
    const bodyTag = document.querySelector('body'); // body 태그를 불러옴

    function colorChan() {
        ++i;
        bodyTag.style.backgroundColor = color[i%color.length]; // body 태그의 backgroud-color를 변경

    }
    colorChange.addEventListener('click', colorChan)

    // 3. 색상 초기화 버튼 이벤트 등록

    function colorOneFun() {
        i = 1;
        bodyTag.style.backgroundColor = color[0];
    }
    colorOne.addEventListener('click', colorOneFun)
</script>

 

4. 이벤트 핸들러 익명함수 제거 

 - removeEventListener 메서드에 인수로 전달한 이벤트 핸들러는

 - addEventListener 메서드에 인수로 전달한 등록 이벤트 핸들러와 동일한 함수여야 함

 - 따라서 익명함수를 이벤트 핸들러로 등록한 경우에는 제거할 수 없음

 

 - 단, 기명 이벤트 핸들러 내부에서 removeEventListener 메서드를 호출하여 이벤트 핸들러를 제거하는 것은 가능

 - 이때 이벤트 핸들러는 한 번만 호출

<body>
    <button>Click me!</button>
    <script>
        const btn = document.querySelector('button')

        btn.addEventListener('click', function foo() {
            console.log('button click');

            // 이벤트 핸들러를 제거. 따라서 이벤트 핸들러는 단 한 번만 호출
            btn.removeEventListener('click', foo)
        })
    </script>
</body>
<body>
    <button>Click me!</button>
    <script>
        const btn = document.querySelector('button')
        const handleClick = () => console.log('button click')

        // 이벤트 핸들러 프로퍼티 방식으로 이벤트 핸들러 등록
        btn.onclick = handleClick;

        // removeEventListener 메서드로 이벤트 핸들러를 제거할 수 없음
        btn.removeEventListener('click', handleClick);

        // 이벤트 핸들러 프로퍼티에 null을 할당하여 이벤트 핸들러를 제거.
        btn.click = null;
    </script>
</body>

 

5. JS로 html 다루기

 - 자바 스크립트를 사용하는 목적은 html을 다루는 것

 - 자바 스크립트에서는 html 요소를 문서 객체 document object를 이용해 조작을 함

 - 문서 객체 모델 : Document Object Model

 - 문서 객체를 조합해서 만든 전체적인 형태

 

    <script>
        const h1 = (text) => `<h1>${text}</h1>`;
    </script>
    <script>
        /*
        head 태그 내부에 script 태그를 배치하면 body 태그에 있는 문서 객체(요소)에 접근할 수 없음
        head 태그 내부의 script 태그에서 body 태그에 있는 문서에 접근하려면 화면에 문서 객체(요소)를
        모두 읽어들일 때까지 기다려야 함
         */
        document.addEventListener('DOMContentLoaded', function () {
            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>

 

6. DOMContentLoaded 이벤트

 - DOMContentLoaded는 웹 브라우저가 문서 객체를 모두 일고 나서 실행하는 이벤트

 - DOMContentLoaded 이벤트를 연결. DOMContentLoaded 상태가 되었을 때 콜백 함수를 호출  

    <script>
        document.addEventListener('DOMContentLoaded', ()=> {
            const h1 = (text) => `<h1>${text}</h1>`;
            document.body.innerHTML += h1('DOMContentLoaded 이벤트 발생');
        })
    </script>
</head>
<body>
</body>

 

    <script>
        document.addEventListener('DOMContentLoaded', function () {
            // 1. 요소 지정
            const colorChange = document.querySelector('button:nth-child(1)')
            const colorOne = document.querySelector('button:nth-child(2)')
            let color = ['white','red', 'orange', 'yellow', 'blue']

            // 2. 클릭 버튼 이벤트 등록
            let i = 1;
            const bodyTag = document.querySelector('body'); // body 태그를 불러옴

            function colorChan() {
                ++i;
                bodyTag.style.backgroundColor = color[i%color.length]; // body 태그의 backgroud-color를 변경

            }
            colorChange.addEventListener('click', colorChan)

            // 3. 색상 초기화 버튼 이벤트 등록

            function colorOneFun() {
                i = 1;
                bodyTag.style.backgroundColor = color[0];
            }
            colorOne.addEventListener('click', colorOneFun)
        });
    </script>
</head>
<body>
    <button>배경색 변경</button>
    <button>배경색 초기화</button>
</body>

 

    <script>
        document.addEventListener('DOMContentLoaded', function () {
            // 1. querySelector()로 요소 선택
            const plus = document.getElementById('plus')
            const remover = document.getElementById('remover')
            const btnRegister = document.querySelector('button:nth-child(3)');

            // 2. 클릭 버튼 이벤트 등록
            let count = 0;
            function handleClick() {
                ++count;
                alert(`${count}번 클릭했습니다.`)
            }
            plus.addEventListener('click',handleClick)

            // 3. 제거 버튼 이벤트 등록
            function handleRemove() {
                plus.removeEventListener('click', handleClick)
            }
            remover.addEventListener('click', handleRemove)

            // 4. 재등록 버튼 이벤트 등록
            btnRegister.addEventListener('click', () => {
                plus.addEventListener('click', handleClick)
            })
        })
    </script>
</head>
<body>
    <button id="plus">클릭</button>
    <button id="remover">제거</button>
    <button>Register!</button>
</body>

 

7. 문서 객체

 - document.head, document.body, document.title 등을 이용

 - head와 body 요소 내부에 만든 다른 요소들은 다음과 같은 별도의 메소드를 사용해서 접근

 - document.querySelector(선택자) : 요소를 하나만 추출

 - document.querySelectorAll(선택자) : 선택자에 해당하는 모든 문서 객체를 배열로 가져옴

 

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>
        document.addEventListener('DOMContentLoaded', ()=> {
            const header = document.querySelector('h1'); // 요소를 읽어들임. 제일 먼저 나오는 요소 하나만 가져옴
            //텍스트와 스타일을 적용
            header.textContent = 'HEADERS';
            header.style.color = 'white';
            header.style.backgroundColor = 'skyblue'
            header.style.padding= '10px'
            header.style.textAlign = 'center'

            const headersAll = document.querySelectorAll('h2') // 요소들 읽어들임
            console.log(headersAll);
            headersAll.forEach((item) => { // 일반적으로 forEach() 메소드를 사용해서 반복을 돌림
                item.textContent = 'headersAll';
                item.style.color = 'white';
                item.style.backgroundColor = '#4caf50'
                item.style.padding = '20px'
            })
        });
    </script>
</head>
<body>
    <h1></h1>
    <h1>2</h1>
    <h2></h2>
    <h2></h2>
    <h2></h2>
    <h2></h2>
</body>
</html>

 

 

// 1. for 문을 사용해서 글자색을 빨강으로 변경
for (let i = 0; i<headersAll.length; i++) {
    headersAll[i].style.color = 'red'
}

// 2. for in 문을 사용해서 글자색을 파라으로 변경
for (let item in [...headersAll]) {
    headersAll[item].style.color = 'blue'
}
// 3. for of 문을 사용해서 글자색을 주황으로 변경
for (let item of headersAll) {
    item.style.color = 'orange'
}

 

 

8. 글자 조작

 - 문서 내부의 글자를 조작할때는 textContent, innerHTML 속성 사용

 - 문서객체.textContent : 입력된 문자열을 그대로 넣어줌

 - 문서객체.innerHTML : 입력된 문자열을 HTML 형식으로 넣어줌

 

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>
        document.addEventListener('DOMContentLoaded', ()=> {
            const a = document.getElementById('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>

 

 

9. 스타일 조작

 - 자바스크립트의 style 속성들의 이름이 CSS에서 사용할 때와 차이가 있음

 - 자바스크립트에서는 -가 연산자이고, 식별자에 사용할 수 없어서 두 단어의 조합은 캐멀 케이스로 표현

 - background-color : backgroudColor

 - text-align : textAlign

 - font-size : fintSize

 

 - 스타일 조정하는 방법

 - h1.style.backgroundColor -> 이 형태를 가장 많이 사용.

 - h1.style['backgroundColor']

 - h1.style['background-color']

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>
        /*
        * 스타일 조작하기
        *
         */
        document.addEventListener('DOMContentLoaded', () => {
            const divs = document.querySelectorAll('body > div');

            divs.forEach((div, index) => { // div개수 만큼 반복 출력
                console.log(div, index);
                const val = index * 10; // index는 0부터 24까지 반복
                div.style.height = `10px`; //  크기를 지정할 때는 반드시 단위를 붙여줘야 함
                div.style.backgroundColor = `rgba(${val},${val},${val})`;
            })
        });
    </script>
</head>
<body>
    <!-- div 태그 25개 -->
    <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>
</html>

 

 

10. 속성 조작하기

 - 문서 객체의 속성을 조작할 때는 다음과 같은 메소드를 사용

 - 문서객체.setAttribute(속성 이름, 값) : 특성 속성에 값을 지정

 - 문서객체.getAttribute(속성 이름) : 특성 속성에 값을 추출

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>
        document.addEventListener('DOMContentLoaded', () => {
            const rects = document.querySelectorAll('.rect'); // 클래스 선택자 이용

            for (let i = 0; i < rects.length; i++) {
                const width = (i + 1) * 100; // 100, 200, 300, 400의 너비를 가짐
                const src = `http://placebear.com/${width}/250`
                rects[i].setAttribute('src', src); // src 속성에 값을 지정
            }

            // foreach() 메서드로 동일한 작업
            rects.forEach((item, i)=>{
                const width = (i+1) * 100;
                const src = `http://placebear.com/250/${width}`
                item.setAttribute('src',src);
            })
        })
    </script>
</head>
<body>
    <img class="rect" alt="" src="">
    <img class="rect" alt="" src="">
    <img class="rect" alt="" src="">
    <img class="rect" alt="" src="">
</body>
</html>

 

 

 

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        #galleryZone {
            text-align: center;
        }
    </style>
    <script>
        document.addEventListener('DOMContentLoaded', () => {
            const back = document.querySelector('.back')
            const next = document.querySelector('.next')
            const logo = document.querySelector('.logo')
            let num = 1;
            back.addEventListener('click', () => {
                if (num === 1) {
                    alert('첫 이미지입니다.')
                    num = 9;
                } else {
                    num--;
                }
                logo.setAttribute('src', 'images/pic_' + num + '.jpg') // id값이 photo인 요소의 src 속성을 변경

            })

            next.addEventListener('click', () => {
                if (num === 9) alert('마지막 이미지입니다.');
                num === 9 ? num = 1 : num++;
                logo.setAttribute('src', 'images/pic_' + num + '.jpg') // id값이 photo인 요소의 src 속성을 변경

            })
            logo.setAttribute('src', 'images/pic_' + num + '.jpg') // id값이 photo인 요소의 src 속성을 변경

            })
    </script>
</head>
<body>
    <div id="galleryZone">
        <p><img class="logo" src="" id="photo" alt=""></p>
        <p>
            <button class="back">이전</button>
            <button class="next">다음</button>
        </p>
    </div>

</body>
</html>

 

11.  연습문제

    <script>
        document.addEventListener('DOMContentLoaded', () => {
            const redBtn = document.querySelector('#apple2')
            const orangeBtn = document.querySelector('#banana2')
            const yellowBtn = document.querySelector('#orange2')
            const list = document.querySelector('ul')

            redBtn.addEventListener('click', () => {
                list.style.color = 'red'
            })
            orangeBtn.addEventListener('click', () => {
                list.style.color = 'orange'
            })
            yellowBtn.addEventListener('click', () => {
                list.style.color = 'yellow'
            })
        })
    </script>
<body>
    <ul>
        <li id="apple">Apple</li>
        <li id="banana">Banana</li>
        <li id="orange">Orange</li>
    </ul>
    <div>
        <button id="apple2">red</button>
        <button id="banana2">orange</button>
        <button id="orange2">yellow</button>
    </div>

</body>

 

 

    <script>
        document.addEventListener('DOMContentLoaded', () => {
            const btns = document.querySelectorAll('div button');
            const fruits = document.querySelectorAll('ul li')
            const colors = ['red', 'orange', 'yellow'];

            btns.forEach((item, index) => {
                item.addEventListener('click', ()=>{
                    fruits.forEach((item) => {
                        item.style.color = colors[index]
                    })
                })
            })
        })
    </script>
<body>
    <ul>
        <li id="apple">Apple</li>
        <li id="banana">Banana</li>
        <li id="orange">Orange</li>
    </ul>
    <div>
        <button id="apple2">red</button>
        <button id="banana2">orange</button>
        <button id="orange2">yellow</button>
    </div>
</body>

 

12. 문서 객체 생성하기

 

 - creatElement()

 - body 태그 내부에 있는 특정 문서 객체를 읽어들이고 조작하는 것도 가능하나

 - 문서 객체를 생성하는 것도 가능

 - 문서 객체를 생성하고 싶을 때는 document.createElement() 메소드를 사용 

 

 - appendChild()

 - 문서 객체를 만든 후에는 문서 객체를 추가해야 함

 - appendChild() 메소드를 활용하면 어떤 부모 객체 아래에 자식 객체를 추가할 수 있음

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

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
    <script>
        // createElement() 메소드로 h1 태그를 생성하고, appendChild()를 사용하여 객체를 추가
        document.addEventListener('DOMContentLoaded', () => {
            // 문서 객체 생성하기
            const header = document.createElement('h1');

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

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

</body>
</html>

 

13. 문서 객체 이동하기

 - appendChild() 메소드를 사용하면 문서 객체를 이동할 수도 있음

 - 문서 객체를 다른 문서 객체에 추가하면 문서 객체가 이동

<script>
    document.addEventListener('DOMContentLoaded', () => {
        // 문서 객체 읽어들이고 생성하기
        const divA = document.querySelector('#first'); // id 속성이 first인 태그를 반환
        const divB = document.getElementById('second') // id 속성이 second인 태그를 반환

        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, 1000); // 1초 후에 toSecond() 함수를 실행
        }
        toFirst();
    })
</script>
<body>
    <div id="first">
        <h1>첫 번째 div 태그 내부</h1>
    </div>
    <hr>
    <div id="second">
        <h1>두 번째 div 태그 내부</h1>
    </div>

</body>

 

14. 문서 객체 삭제하기

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

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

 

 - appendChild()메소드 등으로 부모 객체와 이미 연결이 완료된 문서 객체의 경우 parentNode 속성으로

 - 부모 객체에 접근할 수 있으므로, 일반적으로 어떤 문서 객체를 제거할 때는 다음과 같은 형태의 코드 사용

 - 문서 객체.parentNode.removeChild(문서 객체);

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>
        document.addEventListener('DOMContentLoaded', ()=> {
            setTimeout(() => {
                const h1 = document.querySelector('h1');
                h1.parentElement.removeChild(h1);
            }, 3000);
        })
    </script>
</head>
<body>
    <hr>
    <h1>제거 대상 문자 객체</h1>
    <hr>
</body>
</html>

 

15. 연습문제

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            list-style: none;
        }
    </style>
    <script>
        document.addEventListener('DOMContentLoaded', () => {
            let rainbow = ['red', 'orange', 'yellow', 'green', 'blue','indigo','violet']
            const btn = document.querySelector('button');
            const ulTag = document.querySelector('ul')
            let cnt = 0;

            btn.addEventListener('click', function () {
                const liTag = document.createElement('li');

                liTag.setAttribute('class', rainbow[cnt % rainbow.length]);

                liTag.textContent = rainbow[cnt % rainbow.length];
                liTag.style.backgroundColor = rainbow[cnt++ % rainbow.length]
                liTag.style.color = 'white';

                if (cnt > rainbow.length) {
                    const firstLi = document.querySelector('ul li:nth-child(1)')
                    firstLi.parentNode.removeChild(firstLi)
                }
                ulTag.appendChild(liTag)
            })
        })
    </script>
</head>
<body>
<button>무지개색 추가</button>
<ul>

</ul>
</body>
</html>

 

 

 


공부 과정을 정리한 것이라 내용이 부족할 수 있습니다.

부족한 내용은 추가 자료들로 보충해주시면 좋을 것 같습니다.

읽어주셔서 감사합니다 :)