학원 65일차 - JavaScript

·2021년 7월 12일
0

2021.06.28

ex30_timer.html

Timer

<!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>Document</title>
</head>
<body>
   <!--  
      타이머, timer
   -->
   <h1>Timer</h1>

   <form name="form1">
      <input type="text" name="txt1" placeholder="10초내에 입력하세요.">
      <hr>
      <input type="button" value="버튼1" name="btn1">
      <input type="button" value="버튼2" name="btn2">
      <input type="button" value="버튼3" name="btn3">
      <hr>
      <input type="button" value="시작" name="btnStart">
      <input type="button" value="멈춤" name="btnStop">
      <hr>
      <img src="images/catty01.png" name="cat1">
      <hr>
      <input type="button" value="버튼4" name="btn4">
      <input type="button" value="버튼5" name="btn5">
      <input type="button" value="버튼6" name="btn6">

      <hr>

      <select name="sel1" size="5">
         <option>하나</option>
         <option></option>
         <option></option>
         <option></option>
         <option>다섯</option>
      </select>
      <input type="button" value="삭제" name="btnDelete">

   </form>

   <script>
      
      var txt1 = document.form1.txt1;
      var btn1 = document.form1.btn1;
      var btn2 = document.form1.btn2;
      var btn3 = document.form1.btn3;
      var btn4 = document.form1.btn4;
      var btn5 = document.form1.btn5;
      var btn6 = document.form1.btn6;

      var cat1 = document.images['cat1'];

      var btnStart = document.form1.btnStart;
      var btnStop = document.form1.btnStop;

      var sel1 = document.form1.sel1;
      var btnDelete = document.form1.btnDelete;




      //타이머
      // - window 객체 메소드
      
      // - number setTimeout(함수, 시간(ms))
      //    - 해당 함수 실행 후 지정한 시간이 되는 순간 함수를 실행한다.
      //    - 1회 실행
      // - void clearTimeout(타이머 ID) -> 동작 중인 타이머를 없애주는 일을 한다. 

      // - number setInterval(함수, 시간(ms))
      //    - 해당 함수 실행 후부터 지정한 시간마다 함수를 실행한다.
      //    - 반복 실행
      // - void clearInterval(타이머 ID)
      //    - 타이머 ID : number setInterval(함수, 시간(ms))의 반환값. 고유ID

      btn1.onclick = function() {
         setTimeout(function () {
            alert('확인');
         }, 3000); // 3초
      };

      btn2.onclick = function() {
         setInterval(function() {
            alert('확인');
         }, 3000);
      };

      btn3.onclick = function() {
         // setTimeout(function() {
         //    txt1.size += 10;
         // }, 3000);

         // 버튼 누르면 바로 실행
         var now = new Date();
         txt1.value = now.toLocaleTimeString();

         // 1초마다 실행
         setInterval(function() {   
            var now = new Date(); // 현재 시간
            txt1.value = now.toLocaleTimeString(); // 시분초
         }, 1000); //1초마다 함수 실행
      };

      // 페이지가 들어오자마자 바로 실행
      // var now = new Date();
      // txt1.value = now.toLocaleTimeString();

      // 페이지가 로딩되고 1초마다 실행
      // setInterval(function() {   
      //    var now = new Date();
      //    txt1.value = now.toLocaleTimeString();
      // }, 1000); //1초마다 함수 실행


      // ------------------------------------------------


      // 전역 변수는 페이지가 화면에 보이는 동안은 계속 살아있다.
      //    - 멈춤 버튼 눌러도 멈춘 숫자에서 이어져서 동작하는 이유(자기 값을 계속 이어서 관리)
      var n = 1;
      var timer = 0; // 타이머 1개 기억. 타이머 ID(중복되지 않는 고유값)
      var timerList = []; // 타이머 N개 기억 - 배열
         
      // 개발자가 아니라, 시스템이나 실행환경이 호출하는 함수(메소드)
      // 개발자가 원하는 시점에 바로 호출하는 것이 아니라 언젠가 어떤 조건이 만족했을 때 환경(시스템)이 호출하는 함수
      // - 콜백 함수(Callback Function), 콜백 메소드

      btnStart.onclick = function() {
         // timer = setTimeout(function() {
         //    txt1.value = n;
         // }, 5000);
         // console.log(timer);

         // timer = setInterval(function() {
         //    txt1.value = n;
         //    n++;
         // }, 10); // 0.01초 
         // console.log(timer);

         // 타이머ID를 여러개 생성 -> 삭제하는 방법
         // timerList.push(timer); // 버튼을 여러번 누르면 타이머 ID가 여러개 생성된다. -> 타이머 ID 배열에 저장

         // 시작버튼 한번만 클릭가능.
         if (timer == 0) {
            timer = setInterval(function() { // 타이머 ID 대입
               txt1.value = n;
               n++;
            }, 10);
         }

      };

      btnStop.onclick = function() {
         // clearTimeout(timer);
         // clearInterval(timer);
         // n = 0; // 전역변수 리셋

         // timer = timerList.pop(); // 배열에 넣은 타이머 ID를 pop()으로 호출 (pop()은 스택이라 꺼내면 사라짐.)
         // clearInterval(timer); 
         // console.log(timerList);

         clearInterval(timer); 
         timer = 0; // 0으로 초기화
         
      };


      // ------------------------------------------------------


      var index = 0;
      var colors = [ 'white', 'black', 'tomato', 'gold', 'cornflowerblue' ];

      btn4.onclick = function() {

         setInterval(function() {
            document.body.bgColor = colors[index];
            index++;
            if (index >= colors.length) {
               index = 0; //reset
            }
         }, 1000);

      };

      // -----------------------------------------------------

      cat1.onclick = function() {

         index = 1;
         
         if (timer == 0) {
            timer = setInterval(function() {
               //JavaScript -> format String X (자바스크립트는 형식문자열이 없다.)
               //console.log() -> format String O
               cat1.src = "images/catty0" + index + ".png";
               index++;

               if (index > 9) {
                  index = 1;
               }

            }, 50);
         } else {
            clearInterval(timer);
            timer = 0;
         }

      };


      // ----------------------------------------------------


      txt1.onkeyup = function() {
         //무언가를 입력중이면 타이머 중지
         clearTimeout(timer);
      };

      txt1.onblur = function() {
         // onblur : 포커스가 소멸되는 순간(입력 상태가 풀리면) 발생하는 이벤트
         txt1.readOnly = true;
      };

      timer = setTimeout(function() {
         txt1.readOnly = true;
         txt1.placeholder = '입력이 불가능합니다.';
      }, 10000); // 10초가 지나면 입력 불가능 -> 읽기만 가능


      // ------------------------------------------------------


      btnDelete.onclick = function() {

         // <select>의 모든 <option>태그 삭제하기
         //1.
         // while (sel1.options.length > 0) {
         //    sel1.options.remove(0);
         // }

         //2.
         //sel1.options = null;

         //3.
         // a. length의 변화
         // b. index의 shift

         //length -> 5 => loop x 5

         var count = sel1.options.length;

         // for (var i=0; i<count; i++) {
         //    sel1.options.remove(i);
         //    // console.log(sel1.options.length);
         // }

         for (var i = count-1; i>=0; i--) { // shift를 방지하기 위해 뒤에서부터 지운다.
            sel1.options.remove(i);
         }

      };

   </script>

</body>
</html>

문제

<!-- https://pinnpublic.github.io/example/javascript/exam12.html -->

ESLint

  • ESLint는 JavaScript 코드에서 발견 된 문제 패턴을 식별하기위한 정적 코드 분석 도구
      JavaScript -> 문법 검사 도구

      ESLint
      -> node.js
      -> npm(JS 관련 라이브러리 설치/관리 도구) or yarn

      VS Code > Ctrl + `(~)

      VS Code
      1. 폴더 열기 > Ctrl + K,O > javascript 폴더 선택
      2. Ctrl + ` > 프롬프트 > javascript
      3. > npm install bootstrap@3

      현재 행동 > 사이트 + 설치 파일 다운로드 + 작업 폴더 이동 + 설정
      -> 위의 행동을 대신

      XXLint

      1. > npm install -g eslint
      2. > npm init : 작업 공간 선언(초기화)
      3. > eslint --init : eslint 작업 공간 선언 (***터미널이 powerShell이면 버그때문에 안됨 -> cmd로 설정하기)
      4. > eslint ex36.js
      5. VS 확장 프로그램 -> ESLint 실시간 연동
      6. 구글검색 git > eslint-plugin-html > .eslintrc.js (ESLint 설정파일) > 붙여넣기


DOM

<!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>Document</title>
   <link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.css">
   <script src="node_modules/bootstrap/dist/js/bootstrap.js"></script>
</head>
<body>
   <!-- ex36_DOM.html -->

   <!--  
      JavaScript -> 문법 검사 도구

      ESLint
      -> node.js
      -> npm(JS 관련 라이브러리 설치/관리 도구) or yarn

      VS Code > Ctrl + `(~)

      VS Code
      1. 폴더 열기 > Ctrl + K,O > javascript 폴더 선택
      2. Ctrl + ` > 프롬프트 > javascript
      3. > npm install bootstrap@3

      현재 행동 > 사이트 + 설치 파일 다운로드 + 작업 폴더 이동 + 설정
      -> 위의 행동을 대신

      XXLint

      1. > npm install -g eslint
      2. > npm init : 작업 공간 선언(초기화)
      3. > eslint --init : eslint 작업 공간 선언
      4. > eslint ex36.js
      5. VS 확장 프로그램 -> ESLint 실시간 연동
      6. 구글 > eslint-plugin-html

   -->


   <!--  
      name: BOM 구성요소만 가질 수 있다.
      id, class: 모든 태그가 가질 수 있다.
   -->

   <div class="container">
      <h1 class="title">DOM</h1>

      <form name="form1">
         <h2 class="title">Document Object Model</h2>
         <div id="container">
            <input type="text" name="txt1" id="txt1" class="txt"><br>
            <input type="text" name="txt2" id="txt2" class="txt"><br>
            <input type="text" name="txt3" id="txt3" class="txt"><br>
         </div>
      </form>
   </div>

   <script>

      /*  
      
      BOM vs DOM
      1. BOM, Browser Object Model
         - HTML 문서의 일부 요소만을 가지고 트리 구조를 제공
         - BOM 트리 구조를 기반으로 태그 검색
         - 접근한 태그 > 속성 조작
         - BOM에 속하지 않은 나머지 태그 접근 불가능!!
         - 조작 도구가 HTML 속성에 기반 > 프로퍼티로 제공 > 한계(제한)!!
         - PCDATA 조작 불가능!!
         - 태그 동적 추가/삭제 불가능!!(예외. <option> 태그)
         - CSS 조작 불가능!!!

      2. DOM, Document Object Model
         - 현재 HTML의 모든 태그를 사용해서 트리 구조 생성 + 제공
         - BOM과 달리 모든 태그를 인식
         - 검색 도구 추가 제공, 조작 도구 추가 제공
         - 태그 동적 추가/삭제 가능!!
         - CSS 조작 가능!!
         - PCDATA 조작 가능!!
         - DOM Level 1
         - DOM Level 2
         - DOM Level 3
         - BOM 기반으로 생성 > 모든 DOM 기능이 document를 통해서 정의(사용)
         
      */

      
      /*
      
         DOM 태그 검색 도구
         1. id 검색(***)
            - object getElementById("id")
            - 유일한 객체(태그)를 찾겠다.
            - 계층 구조를 고려할 필요가 없다.(누구의 자식(X))

         2. class 검색(**)
            - collection getElementsByClassName("class")
            - 같은 이름의 class를 가진 태그 집합을 반환한다.
            - 유사 배열

         3. 태그명 검색
            - collection getElementsByTagName("tag name")
            - 태그명을 검색 -> 태그 집합을 반환한다. (유사배열)

         4. name 검색
            - BOM에서 사용하는 name 식별자를 지원하기 위해서 추가된 기능
            - collection getElementsByName("name")
            - name을 검색 -> 태그 집합을 반환한다.

         5. axis 검색

      */

      // id 검색
      //txt1 검색
      var txt1 = document.form1.txt1; // BOM 방식으로 검색
      //txt1.value = "BOM"; // BOM
      txt1.setAttribute("value", "BOM2"); // DOM 방식으로 수정

      //id(유일)
      var txt2 = document.getElementById("txt2"); // <input id="txt2"> DOM 방식으로 검색
      //txt2.setAttribute("value", "DOM"); // DOM
      txt2.value = "DOM2"; // BOM 방식으로 수정

      //*** BOM으로 검색하던 DOM으로 검색하던 찾은 결과 객체는 동일한 타입이다. -> DOM이랑 BOM을 섞어서 사용 가능하다.!!!
      var txt3_1 = document.form1.txt3; //BOM
      var txt3_2 = document.getElementById("txt3"); //DOM

      console.log(txt3_1 == txt3_2); // true
      console.log(txt3_1 === txt3_2); // true

      
      // class 검색
      var txt = document.getElementsByClassName("txt");
      console.log(txt.length); // 유사 배열 반환
      console.log(typeof txt); // 자료형 - object

      // Array(X) 
      // HTMLCollection(O): Collection, 유사배열(배열은 아니지만 배열처럼 사용 가능)
      console.log(txt.constructor);
      txt[0].value = "100";

      // 에러 : txt.forEach is not a function (배열처럼 사용이 가능하지만 배열이 아니라서 forEach는 사용할 수 없다. )
      // txt.forEach(function(item, index) {
      //    console.log(item.id);
      // });
      
      // for문은 사용 가능
      for (var i=0; i<txt.length; i++) {
         // console.log(txt[i].id);
         txt[i].value = "집합";
      }


      // 태그명 검색
      var input = document.getElementsByTagName("input");
      console.log(input.length); // 유사배열
      console.log(input.constructor);

      // ESLint -> 강제력(X), 통보(O)
      for (var i=0; i<input.length; i++) {
         input[i].value = "하하하";
      }


      // name 검색
      var txt1 = document.getElementsByName("txt1"); // txt1 -> 배열
      txt1[0].value = "추가 검색";



      //<h1>, <h2> 태그 찾기 -> BOM이 찾을 수 없었던 태그 찾기 가능
      var title = document.getElementsByClassName("title");
      title[0].style.color = "red";
      title[1].style.color = "blue";

   </script>
   
</body>
</html>

ex37_content.html

<!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>Document</title>
   <style>

      #div1 {
         background-color: gold;
         width: 100%;
         height: 50px;
      }

   </style>
</head>
<body>

   <h1>Content 조작</h1>

   <input type="button" value="버튼1" id="btn1">
   <hr>
   <div id="div1"></div>

   <script>

      var btn1 = document.getElementById("btn1");
      var div1 = document.getElementById("div1");

      // <input type value size readonly disabled maxlength title..> => 태그 조작할게 많음.
      // btn1.value = "100";

      // <div id="" class="" title="" bgcolor(X)> => 태그 자체에 조작할 속성이 많지 않음. -> DOM으로 찾은 태그를 활용할 범위가 생각보다 많지 않음. -> 주로 contents를 조작함.
      // div1.bgColor = "red"; -> 없는 프로퍼티 조작 불가능. 


      /*      
         content : 시작 태그와 끝 태그 사이에 있는 내용물

         Content 조작(DOM 전용)
         - <div>Content</div>
         - getter(읽기), setter(쓰기)

         1. innerText
         - 시작 태그와 끝 태그 사이의 문자열 읽기/쓰기 프로퍼티
         - 내용물 파싱하지 않는다.(= 해석하지 않고 있는 그대로 입출력)
         - 비 표준 프로퍼티(MS), 모든 브라우저 지원

         2. innerHTML
         - 시작 태그와 끝 태그 사이의 문자열 읽기/쓰기 프로퍼티
         - 내용물 파싱한다.(구문이 존재하면 해석해서 실행한다.)
         - 표준 프로퍼티

         3. textContent
         - innerText와 동일한 프로퍼티
         - 표준 프로퍼티 
      */
      
      btn1.onclick = function() {
         // div1.innerText = "홍길동";
         // div1.innerText = "<b>안녕하세요.</b>"; // => 내용물 파싱하지 않는다. 태그가 들어있으면 태그가 그대로 들어가지 않고 엔티티로 변환되서 들어간다.

         // div1.innerHTML = "아무개";
         // div1.innerHTML = "<b>반갑습니다.</b>"; // => 내용물 파싱한다. 태그가 들어있으면 태그를 인식 + 통제.

         // 동적 컨트롤 생성
         // div1.innerHTML += "<input type='text'><br>";

         // div1.innerHTML = "<img src='images/catty01.png'>";

         // div1.innerHTML = "<input type='button' value='버튼' onclick='alert(100);'>";

         var n = parseInt(Math.random() * 5) + 1; // 1 ~ 5 랜덤
         div1.innerHTML += "<img src='images/catty0" + n + ".png'>";
      };
      

      // 브라우저 > 개발자 도구 > 요소(탭)의 소스 > 현재 브라우저에서 실행 중인 페이지 상태를 보여주는 것 > DOM Tree
      // 실제 현재 상태 -> 개발자 도구사용
      // 실제 원본 -> 원본 소스보기 사용

   </script>
</body>
</html>

ex38_content.html

<!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>Document</title>
   <style>

      #tbl1 {
         border: 1px solid black;
         border-collapse: collapse;
         width: 500px;
         height: 500px;
      }

      #tbl1 td {
         border: 1px solid black;
         width: 100px;
         height: 100px;

         text-align: center;
         font-size: 4em;
         font-weight: bold;
      }

   </style>
</head>
<body>

   <h1>게시판</h1>

   <div>
      <input type="button" value="첨부파일 추가하기" id="btnAdd">
   </div>

   <hr>

   <div>
      <label>첨부파일: <input type="file" class="file"></label>
   </div>

   <div id="filelist"></div>

   <hr>

   <table id="tbl1">
      <tr>
         <td></td>
         <td></td>
         <td></td>
         <td></td>
         <td></td>
      </tr>
      <tr>
         <td></td>
         <td></td>
         <td></td>
         <td></td>
         <td></td>
      </tr>
      <tr>
         <td></td>
         <td></td>
         <td></td>
         <td></td>
         <td></td>
      </tr>
      <tr>
         <td></td>
         <td></td>
         <td></td>
         <td></td>
         <td></td>
      </tr>
      <tr>
         <td></td>
         <td></td>
         <td></td>
         <td></td>
         <td></td>
      </tr>
   </table>

   
   <script>

      // 동적 컨트롤
      var btnAdd = document.getElementById("btnAdd");
      var filelist = document.getElementById("filelist");

      btnAdd.onclick = function() {
         filelist.innerHTML += "<div><label>첨부파일: <input type='file' class=\"file\"></label></div>";
      };

      // --------------------------------------------------

      var td = document.getElementsByTagName("td");

      for (var i=0; i<td.length; i++) {
         td[i].onclick = function() {
            // alert("click");
            // alert(i); - 사용X
            
            // event.srcElement.innerText = "O";
            event.srcElement.innerHTML = "<img src='images/catty01.png' width='90' height='90'>";

            // event.srcElement.innerHTML = ""; // 없애기
         };
      }

   </script>

</body>
</html>

ex39_content.html

<!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>Document</title>
   <style>
       
      fieldset { 
         border: 1px solid #999; 
         border-radius: 5px;
         width: 200px;
      }
       
      fieldset > div {
         margin: 7px;
      }

      #tbl1 {
         border: 1px solid black;
         border-collapse: collapse;
      }

      #tbl1 td {
         border: 1px solid black;
         padding: 5px 15px;
         text-align: center;
      }
   </style>
</head>
<body>

   <h1>테이블</h1>

   <fieldset>
      <legend>행x열</legend>
      <div><label>행: <select id="selRow"></select></label></div>
      <div><label>열: <select id="selColumn"></select></label></div>
      <div><input type="button" value="생성하기" id="btnCreate"></div>
   </fieldset>

   <table id="tbl1">
      <tbody id="tbody1"></tbody>
   </table>

   <script>

      var selRow = document.getElementById("selRow");
      var selColumn = document.getElementById("selColumn");
      var btnCreate = document.getElementById("btnCreate");
      var tbody1 = document.getElementById("tbody1");

      // selRow -> BOM 추가
      // selColumn -> DOM 추가

       // BOM
      for (var i=1; i<=30; i++) { // -> option태그에만 쓸 수 있는 방법
         var op = new Option();
         op.text = i;
         op.value = i;
         selRow.options.add(op);
      }

      selRow.value = 5; // 평균 -> 초기값(기본값)

       // DOM
      for (var i=1; i<=10; i++) { // -> 어디서든 쓸 수 있는 방법
         selColumn.innerHTML += "<option value='" + i + "'>" + i + "</option>";
      }

      selColumn.value = 3; // 기본값

       
      btnCreate.onclick = function() {
         // 사용자가 선택한 : 행 x 열 -> 테이블 추가

         //혹시 기존 내용이 <tbody>에 남아있으면 지우고 다시 시작
         tbody1.innerHTML = ""; // 삭제(초기화)

         for (var i=0; i<selRow.value; i++) {
            // 행 -> <tr>
            var temp = ""; // 누적변수
            temp += "<tr>";

               for (var j=0; j<selColumn.value; j++) {
                  //열 -> <td>
                  temp += "<td>";
                  temp += i + ',' + j; //<td>5,2</td>
                  temp += "</td>";
               }

            temp += "</tr>";
            
            tbody1.innerHTML += temp; //<tr> 동적 추가
         }

      };

   </script>

</body>
</html>
profile
모르면 괴롭고 알면 즐겁다.

0개의 댓글