✿∘˚˳°∘°

43일차 : [실습]DOM / BOM 본문

국비수업/JavaScript

43일차 : [실습]DOM / BOM

_HYE_ 2023. 1. 30. 00:02

20230127

 

1. DOM실습

 

[ 실습 1 ]

<!DOCTYPE html>
<html lang="ko">
<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>실습1</title>
    <style>
        .examzone{
            width: 500px;
            padding: 50px;
            border: 1px solid black;
            margin-bottom: 20px;
            background-color: cornsilk;
        }
        #result{
            color:cornsilk;
        }
    </style>
</head>
<body>
    <h1>실습1</h1>
    <p>다음 문제를 보고 요구하는 함수를 작성해주세요.</p>
    <hr>
    <h3>문제 1. 다음 정보를 본인정보 prompt로 입력받아 수정하세요.</h3>
    <div class="examzone">
        <div>
            <span>이름 : </span>
            <span id="name">김유저</span>
        </div>
        <div>
            <span>나이 : </span>
            <span id="age">20</span>
        </div>
        <div>
            <span>주소 : </span>
            <span id="addr">서울</span>
        </div>
    </div>    
    <button id="q1">정보수정하기</button>
    <hr>
    <h3>문제 2. 숫자를 입력하고 결과확인버튼을 누르는경우 홀수인지 짝수인지 구별하고, 숫자가 아닌경우 숫자가 아니라고 결과를 출력 하세요.</h3>
    <div class="examzone">
        <span>결과 : </span>
        <span class="result">결과출력공간</span>
    </div>
    <label for="input1">숫자 입력 : </label>
    <input type="text" name="input1" id="input1" size="55">
    <button id="q2">결과확인</button>
    <hr>
    <h3>문제 3. 아래 이미지를 클릭했을 때 angel.png 이미지로 변경해주세요.</h3>
    <img src="img/smile.jpg">
    <hr>
    <h3>문제 4. 아래 영역의 글씨색과 배경색이 동일해서 보이지 않습니다. 글씨색을 navy로 변경해주세요.</h3>
    <div class="examzone">
        <span id="result">수고하셨습니다.</span>
    </div>
    <button id="q4">결과확인</button>

    <script src="js/01_exam1.js"></script>
</body>
</html>
const btn1 = document.querySelector("#q1");
btn1.onclick = function(){
    const name = prompt("이름");
    const age = prompt("나이");
    const addr = prompt("주소");

    const updateName = document.querySelector("#name");
    const updateAge = document.querySelector("#age");
    const updateAddr = document.querySelector("#addr");
    //주의점 : getElementById의 경우 id로 가져올거라고 명시했기 때문에 #name으로 가져오면 안된다.
    //        querySelector는 선택자를 가져오는것이므로 #name로 가져오는게맞음!(각 선택자에 맞춰서)
    updateName.innerText = name;
    updateAge.innerText = age;
    updateAddr.innerText = addr;
    //innerHTML을 사용해도 달라지는건 없지만 태그는 변경할 게 없으므로 innerText사용
}

const btn2 = document.querySelector("#q2");
btn2.onclick = function(){
    const input = document.querySelector("#input1");
    inputNum = input.value;
    //value를 붙이지 않으면 input값이 아닌 input태그를 지칭

    const msg = document.querySelector(".result");
    if(isFinite(inputNum)){
        if(inputNum%2 == 0){
            msg.innerText = "짝수";
        }else if(inputNum%2 != 0){
            msg.innerText = "홀수";
        }
    }else{
        msg.innerText = "잘못입력";
    }
    input.value = "";
    //입력 후 버튼을 누르면 clear되는 효과를 위해
}

const btn3 = document.querySelector("img");
btn3.onclick = function(){
    const img = document.querySelector("img");
    img.src = "img/angel.png";
    
}

const btn4 = document.querySelector("#q4");
btn4.onclick = function(){
    const result = document.querySelector("#result");
    result.style.color = "navy";
}

결과화면

 

[ 실습 2 ]

<!DOCTYPE html>
<html lang="ko">
  <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>실습2</title>
    <style>
      fieldset {
        width: 400px;
        text-align: center;
        background-color: #ebebeb;
      }
      .searchBox {
        width: 500px;
        height: 50px;
        margin: 10px;
        padding: 10px;
        background-color: khaki;
        display: none;
      }
    </style>
  </head>
  <body>
    <h1>실습2</h1>
    <p>라디오 버튼에 따른 검색창을 나오게 해주세요.</p>
    <hr />
    <fieldset>
      <legend>검색할 항목을 선택하세요.</legend>
      <input type="radio" name="search" id="title" value="title" />
      <label for="title">제목</label>
      <input type="radio" name="search" id="date" value="date" />
      <label for="date">날짜</label>
      <input type="radio" name="search" id="writer" value="writer" />
      <label for="writer">작성자</label>
    </fieldset>
    <hr />
    <div id="titleBox" class="searchBox">
      <form action="" method="post">
        <label>검색할 제목을 입력하세요</label>
        <br />
        <input type="text" name="title" size="50" />
        <input type="submit" value="검색" />
      </form>
    </div>
    <div id="dateBox" class="searchBox">
      <form action="" method="post">
        <label>검색할 날짜를 입력하세요</label>
        <br />
        <input type="date" name="start" />
        ~
        <input type="date" name="end" />
        <input type="submit" value="검색" />
      </form>
    </div>
    <div id="writerBox" class="searchBox">
      <form action="" method="post">
        <label>작성자를 입력하세요</label>
        <br />
        <input type="text" name="wirter" size="30" />
        <input type="submit" value="검색" />
      </form>
    </div>
    <script src="js/02_exam2.js"></script>
  </body>
</html>

- 로직 및 일반for문

/*
const title = document.querySelector("#title");
title.onclick = function(){
    searchBox[0].style.display = "block";
    searchBox[1].style.display = "none";
    searchBox[2].style.display = "none";
}

const date = document.querySelector("#date");
date.onclick = function(){   
    searchBox[0].style.display = "none";
    searchBox[1].style.display = "block";
    searchBox[2].style.display = "none";
}

const writer = document.querySelector("#writer");
writer.onclick = function(){
    searchBox[0].style.display = "none";
    searchBox[1].style.display = "none";
    searchBox[2].style.display = "block";
}
*/

const radio = document.querySelectorAll("[type=radio]");
//[type=radio] 또는 [name=search]
/*
for(let i=0; i<radio.length; i++){
    radio[i].onclick = function(){
        for(let j=0; j<searchBox.length; j++){
            if(i == j){
                searchBox[j].style.display = "block";
            }if(i != j){
                searchBox[j].style.display = "none";
            }
        }
    }
}
*/
/*
for(let i=0; i<radio.length; i++){
    radio[i].onclick = function(){
        searchBox.forEach(function(item){
            item.style.display = "none";
        });
        const id = radio[i].id;
        const showBox = document.querySelector("#"+id+"Box");
        searchBox.style.display = "block";
    }
}
*/

- forEach문을 사용한 최종코드

const searchBox = document.querySelectorAll(".searchBox");
radio.forEach(function(button, i){
    button.onclick = function(){
        searchBox.forEach(function(box, j){
            if(i == j){
                box.style.display = "block";
            }if(i != j){
                box.style.display = "none";
            }
        });
    }
});

 

[ 실습 3 ]

<!DOCTYPE html>
<html lang="ko">
  <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>실습3</title>
    <style>
      .divs {
        width: 100px;
        height: 100px;
        float: left;
        border: 1px solid black;
      }
      #red {
        background-color: red;
      }
      #blue {
        background-color: blue;
      }
      #green {
        background-color: green;
      }
      #pink {
        background-color: pink;
      }
      #yellow {
        background-color: yellow;
      }
    </style>
    
  </head>
  <body>
    <h1>실습3</h1>
    <p>
      1. 클릭한 div는 화면에서 사라짐 <br />
      2. 5개 모두 클릭하면 다시 화면에 나옴 <br />
      3. 화면에 다시 출력될땐 이전에 클릭에서 사라진 순서 그대로 나와야함
    </p>
    <fieldset>
      <legend>보기</legend>
      <div id="divWrap">
        <div class="divs d1" id="red"></div>
        <div class="divs d2" id="blue"></div>
        <div class="divs d3" id="green"></div>
        <div class="divs d4" id="pink"></div>
        <div class="divs d5" id="yellow"></div>
      </div>
    </fieldset>
    <script src="js/03_exam3.js"></script>
  </body>
</html>

- 방법1. display : none 을 사용하고 div의 id값을 변경해주는 방법

///////////////////////////////////////////////////////////
//방법 1 : id를 변경하여 색상변경
///////////////////////////////////////////////////////////
// let count = 0; 카운트를 넣으면 순서대로 나오게할 수 없음
// 배열의 순서는 변화하지 않으므로
let arr = new Array();
divs.forEach(function(item){
    item.onclick = function(){
        item.style.display = "none";
        //count++;
        const id = item.id;
        arr.push(id);
        if(arr.length == 5){
            arr.forEach(function(color, i){
                const div = document.querySelector("#"+color);
                div.style.display = "block";
                //div에 누른순서대로 들어가긴 하지만 
                //none이었던 display가 block로 바뀔 뿐 div순서가 변화하는게 아니므로
                //클릭순서대로 나오지않는다
                //이경우엔 id의 색 자체가 변경되어야함
                div.id = arr[i];
            });
            arr = new Array();
        }
    }
});

- 방법2. div를 새배열에 저장 후 기존div는 삭제 -> 삭제되어들어간 순서대로 다시appendChild를 통해 나오게함

const divs = document.querySelectorAll(".divs");

let ckDivs = new Array();
divs.forEach(function(divBox){
    divBox.onclick = function(){
        ckDivs.push(divBox);
        divBox.remove();
        if(ckDivs.length == 5){
            const divWrap = document.querySelector("#divWrap");
            ckDivs.forEach(function(ckDivBox){
                divWrap.appendChild(ckDivBox);
            });
            ckDivs = new Array();
        }
    }
});
// display를 사용하는 방법과의 차이점 
// 아까는 id값을 변경해줫다면 지금은 div의 순서를 변경해준것

-- 방법2의 로직 + 일반for문 버전

divs[0].onclick = function(){
    divs[0].remove();
}
divs[1].onclick = function(){
    divs[1].remove();
}
divs[2].onclick = function(){
    divs[2].remove();
}
divs[3].onclick = function(){
    divs[3].remove();
}
divs[4].onclick = function(){
    divs[4].remove();
}
/*
일반 for문
for(let i=0; i<divs.length; i++){
    divs[i].onclick = function(){
        ckDivs.push(divs[i]);
        divs[i].remove();
        if(ckDivs.length == 5){
            const divWrap = document.querySelector("#divWrap");
            for(let j=0; j<ckDivs.length; j++){
                divWrap.appendChild(ckDivs[j]);
            }
            ckDivs = new Array();
        }
    }
}

-방법3 : 재귀함수

const divs = document.querySelectorAll(".divs");
let arr = new Array();

divs.forEach(function(item){
    item.onclick = function(){
        removeFunc(item);
    }
});

function removeFunc(item){
    item.remove();
    const id = item.id;
    arr.push(id);
    if(arr.length == 5){
        arr.forEach(function(color, index){
            //<div></div>
            const div = document.createElement("div");
            //<div class="divs" id="배열순서대로색상"></div>
            div.setAttribute("class", "divs");
            div.id = color;

            div.onclick = function(){
                //재귀함수
                //자기가 자기자신을 호출
                //새로만들어지면 주소가 달라지기때문에 새로만들어줘야함
                removeFunc(div);
            }
            const divWrap = document.querySelector("#divWrap");
            divWrap.appendChild(div);
        });
        arr = new Array();
    }
}

 

2. BOM

<!DOCTYPE html>
<html lang="en">
<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>BOM</title>
    <!--
    <script src="js/09_bom.js"></script>
    여기에 js파일이 있으면 에러발생 + 실행안됨
    -->
    <!-- btn6에 해당하는것만 옮김-->
    <script>
        //navigator의 위경도를 저장할 전역변수
        let lat;
        let lng;

        //onload 방법1
        //이게없으면 이 코드가 동작할때 html이 만들어지기 전이므로 btn6가 없어서 null에러가 발생
        window.onload = function(){
            //위치와 상관없이 html요소들이 전부 화면에 나타날 때(만들어지고나면) 딱 한번 실행되는게 onload
            const btn6 = document.querySelector("#btn6");
            //onload를 사용할 줄 모르면 스크립트를 아래쪽에 두는게 좋다.
            btn6.onclick = function(){
            console.log("onload 버튼 클릭");
            }

            const btn8 = document.querySelector("#btn8");
            btn8.onclick = function(){
                console.log("화면 높이값 : "+screen.height);
                console.log("화면 너비값 : "+screen.width);
                console.log("실제 사용 가능한 높이 : "+screen.availHeight);
                console.log("실제 사용 가능한 너비 : "+screen.availWidth);
                console.log("사용가능한 색상 수"+screen.colorDepth);
                console.log("한 픽셀당 비트 수 : "+screen.pixeDepth);
            }

            const btn9 = document.querySelector("#btn9");
            btn9.onclick = function(){
                location.href = "http://www.naver.com"; 
                //페이지이동에 사용
                //자바스크립트가 없으면 <a href> 또는 <form>을 통해 이동시켜줘야하는데 
                //있을경우 어떤태그를 클릭하더라도 이동할 수 있게 해준다.
            }

            const btn10 = document.querySelector("#btn10");
            btn10.onclick = function(){
                location.reload(); 
                //현재페이지 새로고침
            }

            //현재 화면 로드가 완료되면 현위치의 위도/경도를 구해서 변수에 저장
            //getCurrentPositoin : 내 현재위치를 조회 -> 매개변수로 준 함수에 해당 조회정보를 전달
            navigator.geolocation.getCurrentPosition(showMyLocation);
            const btn11 = document.querySelector("#btn11");
            btn11.onclick = function(){
                console.log(lat);
                console.log(lng);
            }
        }
        //onload밖에 생성
        function showMyLocation(position){
            lat = position.coords.latitude;
            lng = position.coords.longitude;
        }
        //onload 방법2
        function func1(){
            const btn6 = document.querySelector("#btn6");
            console.log(btn6);
            //위와달리 이 상태에서는 정상적으로 불러올 수 있다
            //가능한 이유
            //선언적함수의 경우 위치와 상관없이 가장먼저 만들어진다 - 버튼을 누르면 버튼을 누를 때 가져옴
            //버튼을 누른 그 순간btn6을 가져옴 -> 이시점에는 이미 btn6이 만들어져 있기 때문에 가능하다.
        }
    </script>
    <style>
        #time-zone{
            padding: 50px;
            font-size: 50px;
            font-weight: bold;
        }
    </style>
</head>
<body>
    <h1>BOM(Browser Object Model)</h1>
    <hr>
    <h3>window.open : 높이와 너비를 입력해서 새창을 띄움</h3>
    <pre>버튼같은걸 눌렀을 때 작은window를 새로 여는기능(옛날방식의 아이디중복체크등에 사용)</pre>
    <h3>window.setTimeout : 일정 시간 후 함수를 한번 실행/id리턴</h3>
    <pre>일정시간 후 행동(함수)을 실행하게 만듬</pre>
    <h3>window.clearTimeout : setTimeout을 종료</h3>
    <h3>window.setInterval : 일정시간마다 함수를 반복해서 실행/id리턴</h3>
    <pre>홈페이지내의 시계 등에 사용 1초마다 현재시간을 읽어서 화면에 띄우는것</pre>
    <h3>window.clearInterval : setInterval 종료</h3>
    <h3>window.onload : 화면에 요소들이 로드가 완료되면 자동으로 실행되는 함수</h3>
    <button id="btn1">open</button>
    <button id="btn2">setTimeout</button>
    <button id="btn3">clearTimeout</button>
    <button id="btn4">setInterval</button>
    <button id="btn5">clearInterval</button>
    <button id="btn6">onload</button>
    <button id="timeStart">시계 시작</button>
    <button id="timeStop">시계 정지</button>
    <button id="btn7" onclick=func1();>테스트버튼</button>
    <p id="time-zone"></p>
    <hr>
    <h3>screen : client 운영체제 화면속의 속성값을 갖는 객체</h3>
    <h3>location : 브라우저 주소표시줄(URL)과 관련된 객체</h3>
    <h3>navigator : 브라우저에 대한 정보</h3>
    <button id="btn8">screen</button>
    <button id="btn9">location.href</button>
    <button id="btn10">location.reload</button>
    <button id="btn11">현재 위/경도 조회</button>
    <script src="js/09_bom.js"></script>
</body>
</html>
const btn1 = document.querySelector("#btn1");
btn1.onclick = function(){
    /*
        window.open(param1, param2, param3);
        param1 : 주소(새창에서 열릴 페이지의 주소)
        param2 : 열리는방식 or 창의이름 
        param3 : 옵션(크기 등)
    */
    window.open("http://www.naver.com", "_blank", "width=500, height=500");
}

let timeoutId; //clearTimeout에서 사용하기 위해 전역변수로
const btn2 = document.querySelector("#btn2");
btn2.onclick = function(){
    /*
        window.setTimeout(param1, param2);
        param1 : 지정시간 후 실행될 함수
        param2 : 시간(ms)
    */
    //setTimeout을 사용하면 id라는걸 리턴함(예약아이디를 주는것)
    timeoutId = window.setTimeout(function(){
        //함수내용을 바로 쓰기위해
        alert("집갈래");
    }, 1000*5 );
}

const btn3 = document.querySelector("#btn3");
btn3.onclick = function(){
    //반드시 setTimeout을 통해 리턴된 아이디값을 매개변수로 줘야한다
    window.clearTimeout(timeoutId);
}

const btn4 = document.querySelector("#btn4");
let clearId;
btn4.onclick = function(){
    /*
        window.setInterval(param1, param2);
        param1 : 지정 시간마다 반복해서 실행할 함수
        param2 : 시간(ms)
    */
    clearId = window.setInterval(function(){
        console.log("3초마다 반복되는 함수!!");
    }, 3*1000);
    // 주의점 : 버튼을 누를때마다 interval이 쌓여서 중첩되어 넘어간다
    // 누를 때마다 clearId가 들어가기 때문에 겹쳐지므로 여러번 누르면 clearInterval사용불가
    // 이런경우가 없어야하지만 만일 발생할 경우
    // id변수를 배열로만들어서 push로 넣고 한번에 멈추게 해야한다.
}
const btn5 = document.querySelector("#btn5");
btn5.onclick = function(){
    window.clearInterval(clearId);
}

const timeStart = document.querySelector("#timeStart");
let timeId;
timeStart.onclick = function(){
    timeId = window.setInterval(function(){
        const date = new Date();
        const currentTime = date.getHours()+" : "+date.getMinutes()+" : "+date.getSeconds()+"."+date.getMilliseconds();
        const timeZone = document.querySelector("#time-zone");
        timeZone.innerText = currentTime;
    }, 1/1000);
}

const timeStop = document.querySelector("#timeStop");
timeStop.onclick = function(){
    window.clearInterval(timeId);
}

'국비수업 > JavaScript' 카테고리의 다른 글

46일차 : [실습] 단계형 회원가입 만들기  (0) 2023.02.02
45일차 : [실습] 상품상세페이지만들기  (0) 2023.02.02
44일차 : EVENT  (0) 2023.01.30
42일차 : DOM  (0) 2023.01.26
41일차 : JavaScript의 기본  (0) 2023.01.25
Comments