[웹 개발] Week 2. Javascript / JQuery / Fetch

Jake·2022년 12월 30일

#Fetch #Javascript #JQuery

01. 2주차 오늘 배울 것

  • 1) 움직이는 웹 만들기 🔥 1주차는 뼈대를 만들고 꾸며보았다면, 이번 주차에는 실제로 데이터가 움직이게 만들어 볼거에요! > html은 뼈대, css는 꾸미기, javascript는 움직이기! > ![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/6434b1c6-1baf-4746-a253-19cd70fd5825/Untitled.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/6434b1c6-1baf-4746-a253-19cd70fd5825/Untitled.png)
  • 2) 2주차 : Javascript, jQuery, Fetch
    • Javascript 는 웹을 움직이게 하는 코드에요!

    • jQuery는 html 뼈대를 선택해서 쉽게 조작할 수 있어요!

      💁 Bootstrap, 기억나시나요? jQuery도 남들이 만든 코드모음, 라이브러리에요!
    • Fetch는 짧은 코드로 요청을 보내고 받아올 수 있어요!

      🤔 이거 세 개를 하면 뭘 할 수 있는데요?
    • 모바일 청첩장으로 예를 들어보자면요!

      • 지난 주차까지는 모바일 청첩장만 만들어 보낼 수 있어요! 화면에서 사용자는 그저 볼 수만 있었죠!
      • 이번 주차까지 배우면, 요청을 보내면 친구의 이름으로 축하를 받을 수 있는 모바일 청첩장을 만들 수 있게 되는거에요! 💁 이를테면, 클릭으로 사진이 바뀐다거나 스크롤을 내리면 사진이 바뀌는 것처럼요!

02. Javascript 맛보기

  • 1) 자바스크립트란?
    • 프로그래밍 언어 중 하나로, 브라우저가 알아들을 수 있는 언어입니다. 😎 이론 설명 때, 클라이언트가 서버에 요청하면, 서버가 클라이언트에게 HTML+CSS+Javascript를 준다고 했던 것, 기억하시나요? 🤔 [잠깐 상식!] Q. 왜 브라우저는 Javascript만 알아들어요? HTML안에다 파이썬, Java 같은 언어를 써서 주면 안되나요? A. 불가능한 이야기는 아닙니다. 다만, 이 "역사적인 이유 & 이미 만들어진 표준"이기 때문에, 모든 브라우저는 기본적으로 Javascript를 알아듣게 설계되어있고, 모든 웹서버는 HTML+CSS+Javascript를 주게 되어있죠.
    • Java와 Javascript는 어떤 차이가 있나요? 🤔 인도와 인도네시아.. 바다와 바다코끼리.. 아무 관련 없습니다.
  • 2) 자바스크립트 기초
    • 처음 프로그래밍 언어를 배우면 생소한 부분도 존재하기에, 다음 주에 본격적으로 하기 전에! 오늘 먼저 맛보기를 해보겠습니다. 😎 일단 따라쓰기!를 통해, 자바스크립트가 HTML과 어떻게 연동되는지 알아보겠습니다.
  • 3) 자바스크립트 - HTML 연결. 버튼을 클릭하면 경고창이 뜨게하기
    • 함수를 만들어두기
      function hey(){
      	alert('안녕!');
      }
      👉 ~ 안에 로 공간을 만들어 작성합니다. `script 태그` 안에 자바스크립트를 작성하는 것이죠 아래 코드를 통해 간단한 사용방법을 알아봅니다.
    • 버튼에 함수를 연결하기. 버튼을 누르면 함수가 불립니다.
      <button onclick="hey()">영화 기록하기</button>
      스크린샷 2022-12-09 오후 3.18.32.png 💁 직독직해하면, (1)**버튼을 클릭하면**, (2)**hey를 불러라!** (3)**alert(’안녕’)을 실행해라!** 💁 프로그래밍에서는 정해진 일을 반복하는 친구를 함수라고 불러요! 우리는 방금 function hey()라는 규칙으로 hey라는 함수를 만들었고, alert(’안녕’)이라는 작업을 원할 때마다 반복적으로 수행하게 만들었습니다!

03. Javascript 기초 문법 배우기

  • 1) 화면에 미리 찍어보는 console.log()

    💁 기초문법은 자바스크립트 뿐만이 아니라 개념자체는 어느 프로그래밍 언어를 가도 똑같습니다!다음 주차의 파이썬에서도 유사하게 활용할 수 있을 거에요! - 일단 코드화면, 브라우저화면을 줄여서 한 화면을 둘로 나눠봅시다!
    • script 태그 안에 있는 function hey의 코드를 바꿔서 적어봅시다

      ```jsx
      <script>
      	funtion hey() {
      		console.log('안녕하세요')
      	}
      </script>
      
      <body>
      	<button onclick="hey()">영화 기록하기</button>
      </body>
      ```
      🤔 alert에서 console.log를 바꿔서 실행하라는 것은 알겠는데.. 대체 화면 어디에 나오는거죠? - 브라우저 화면에서 오른쪽 클릭! `검사`를 눌러주세요! - 화면에 뜨는 건 **개발자도구**에요! `Console` 탭을 눌러봅시다! 💁 우리가 코딩한 것이 맞게 출력되는건가..?를 확인하기 위해 개발자들이 미리 찍어보는 도구가 console.log 입니다! - 그러나 값을 매번 찍어보려고 버튼을 클릭해서 실행하는 것은 불편하죠?
          ```jsx
          <script>
          	console.log('안녕하세요')
          </script>
          ```
          
      💁 프로그래밍 언어는 기계와 사람이 소통하기 위해 만든 언어입니다! 사람이 썼기 때문에, 우리 눈에 친숙할 거에요!
    • 변수 & 기본연산

      • 변수 대입( a = 2 )의 의미: "오른쪽에 있는 것을 왼쪽에 넣는 것!"
        (2를 a라는 변수에 넣는다)

      • let으로 변수를 선언합니다.

        let a = 2
        a = 'Bob' // 문자열은 작은 따옴표로 감싸줍니다!
        
        // 변수는 값을 저장하는 박스예요.
        // 처음 변수를 저장하려면, let을 앞에 붙여주세요!
        // 한 번 선언했으면, 다시 선언하지 않고 값을 넣습니다.
      • 사칙연산, 그리고 문자열 더하기가 기본적으로 가능합니다.

        let a = 2
        let b = 3
        
        console.log(a+b) // 5
        
        let c = '대한'
        let d = '민국'
        
        console.log(c+d) // 대한민국
    • 리스트 & 딕셔너리

      • 리스트: 순서를 지켜서 가지고 있는 형태입니다.

        💁 컴퓨터는 **0부터 세요**! 리스트에 들어있는 **첫 번째 값은 [0]으로 불러옵니다!**
        let a_list = []  // 리스트를 선언. 변수 이름은 역시 아무렇게나 가능!
        
        // 또는,
        
        let a = ['사과','수박','딸기','감'] // 로 선언 가능
        
        console.log(a[1]) // 수박
        console.log(a[0]) // 사과
        
        //리스트 길이 구하기
        console.log(a.length) //4
        
      • 딕셔너리: 키(key)-밸류(value) 값의 묶음

        let a_dict = {}  // 딕셔너리 선언. 변수 이름은 역시 아무렇게나 가능!
        
        // 또는,
        
        let a = {'name':'영수','age':27} // 로 선언 가능
        
        console.log(a)
        console.log(a['name']) // 영수
        console.log(b_dict['age']) // 27
        💁 리스트는 `[]`가 생겼으니까 `[]`로 가져오는데, 딕셔너리는 `{}`로 만들었는데 `{}`로 왜 안가져오는가… 이게 이렇게 생긴 이유와 원리를 찾아가면 너~무 코딩이 어려워져요..! - 이런 규칙들은 프로그래밍 언어를 만든 사람이 그때그때 목적에 맞게 작성한 것이에요! → 따라서 규칙을 설정하는 것도 다 제각각이겠죠? - 있는 그대로! 아 얘는 이렇게 쓰는거구나.. 하고 받아 들여주세요! 😄
      • 리스트와 딕셔너리의 조합

        💁 꺾쇠와 키-밸류, 이 두가지로 이뤄진 형태의 자료를 정~말 많이 씁니다! 이게 기초가 되는 문법이에요!
        let a = [
        	{'name':'영수','age':27},
        	{'name':'철수','age':15},
        	{'name':'영희','age':20}
        ]
        console.log(a[0]['name']) //영수
        console.log(a[1]['age']) //15
      • 왜 필요할까요?

        💡 **순서를 표시할 수 있고, 정보를 묶을 수 있습니다.** 앞에서 언급한 <스파르타과일가게>가 정말 잘 되어서 전국에서 손님이 찾아오고 있습니다. 대기표를 작성하기 위해서 온 순서대로 이름, 휴대폰 번호를 적도록 하였는데요. 변수만을 사용한 모습은 다음과 같습니다. let customer_1_name = '김스파'; let customer_1_phone = '010-1234-1234'; let customer_2_name = '박르탄'; let customer_2_phone = '010-4321-4321'; ...(알아보기 힘듭니다.) 👉딕셔너리를 활용한다면 다음과 같이 고객 별로 정보를 묶을 수 있습니다. let customer_1 = {'name': '김스파', 'phone': '010-1234-1234'}; let customer_2 = {'name': '박르탄', 'phone': '010-4321-4321'}; 👉그리고 순서를 나타내기 위해 리스트를 사용하면, 이렇게나 깔끔해집니다. let customer = [ {'name': '김스파', 'phone': '010-1234-1234'}, {'name': '박르탄', 'phone': '010-4321-4321'} ] ✅보기에도 깔끔해지고, 다루기도 쉬워지고, 고객이 새로 한 명 더 오더라도 .push 함수를 이용해 간단하게 대응할 수 있습니다.
    • 📌 추가자료 - 기본 함수들

      • 사칙연산 외에도, 기본적으로 제공하는 여러 함수들이 존재합니다.

        🤔 왠지 이건 있을 것 같은데?(예 - 특정 문자를 바꾸고 싶다 등) 싶으면 직접 만들지 말고 **구글에 먼저 찾아보세요!**
        **예를 들면, '나눗셈의나머지'를 구하고 싶은 경우**
        
        let a = 20
        let b = 7
        
        a % b = 6
        **, 특정 문자로 문자열을 나누고 싶은 경우**
        
        let myemail = 'sparta@gmail.com'
        
        let result = myemail.split('@') // ['sparta','gmail.com']
        
        result[0] // sparta
        result[1] // gmail.com
        
        let result2 = result[1].split('.') // ['gmail','com']
        
        result2[0] // gmail -> 우리가 알고 싶었던 것!
        result2[1] // com
        
        myemail.split('@')[1].split('.')[0] // gmail -> 간단하게 쓸 수도 있다!

04. Javascript & JQuery 연습하기 (1)

  • 1) JQuery가 뭐라고요?

    💁 jQuery를 왜 쓴다구요? 웹을 조작하려고! 왜 조작하죠? 움직이게 만드려고! 그런데 javascript만 사용하면 복잡하니까 jQuery도 쓰는 겁니다! - HTML의 요소들을 조작하는, 편리한 Javascript를 미리 작성해둔 것. 라이브러리! 👀 Javascript로도 모든 기능(예 - 버튼 글씨 바꾸기 등)을 구현할 수는 있지만, 1) 코드가 복잡하고, 2) 브라우저 간 호환성 문제도 고려해야해서, **j**Query라는 라이브러리가 등장하게 되었답니다. - jQuery와 Javascript - 코드 비교해보기 🤔 jQuery는 Javascript와 다른 특별한 소프트웨어가 아니라 미리 작성된 Javascript 코드입니다. 전문 개발자들이 짜둔 코드를 잘 가져와서 사용하는 것임을 기억해주세요! (그렇게 때문에, 쓰기 전에 "임포트"를 해야합니다!) - `Javascript`로 길고 복잡하게 써야 하는 것을
          ```jsx
          document.getElementById("element").style.display = "none";
          ```
          
      - `jQuery`로 보다 직관적으로 쓸 수 있어요. 편리하죠? :-)
          
          ```jsx
          $('#element').hide();
          ```
          
    • jQuery 사용하기

      • 미리 작성된 Javascript 코드를 가져오는 것을 '임포트'라고 부릅니다.

        👀 jQuery CDN 부분을 참고해서 임포트하기: [(링크)](https://www.w3schools.com/jquery/jquery_get_started.asp) - **[코드스니펫] jQuery CDN**
          ```html
          https://www.w3schools.com/jquery/jquery_get_started.asp
          ```
          
      • 와 사이에 아래를 넣으면 끝! 🤔 수업 자료를 잘 따라온 분이라면, 코드에 이미 다음과 같이 임포트 되어있을거예요. 다시한번 잘 살펴보세요!
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
      • jQuery를 사용하는 방법

        😎 css와 마찬가지로, jQuery를 쓸 때에도 "가리켜야" → 조작할 수 있습니다. 예) 특정 인풋박스의 값을 → 가져와줘! 예) 특정 div를 → 안보이게 해줘! css에서는 선택자로 class를 썼지요? jQuery에서는 id 값을 통해 특정 버튼/인풋박스/div/.. 등을 가리키게 됩니다. 백문이불여일견! 자주 쓰는 jQuery들을 함께 다뤄보면서 익혀보죠!
  • 2) JQuery 연습하기

    📌 새로운 폴더 `jsprac` 을 만들고, 그 안에 `prac.html` 로 시작해봐요! 👀 Live Server를 활용해 화면을 반으로 나눠 코드를 적으면서 확인해보세요! - prac.html에 뼈대를 붙여넣어 봅시다! - **[코드스니펫] prac.html - JQuery 연습하기 뼈대**
          ```html
          <!DOCTYPE html>
          <html>
              <head>
                  <title>자바스크립트 문법 연습하기!</title>
                  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
              </head>
              <style>
                  .button-part {
                      display: flex;
                      height: 50px;
                  }
              </style>
              <script>
                  
              </script>
              <body>
                  <div class="top-part">
                      <h1>자바스크립트 문법 연습하기!</h1>
                  </div>
                  <hr/>
                  <br>
                  <h2>1. 함수</h2>
                  <div class="button-part">
                      <button onclick="checkResult()">결과 확인하기!</button>
                  </div>
                  <div class="list-part">
                      <h2>2. 리스트</h2>
                      <div id="q1"></div>
                  </div>
                  <div class="dict-part">
                      <h2>3. 딕셔너리</h2>
                      <div id="q2"></div>
                  </div>
                  <div>
                      <h2>4. 리스트 딕셔너리</h2>
                      <div id="q3"></div>
                  </div>
              </body>
          </html>
          ```
          
      
    • script 태그에 checkResult() 함수를 만들어 봅시다

      <script>
      function checkResult() {}
      </script>
    • alert(’안녕하세요’)를 적어 똑같이 작동하는지 한 번 해봅시다

      ```jsx
      function checkResult() {
      	alert('안녕하세요')
      }
      ```
      💁 css-클래스처럼 자바스크립트에서 html을 움직이게 하기 위한 명찰, id 값이 필요합니다!
    • html 태그에 id를 적어주어야 합니다! 예제에 달려있는지 볼까요?

      <div id="q1"></div>
    • div태그가 존재하는데 우리 눈에 안보이는 이유는 껍데기는 있는데, 내용은 없어서 그래요!

      <div id="q1">테스트</div>
    • 값을 넣을 변수를 써봅시다

      let a = '사과'
    • 테스트라는 글씨를 값을 사과로 바꿔볼겁니다! 이게 움직이기입니다!

      <aside>
      💁 여기서부터 오타작렬에 주의! 잘 따라오세요!
      
      </aside>
      
      ```jsx
      function checkResult() {
      	let a = '사과'
      	$('#q1').text(a)
      }
      ```
      
      - `$(’#아이디값’)` 으로 어떤 html 태그를 바꿀 것인지 지정해줍니다!
      - 지정했다면, 바꿔줄 명령어를 적어줍니다 `text(a)`를 넣어 글자 값으로 a를 넣습니다!
      😎 이번엔 리스트를 써서 해봅시다!
    • [코드스니펫] 자바스크립트 리스트 자료형

      ```jsx
      let a = ['사과', '배', '감', '귤']
      ```
    • 리스트 형태의 코드를 적고 변수에 저장해봅시다!

    • a의 내용을 문자열에서 리스트로 바꿔봅시다!

      let a = ['사과', '배', '감', '귤']
    • 문자열에서 리스트의 두 번째 값으로 바꿔서 넣어봅시다!

      ```jsx
      $('#q1').text(a[1])
      ```
      
      ⇒ 이외에 필요한 부분들은 “구글링” 하여 찾아 보면 좋아요! 
      😎 이번엔 딕셔너리를 써서 해봅시다!
    • [코드스니펫] 자바스크립트 딕셔너리 자료형

      ```jsx
      let b = {
        "name" : "영수",
        "age" : 30
      }
      ```
    • 딕셔너리 형태의 코드를 적고 변수에 저장해봅시다!

      let b = {
        "name" : "영수",
        "age" : 30
      }
    • 딕셔너리의 키 값을 불러내서 q2라는 아이디 값이 있는 곳에 넣어봅시다!

      ```jsx
      $('#q2').text(b['name'])
      ```
      😎 이번엔 리스트-딕셔너리를 써서 해봅시다!
    • [코드스니펫] 리스트-딕셔너리 자료형

      ```jsx
      let c = [
      	{'name':'영수', 'age':30},
      	{'name':'철수', 'age':35}
      ]
      ```
    • 리스트-딕셔너리 형태의 코드를 적고 변수에 저장해봅시다!

      let c = [
      	{'name':'영수', 'age':30},
      	{'name':'철수', 'age':35}
      ]
    • 리스트에서 원하는 딕셔너리를 부르고, 딕셔너리에서 키 값을 불러내서 q3에 넣어봅시다!

      ```jsx
      $('#q3').text(c[1]['age'])
      ```
      😎 완성된 결과물은?

      Untitled

    • [**완성 코드]**

      <!DOCTYPE html>
      <html>
          <head>
              <title>자바스크립트 문법 연습하기!</title>
              <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
          </head>
          <style>
              .button-part {
                  display: flex;
                  height: 50px;
              }
          </style>
          <script>
              function checkResult(){
                  let a = ['사과','배','감','귤']
                  $('#q1').text(a[1])
      
                  let b = {'name':'영수','age':30}
                  $('#q2').text(b['name'])
      
                  let c = [
                      {'name':'영수','age':30},
                      {'name':'철수','age':35}
                  ]
                  $('#q3').text(c[1]['age'])
              }
          </script>
          <body>
              <div class="top-part">
                  <h1>자바스크립트 문법 연습하기!</h1>
              </div>
              <hr/>
              <br>
              <h2>1. 함수</h2>
              <div class="button-part">
                  <button onclick="checkResult()">결과 확인하기!</button>
              </div>
              <div class="list-part">
                  <h2>2. 리스트</h2>
                  <div id="q1">테스트</div>
              </div>
              <div class="dict-part">
                  <h2>3. 딕셔너리</h2>
                  <div id="q2">테스트</div>
              </div>
              <div>
                  <h2>4. 리스트 딕셔너리</h2>
                  <div id="q3">테스트</div>
              </div>
          </body>
      </html>

05. Javascript & JQuery 연습하기 (2)

  • 1) 반복문

    😎 리스트, 리스트-딕셔너리 형식의 자료는 하나하나 뽑아써야 하나요? 그렇지 않겠죠! - 리스트 자료형의 데이터를 일일히 뽑아보는데..
      ```jsx
      let fruits = ['사과','배','감', ... ,'귤']
      console.log('사과')
      console.log('배')
      console.log('감')
      ...
      console.log('귤')
      
      // 이렇게 100개 씩 쓰기엔 무리가 있겠죠? 그래서, 반복문이라는 것이 존재합니다!
      ```
      
    • 우리는 그 중에서도 forEach라는 친구로 간단하게 뽑아볼 거에요!
      fruits.forEach((a) => {
      	console.log(a)
      }) 
      // fruits 의 요소를 하나씩 확인하는데 이름은 a라고 할 거에요!
      // a는 b,c,zzz,fruit 어떤 걸로 해도 상관 없어요!
      💁 생긴게 조금 어렵죠..? 괜찮아요! 이번에만 오타내지 마시고, 다음 번에는 복사 붙여넣기해요!
    • 과일의 목록이 담긴 리스트로 반복 해봅시다!
      let fruits = ['사과','배','감','귤']
      fruits.forEach((a) => {
      	console.log(a)
      })
      스크린샷 2022-12-09 오후 6.43.52.png 💁 사과, 배, 감, 귤 총 네 번이 개발자 도구에 찍혔죠? 그럼 반복문을 쓰면 몇 번 찍히는 거죠? 바로 리스트 안에 들어 있는 값의 개수만큼!
  • 2) 조건문

    😎 반복문과 더불어 조건에 맞춰 실행을 다르게 해주는 “조건문”도 프로그래밍에선 빼놓을 수 없답니다!
    if (조건) {
    	// 조건에 맞다면~
    } else {
    	// 아니라면~
    }

    ⇒ 만약 20살보다 크면 성인입니다 작으면 청소년입니다 를 출력하려면?

    let age = 24
    
    if (age > 20) {
    	console.log('성인입니다')
    } else {
    	console.log('청소년입니다')
    }

    ⇒ 반복문+조건문 합치기!

    let ages = [12,15,20,25,17,37,24]
    
    ages.forEach((a)=> {
    	if (a > 20) {
    		console.log('성인입니다')
    	} else {
    		console.log('청소년입니다')
    	}
    })

06. JQuery 연습하기

  • 1) JQuery - append (1)

    • 지난 시간에 적었던 코드를 모두 지우고 아래로 새로 붙여보세요!
      • [코드스니펫] 새로운 HTML 코드
        <!DOCTYPE html>
        <html>
        
        <head>
            <title>자바스크립트 문법 연습하기!</title>
            <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
        </head>
        <script>
            function checkResult() {
        
            }
        </script>
        
        <body>
            <div class="top-part">
                <h1>자바스크립트 문법 연습하기!</h1>
            </div>
            <hr />
            <br>
            <h2>1. 함수</h2>
            <div class="button-part">
                <button onclick="checkResult()">결과 확인하기!</button>
            </div>
            <div class="list-part">
                <h2>2. 붙이기</h2>
                <div id="q1">
                    <p>사과</p>
                    <p></p>
                    <p></p>
                </div>
            </div>
            <div class="list-part">
                <h2>3. 붙이기</h2>
                <div id="q2">
                    <p>영수는 24살입니다.</p>
                    <p>세종은 30살입니다.</p>
                    <p>수영은 20살입니다.</p>
                </div>
            </div>
        </body>
        
        </html>
    • checkResult() 함수 안에 적어봅시다!
      • [코드스니펫] fruits

        ```jsx
        let fruits = ['사과','배','감','귤','수박']
        ```
        💁 이제 리스트! 가 들어오면 뭘 해야할지 아시죠! 바로 반복문으로 착착 뽑아내고 싶지 않으신가요?
        function checkResult() {
        	let fruits = ['사과','배','감','귤','수박']
        	fruits.forEach((a)=>{
        	// 이제 이 안에서 뭔가 해야 반복문이 보이겠죠!
        	})
        }
    • 백틱(```)이라는 친구를 사용해 볼 겁니다! 숫자 키 1 왼쪽에 있는 기호에요!
      temp_html 이라는 변수를 만들 때 백틱을 사용해봅시다!
      <aside>
      💁 맥이라면 한글은 ₩로, 영어는 `으로 나옵니다!
      
      </aside>
      
      ```jsx
      function checkResult() {
      	let fruits = ['사과','배','감','귤','수박']
      	fruits.forEach((a)=>{
      		let temp_html = ``
      	})
      }
      ```
    • 우리가 원하는 html 태그를 백틱 안에 넣어줍니다!
      let temp_html = `<p>사과</p>`
    • jQuery를 사용해서, temp_html을 html 태그처럼 붙여볼거에요!
      $('#q1').append(temp_html)
    • 자! 결과는? 사과가 잔뜩 밑에 붙었네요? 스크린샷 2022-12-09 오후 11.36.18.png
    • 사과가 아니라 forEach문으로 돌린 반복문의 데이터가 들어가야겠죠?
      function checkResult() {
      	let fruits = ['사과','배','감','귤','수박']
      	fruits.forEach((a)=>{
      		let temp_html = `<p>${a}</p>`
      		$('#q1').append(temp_html)
      	})
      }
    • 처음에 나오는 사과, 귤 감은 빼줘야겠죠?
      $('#q1').empty()
    • [완성코드] fruits
      function checkResult() {
      	let fruits = ['사과','배','감','귤','수박']
      	$('#q1').empty()
      	fruits.forEach((a)=>{
      		let temp_html = `<p>${a}</p>`
      		$('#q1').append(temp_html)
      	})
      }
    • .append() 를 활용하기 🤔 어? ```` 에 `${}` 까지 너무 어려운데요? - 걱정마세요! 왜 이렇게 생겼는지 이해하려고 하지 마시고, 규칙이 있다고만 생각하고 작성하시면 얼마든지 따라 쓸 수 있어요! - 1) 원하는 html 태그를 백틱(````)으로 묶어 주세요! - 2) 태그 안에 들어갈 값은 `${}` 로 표시하고, 그 안에는 자료가 있는 변수를 넣어주세요! - 3) 통째로 넣을 html 요소를 `$('#아이디')`로 골라주시고 `appnd(변수)`를 넣어주세요! 😎 아직 너무 어렵다면, 계속 반복해서 연습할 테니 걱정마세요!
    • 문자와 변수를 같이 쓰는 백틱(````)
      • 아까 리스트를 HTML에 추가할 때 썼던 백틱(````) 기억나시나요? HTML요소를 통째로 넣을 때 묶어주는 기호였었습니다!

      • 백틱문자와 변수를 함께 써줄 수 있도록 하는 특수기호입니다! 이렇게도 쓸 수 있죠!

        let profile = `${}의 나이는 ${}살 입니다`
      • 이러면 한꺼번에 변수와 문자를 쓸 수 있게 되었습니다. ${} 자리에 변수만 넣어줘 볼까요?

      • 우리가 원하는 이름 값은 nameDict[’name’]으로 가져올 수 있었죠?

      • 우리가 원하는 나이 값은 nameDict[’age’]로 가져올 수 있었습니다!

        let profile = `${nameDict['name']}의 나이는 ${nameDict['age']}살 입니다`
  • 2) JQuery - append (2)

    💁 한 번 더 해볼까요? - 함수의 밑에 코드스니펫을 붙여주세요! - **[코드스니펫] people**
          ```jsx
          let people = [
          	{'name':'서영','age':24},
          	{'name':'현아','age':30},
          	{'name':'영환','age':12},
          	{'name':'서연','age':15},
          	{'name':'지용','age':18},
          	{'name':'예지','age':36}
          ]
          ```
          
    • 위에서 작성한 코드를 그대로 복사붙여넣기 합시다!
      let people = [
      	{'name':'서영','age':24},
      	{'name':'현아','age':30},
      	{'name':'영환','age':12},
      	{'name':'서연','age':15},
      	{'name':'지용','age':18},
      	{'name':'예지','age':36}
      ]
      $('#q1').empty()
      fruits.forEach((a)=>{
      		let temp_html = `<p>${a}</p>`
      		$('#q1').append(temp_html)
      	})
    • 변수 이름과 넣을 위치를 바꿔 줍시다!
      let people = [
      	{'name':'서영','age':24},
      	{'name':'현아','age':30},
      	{'name':'영환','age':12},
      	{'name':'서연','age':15},
      	{'name':'지용','age':18},
      	{'name':'예지','age':36}
      ]
      $('#q2').empty()
      people.forEach((a)=>{
      		let temp_html = `<p>${a}</p>`
      		$('#q2').append(temp_html)
      	})
    • 이름과 나이로 나눠서 변수를 지정해봅시다!
      let name = a['name']
      let age = a['age']
      let temp_html = `<p>${name}${age}살</p>`
    • [완성코드] people
      let people = [
      	{'name':'서영','age':24},
      	{'name':'현아','age':30},
      	{'name':'영환','age':12},
      	{'name':'서연','age':15},
      	{'name':'지용','age':18},
      	{'name':'예지','age':36}
      ]
      $('#q2').empty()
      people.forEach((a)=>{
      		let name = a['name']
      		let age a['age']
      		let temp_html = `<p>${a}</p>`
      		$('#q2').append(temp_html)
      	})

07. 서버-클라이언트 통신 이해하기

  • 1) 서버→클라이언트: "JSON"을 이해하기

    • 서울시 OpenAPI에 접속해보기
      • [코드스니펫] 서울시 미세먼지 OpenAPI
        http://openapi.seoul.go.kr:8088/6d4d776b466c656533356a4b4b5872/json/RealtimeCityAir/1/99
    • 크롬 익스텐션 JSONView를 설치해볼까요? 그럼 좀 더 예쁘게 JSON을 볼 수 있습니다.
      • [코드스니펫] Jsonview
        https://chrome.google.com/webstore/detail/jsonview/chklaanhfefbnpoihckbnefhakgolnmc?hl=ko
    • JSON은, Key:Value로 이루어져 있습니다. 자료형 Dictionary와 아주- 유사하죠 👉 위 예제에서는 RealtimeCityAir라는 키 값에 딕셔너리 형 value가 들어가있고, 그 안에 row라는 키 값에는 리스트형 value가 들어가있습니다.
  • 2) 클라이언트→서버: GET 요청 이해하기

    👉 **API는 은행 창구와 같은 것!** 같은 예금 창구에서도 개인 고객이냐 기업 고객이냐에 따라 가져와야 하는 것 / 처리해주는 것이 다른 것처럼, 클라이언트가 요청 할 때에도, "타입"이라는 것이 존재합니다. * GET → 통상적으로! 데이터 조회(Read)를 요청할 때 예) 영화 목록 조회 * POST → 통상적으로! 데이터 생성(Create), 변경(Update), 삭제(Delete) 요청 할 때 예) 회원가입, 회원탈퇴, 비밀번호 수정 이 중에서 오늘은 GET 방식에 대해 배워보겠습니다. (POST는 4주차에 배웁니다) - **GET** [기생충](https://movie.naver.com/movie/bi/mi/basic.nhn?code=161967)
      ```jsx
      https://movie.naver.com/movie/bi/mi/basic.nhn?code=161967
      
      위 주소는 크게 두 부분으로 쪼개집니다. 바로 "?"가 쪼개지는 지점인데요.
      "?" 기준으로 앞부분이 <서버 주소>, 뒷부분이 [영화 번호] 입니다.
      
      * 서버 주소: https://movie.naver.com/movie/bi/mi/basic.nhn
      * 영화 정보: code=161967
      ```
      
      <aside>
      👉 **GET 방식으로 데이터를 전달하는 방법**
      
      ?  : 여기서부터 전달할 데이터가 작성된다는 의미입니다.
      & : 전달할 데이터가 더 있다는 뜻입니다.
      
      예시) google.com/search?q=아이폰&sourceid=chrome&ie=UTF-8
      
               위 주소는 google.com의 search 창구에 다음 정보를 전달합니다!
               q=아이폰                        (검색어)
               sourceid=chrome        (브라우저 정보)
               ie=UTF-8                      (인코딩 정보)
      
      </aside>
      
      <aside>
      👉 **여기서 잠깐, 그럼 code라는 이름으로 영화번호를 주자!는 것은
      누가 정하는 것일까요?**
      
      → 네, 바로 프론트엔드 개발자와 백엔드 개발자가 미리 정해둔 **약속**입니다.
      
      프론트엔드: *"code라는 이름으로 영화번호를 주면 될까요?"*
      백엔드: *"네 그렇게 하시죠. 그럼 code로 영화번호가 들어온다고 생각하고 코딩하고 있을게요"*
      
      </aside>
      

08. Fetch 시작하기 (1)

  • 1) Fetch 연습을 위한 파일

    📌 `prac2.html` 를 만들고 시작합니다! - **[코드스니펫] fetch 연습하기**
      ```sql
      <!doctype html>
      <html lang="ko">
      <head>
          <meta charset="UTF-8">
          <title>Fetch 시작하기</title>
          <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
      		<script>
      
      		</script>
      </head>
      <body>
          Fetch 연습을 위한 페이지
      </body>
      </html>
      ```
      
  • 2) Fetch 시작하기

    • 크롬 개발자 도구에 다음과 같이 써보세요 😎 참고! Fetch를 쓰면서 jQuery를 사용할 것이기 때문에 jQuery를 임포트한 페이지에서만 동작 할 거에요! 즉, [http://google.com/](http://google.com/) 과 같은 화면에서 개발자도구를 열면, jQuery가 임포트 되어있지 않기 때문에 아래와 같은 에러가 뜹니다. *Uncaught TypeError: $ is not a function* → jQuery 라는 게 없다는 뜻 - **[코드스니펫] 미세먼지 OpenAPI** ```html http://spartacodingclub.shop/sparta_api/seoulair ``` - **[코드스니펫] Fetch 기본 골격** ```jsx fetch("여기에 URL을 입력").then(res => res.json()).then(data => { console.log(data) }) ``` Fetch 코드 해설 ```jsx fetch("여기에 URL을 입력") // 이 URL로 웹 통신을 요청한다. 괄호 안에 다른 것이 없다면 GET! .then(res => res.json()) // 통신 요청을 받은 데이터는 res라는 이름으로 JSON화 한다 .then(data => { console.log(data) // 개발자 도구에 찍어보기 }) // JSON 형태로 바뀐 데이터를 data라는 이름으로 붙여 사용한다 ```
    • Fetch 코드 설명
      • fetch("여기에 URL을 입력") ← 이 URL로 웹 통신 요청을 보낼 거야!

        • ← 이 괄호 안에 URL밖에 들어있지 않다면 기본상태인 GET!
      • .then() ← 통신 요청을 받은 다음 이렇게 할 거야!

      • res ⇒ res.json()

        • ← 통신 요청을 받은 데이터는 res 라는 이름을 붙일 거야(변경 가능)
        • ← res는 JSON 형태로 바꿔서 조작할 수 있게 할 거야!
      • .then(data ⇒ {}) ←JSON 형태로 바뀐 데이터를 data 라는 이름으로 붙일거야

        👀 리마인드 GET 요청은, url뒤에 아래와 같이 붙여서 데이터를 가져갑니다. http://naver.com?param=value¶m2=value2

        POST 요청은, data : {} 에 넣어서 데이터를 가져갑니다.
        data: { param: 'value', param2: 'value2' },

      • success: 성공하면, response 값에 서버의 결과 값을 담아서 함수를 실행한다.

        😎 결과가 어떻게 res에 들어가나요? then이 뭐에요? → 일단 모르는 느낌이 있어도 받아들이셔야 합니다..! 형태를 암기하세요! (대부분의 개발자들도 내부 원리는 코드를 안 뜯어봐서 몰라요.^^;;)

09. Fetch 시작하기 (2)

  • 1) Fetch 통신의 결과 값을 이용해보기

    😎 천천히 따라해볼 수 있도록 복습자료를 첨부해요! 1. 미세먼지 데이터가 어디에 있는지 찾기
      ![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/cf6e770d-9618-4c1d-beef-afb23b3cd2c9/Untitled.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/cf6e770d-9618-4c1d-beef-afb23b3cd2c9/Untitled.png)
    
      <aside>
      💁 위 그림과 같이 RealtimeCityAir > row 에 미세먼지 데이터가 들어있습니다. 이걸 꺼내볼까요?
      
      </aside>
      
      ```jsx
      fetch("http://spartacodingclub.shop/sparta_api/seoulair")
      	.then(res => res.json()) 
      	.then(data => { 
      		**console.log(data['RealtimeCityAir']['row'][0]);**
      	})
      ```
      
    1. 반복문으로 구 데이터를 출력해보기

      https://s3-us-west-2.amazonaws.com/secure.notion-static.com/dc6ab951-95aa-4415-8977-fc988e04e3cc/Untitled.png

      💁 row의 값을 `rows`에 담았으니, 반복문을 이용해보겠습니다!
      fetch("http://spartacodingclub.shop/sparta_api/seoulair") // 기본 요청(GET)
      	.then(res => res.json()) // 요청해서 받은 데이터를 JSON화
      	.then(data => { // JSON화 한 데이터를 다시 data로 이름짓기
      		let rows = data['RealtimeCityAir']['row']
      		**rows.forEach((a) => {
      			// 미세먼지 데이터 리스트의 길이만큼 반복해서 하나씩 개발자 도구에서 보기
      			console.log(a)**
      		})
      	})
    2. 구 데이터에서 구 이름, 미세먼지 수치를 골라내어 출력하기

      https://s3-us-west-2.amazonaws.com/secure.notion-static.com/41a0dbc3-2ad1-458f-baeb-08961f950b25/Untitled.png

      💁 구 이름 키 값인 "`MSRSTE_NM`", 미세먼지 수치 키값인 "`IDEX_MVL`"의 밸류를 출력합시다!
      fetch("http://spartacodingclub.shop/sparta_api/seoulair") // 기본 요청(GET)
      	.then(res => res.json()) // 요청해서 받은 데이터를 JSON화
      	.then(data => { // JSON화 한 데이터를 다시 data로 이름짓기
      		let rows = data['RealtimeCityAir']['row']
      		rows.forEach((a) => {
      			// 미세먼지 데이터 리스트의 길이만큼 반복해서 하나씩 개발자 도구에서 보기
      			**// 구의 이름, 미세먼지 수치 값을 개발자 도구에서 찍어보기
      			console.log(a['MSRSTE_NM'], a['IDEX_MVL'])**
      		})
      	})
      • [완성코드] 미세먼지 데이터 찍어보기
        fetch("http://spartacodingclub.shop/sparta_api/seoulair").then(res => res.json()).then(data => { 
        		let rows = data['RealtimeCityAir']['row']
        		rows.forEach((a) => {
        			console.log(a['MSRSTE_NM'], a['IDEX_MVL'])
        		})
        	})

10. Fetch 연습하기 (1)

  • 1) 서울시 OpenAPI(실시간 미세먼지 상태)를 이용하기 📌 `prac3.html` 를 만들고 시작합니다! - **[코드스니펫] fetch 퀴즈(보기)** ```python http://spartacodingclub.shop/ajaxquiz/01 ``` - **[코드스니펫] fetch 퀴즈(뼈대)** ```jsx 미세먼지 API로Fetch 연습하고 가기!

    Fetch 연습하자!


    1. 서울시 OpenAPI(실시간 미세먼지 상태)를 이용하기

    모든 구의 미세먼지를 표기해주세요

    업데이트 버튼을 누를 때마다 지웠다 새로 씌여져야 합니다.

    업데이트
    • 중구 : 82
    • 종로구 : 87
    • 용산구 : 84
    • 은평구 : 82
    ``` - **[코드스니펫] fetch 기본 골격** ```jsx fetch("여기에 URL을 입력").then(res => res.json()).then(data => { console.log(data) }) ``` - **[코드스니펫] 미세먼지 OpenAPI** ```html http://spartacodingclub.shop/sparta_api/seoulair ``` - **[코드스니펫] fetch 퀴즈1(완성)** ```jsx 미세먼지 API로Fetch 연습하고 가기!

    Fetch 연습하자!


    1. 서울시 OpenAPI(실시간 미세먼지 상태)를 이용하기

    모든 구의 미세먼지를 표기해주세요

    업데이트 버튼을 누를 때마다 지웠다 새로 씌여져야 합니다.

    업데이트
    • 중구 : 82
    • 종로구 : 87
    • 용산구 : 84
    • 은평구 : 82
    ``` 1. 뼈대에 fetch 기본 골격을 붙여봅시다! ```jsx ``` - 브라우저 개발자도구(오른쪽 클릭→검사)에서 console탭에서 확인해 보러 가시죠! 💁 data에서 RealtimeCityAir를 타고, row를 타고 들어가야 하네요! 2. 어떤 데이터를 가져와야할 지, console.log()로 찾아봅시다! 💁 리스트는 어떻게 하고 싶죠? 막 반복을 하고 싶지 않나요? `forEach`! ```jsx let rows = data['RealtimeCityAir']['row'] rows.forEach((a) => { let gu_name = a['MSRSTE_NM'] let gu_mise = a['IDEX_MVL'] console.log(gu_name, gu_mise) }) ``` - `forEach`문을 사용해서 하나하나 뽑아 보시죠! forEach문의 만듬새 오타에 주의하세요! → 문법을 모두 외우지 않아도 괜찮아요! 그때그때 가져다 쓰세요! - 구 이름, 미세먼지 수치와 관련된 데이터를 뽑아서 console에서 또 확인해 봅시다! 3. 웹에 붙일 temp_html을 만들어봅시다! ```jsx let rows = data['RealtimeCityAir']['row'] rows.forEach((a) => { let gu_name = a['MSRSTE_NM'] let gu_mise = a['IDEX_MVL'] console.log(gu_name, gu_mise) let temp_html = `
  • 중구 : 82
  • ` $('#names-q1').append(temp_html) }) ``` 💁 어디에 들어갈 지를 확인하고, 아이디 값을 지정해준 뒤 append! 4. 가져올 데이터를 temp_html에 넣어봅시다! ```jsx let rows = data['RealtimeCityAir']['row'] rows.forEach((a) => { let gu_name = a[] let gu_mise = a[] console.log(gu_name, gu_mise) let temp_html = `
  • ${gu_name} : ${gu_mise}
  • ` $('#names-q1').append(temp_html) }) ``` 5. 처음에 보이는 정보는 지워줍시다! ```jsx let rows = data['RealtimeCityAir']['row'] $('#names-q1').empty() rows.forEach((a) => { let gu_name = a[] let gu_mise = a[] console.log(gu_name, gu_mise) let temp_html = `
  • ${gu_name} : ${gu_mise}
  • ` $('#names-q1').append(temp_html) }) ```

11. Fetch 연습하기 (2)

👉 [한걸음 더] 미세먼지 수치가 40이상인 곳은 빨갛게 보여줄까요?
  • [코드스니펫] fetch 연습(완성-한걸음더)
    <!doctype html>
    <html lang="ko">
    
    <head>
        <meta charset="UTF-8">
        <title>미세먼지 API로Fetch 연습하고 가기!</title>
    
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    
        <style>
            div.question-box {
                margin: 10px 0 20px 0;
            }
            .bad {
                color: red;
            }
        </style>
    
        <script>
    			function q1() {
            fetch("http://spartacodingclub.shop/sparta_api/seoulair").then((response) => response.json()).then((data) => {
                $('#names-q1').empty()
    						let rows = data['RealtimeCityAir']['row']
                rows.forEach((a) => {
                    let gu_name = a['MSRSTE_NM']
    								let gu_mise = a['IDEX_MVL']
    								let temp_html = ``
    								if (gu_mise > 40) {
    									temp_html = `<li class="bad">${gu_name} : ${gu_mise}</li>`
    								} else {
    									temp_html = `<li>${gu_name} : ${gu_mise}</li>`
    								}
                    $('#names-q1').append(temp_html)
                });
              })
          }
        </script>
    
    </head>
    
    <body>
        <h1>Fetch 연습하자!</h1>
    
        <hr/>
    
        <div class="question-box">
            <h2>1. 서울시 OpenAPI(실시간 미세먼지 상태)를 이용하기</h2>
            <p>모든 구의 미세먼지를 표기해주세요</p>
            <p>업데이트 버튼을 누를 때마다 지웠다 새로 씌여져야 합니다.</p>
            <button onclick="q1()">업데이트</button>
            <ul id="names-q1">
                <li>중구 : 82</li>
                <li>종로구 : 87</li>
                <li>용산구 : 84</li>
                <li>은평구 : 82</li>
            </ul>
        </div>
    </body>
    
    </html>
  • 1) fetch 연습하기(한걸음 더)
    • 일단 빨간색으로 바꿔주려면? 💁 temp_html에 css 속성을 먹인 html태그를 넣으면 되겠죠? ```jsx ```
    • 미세먼지 수치가 40을 넘긴다면 빨간색을 줘야한다면? → gu_mise 값을 확인하는 조건문을 달아줍시다! 💁 비어있는 temp_html을 먼저 만들어 준 다음, gu_mise를 확인한 값이 True일 때, 클래스를 먹이고 False일 때 이전 그대로 빼주면 되겠죠? ```jsx ```

12. Fetch 퀴즈 (1)

  • 1) 서울시 OpenAPI(실시간 따릉이 현황)을 이용하기 📌 `prac4.html` 를 만들고 시작합니다! - **[코드스니펫] fetch 퀴즈2(보기)** ```python http://spartacodingclub.shop/ajaxquiz/02_1 ``` - **[코드스니펫] fetch 퀴즈2** ```html Fetch 연습하고 가기!

    Fetch 연습하자!


    2. 서울시 OpenAPI(실시간 따릉이 현황)를 이용하기

    모든 위치의 따릉이 현황을 보여주세요

    업데이트 버튼을 누를 때마다 지웠다 새로 씌여져야 합니다.

    업데이트
    거치대 위치 거치대 수 현재 거치된 따릉이 수
    102. 망원역 1번출구 앞 22 0
    103. 망원역 2번출구 앞 16 0
    104. 합정역 1번출구 앞 16 0
    ``` - **[코드스니펫] 따릉이 OpenAPI** ```html http://spartacodingclub.shop/sparta_api/seoulbike ``` - **[코드스니펫] fetch 퀴즈2(완성)** ```jsx Fetch 연습하고 가기!

    Fetch 연습하자!


    2. 서울시 OpenAPI(실시간 따릉이 현황)를 이용하기

    모든 위치의 따릉이 현황을 보여주세요

    업데이트 버튼을 누를 때마다 지웠다 새로 씌여져야 합니다.

    업데이트
    거치대 위치 거치대 수 현재 거치된 따릉이 수
    102. 망원역 1번출구 앞 22 0
    103. 망원역 2번출구 앞 16 0
    104. 합정역 1번출구 앞 16 0
    ```

13. Fetch 퀴즈 (2)

👉 [한걸음 더] 따릉이 대수가 5대 미만인 곳은 빨갛게 보여주면 어떨까요?
  • [코드스니펫] fetch 퀴즈2(보기2)
    http://spartacodingclub.shop/ajaxquiz/02_2
  • [코드스니펫] fetch 퀴즈2(완성2)
    <!doctype html>
    <html lang="ko">
    
    <head>
        <meta charset="UTF-8">
        <title>Fetch 연습하고 가기!</title>
        <!-- JQuery를 import 합니다 -->
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    
        <style type="text/css">
            div.question-box {
                margin: 10px 0 20px 0;
            }
    
            table {
                border: 1px solid;
                border-collapse: collapse;
            }
    
            td,
            th {
                padding: 10px;
                border: 1px solid;
            }
    
            .red {
                color: red;
            }
        </style>
    
        <script>
            function q1() {
                fetch("http://spartacodingclub.shop/sparta_api/seoulbike").then(response => response.json()).then(data => {
                    $('#names-q1').empty()
                    let rows = data['getStationList']['row']
                    rows.forEach(a => {
                        let name = a['stationName']
                        let rack = a['rackTotCnt']
                        let bike = a['parkingBikeTotCnt']
    
                        let temp_html = ``
    
                        if (bike < 5) {
                            temp_html = `<tr class="red">
                                                <td>${name}</td>
                                                <td>${rack}</td>
                                                <td>${bike}</td>
                                            </tr>`
                        } else {
                            temp_html = `<tr>
                                                <td>${name}</td>
                                                <td>${rack}</td>
                                                <td>${bike}</td>
                                            </tr>`
                        }
    
                        $('#names-q1').append(temp_html)
                    })
                })
    
            }
        </script>
    
    </head>
    
    <body>
        <h1>Fetch 연습하자!</h1>
    
        <hr />
    
        <div class="question-box">
            <h2>2. 서울시 OpenAPI(실시간 따릉이 현황)를 이용하기</h2>
            <p>모든 위치의 따릉이 현황을 보여주세요</p>
            <p>업데이트 버튼을 누를 때마다 지웠다 새로 씌여져야 합니다.</p>
            <button onclick="q1()">업데이트</button>
            <table>
                <thead>
                    <tr>
                        <td>거치대 위치</td>
                        <td>거치대 수</td>
                        <td>현재 거치된 따릉이 수</td>
                    </tr>
                </thead>
                <tbody id="names-q1">
                    <tr>
                        <td>102. 망원역 1번출구 앞</td>
                        <td>22</td>
                        <td>0</td>
                    </tr>
                    <tr>
                        <td>103. 망원역 2번출구 앞</td>
                        <td>16</td>
                        <td>0</td>
                    </tr>
                    <tr>
                        <td>104. 합정역 1번출구 앞</td>
                        <td>16</td>
                        <td>0</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </body>
    
    </html>
profile
Walk on the water!

0개의 댓글