목적

: 그룹 채팅방에서 실시간 채팅을 할 수 있는 기능을 구현하고자 한다. 한 사용자가 메세지를 송신하면 채팅방에 있는 다른 사용자들이 메세지를 수신할 수 있어야 한다. 실시간으로 이것이 가능하게 하려면 어떤식으로 흐름을 구성해야 하는지 정리해보고자 한다.

 

고려사항

: 현재의 기획은 단일 서버를 전제로 한다. 따라서 서버가 여러 대일 경우 서로 다른 서버에서 관리되고 있는 웹소켓 세션에 대한 공유가 이뤄져야 한다. 이러한 사항에 대해서는 우선 단일 서버를 전제로 한 구현이 완료된 후에 고도화 작업에서 고려하여 수정해보고자 한다.

 

사용 기술

- WebSocket

- MySQL

 

흐름 설명

  1. 사용자 로그인한다.
  2. 사용자가 특정한 채팅방에 입장한다.
  3. 채팅방 입장과 동시에 WebSocket 연결 및 WebSocketSession 생성이 진행된다.
    • WebSocketSession의 역할은 다음과 같다.
      • 클라이언트 - 서버 연결 상태 추적
      • 연결된 클라이언트 식별
      • 메세지 전송
      • 연결 열거나 종료
  4. Map의 키 값은 채팅방의 아이디를 value 값은 Set<WebSocketSession>으로 받게 하여 세션을 저장한다.
    • roomId가 1인 채팅방에 사용자 a, b, c가 접속 중이라면 이 사용자들의 연결 여부를 확인해주는 세션 객체 세 개가 Set<WebSocketSession>에 담기고 roomId인 1이 Key, Set이 Value가 되어 Map에 저장된다고 보시면 된다.
  5. 채팅방에 접속한 후 사용자가 해당 채팅방의 멤버인지 여부를 확인하고 아닌 경우 채팅방 참여자를 저장하는 테이블에 저장한다.
    • 멤버인 경우 저장 로직을 넘깁니다.
  6. 메세지 송신 발생 시 데이터 베이스에 저장 후 채팅방에 접속 중인 사용자에게 전달된다.
    • 이때 WebSocketSession이 사용된다.
    • Set에 저장된 WebSocketSession 전체에 메세지를 전달하는 방식이다. 이때 전체를 순회하면서 각 세션이 유효한지 확인 후 유효한 경우에만 메세지를 전달한다. 이는 Set에는 저장되어 있더라도 실제로는 어떠한 이유에 의해 연결이 끊겨있을 수 있다는 가능성을 고려한 것이다.
    • 데이터베이스에 저장 후 사용자에게 메세지를 전달하는 이유는 메세지가 소실될 가능성을 염두한 것이다. 다른 클라이언트에게 메세지가 전달됐는데 데이터베이스에는 해당 메세지가 없는 것은 문제가 될 것이다.
  7. 접속 중이 아닌 경우 접속 시 DB에서 불러오는 방식으로 조회한다.
    • 접속 중이 아닌 경우 메시지를 받을 수 없다.
    • 다시 접속한 경우 웹소켓에 의해 메세지를 받는 것은 불가능하나 기존에 주고받은 메세지가 데이터베이스에 저장되어 있기 때문에 이를 조회하는 방식으로 전의 메세지를 확인할 수 있다.
  8. 채팅방에서 퇴장 시 Set에서 삭제한다.
    • 이때 ‘퇴장’은 채팅방의 멤버이기를 그만한다는 뜻이 아니라 채팅방에 접속중이지 않은 상태가 되는 것을 의미한다.
    • 채팅방에 접속중이지 않다는 것은 서버와의 연결을 종료한다는 것이기 때문에 WebSocketSession을 Set에서 삭제한다.
  9. 채팅방에 접속 중인 인원 없을 시 key 값이 해당 roomId인 데이터 삭제한다.
    • 채팅방에 접속 중인 인원이 없으면 WebSocketSession을 담아서 저장할 데이터가 필요 없어진다.
    • Set<WebSocketSession>이 빈 상태가 되면 해당 채팅방의 roomId를 키 값으로 가진 데이터를 Map에서 삭제한다.

JS 활용 및 JQuery

JQuery: JS를 더 쉽게 작성하기 위해 작성한 라이브러리

- import 필요: <head><script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script></head>

- JQuery에서의 이름표: id = 이름            css에서의 이름표: class  = 이름

 

1. text()

function 함수명(){

     $('#id값').text('텍스트');

}

 

2. empty(): 삭제

function 함수명(){

     $('#id값').empty();

}

 

3. append(): 삽입

function 함수명(){

     let temp = `<p>텍스트</p>`          /*반드시 키보드의 숫자 1 옆의 ` 사용*/

     $('#id값').append(temp);

}

function 함수명(){
     let fruits = ['사과','배','감','귤','수박'];
     $("#q1").empty();
     
     let a = fruits[0];
     let temp = `<p>${a}</p>`          /*반드시 키보드의 숫자 1 옆의 ` 사용*/
     $('#id값').append(temp);
}

 

4. toggle(): 껐다 켜기

function openclose(){
	$("#postingbox").toggle();
}

 

5. val(): 값을 가져오기

function makecard(){
	let image = $("#image").val();
	alert(image);
}

 

 


 

 

fetch

: 인터넷을 통해 서버에서 데이터를 요청, 받아오는 과정

 

API

- 허락된 곳의 접근만 허용

 

OpenAPI

- 누구나 접근 허용

/*서울 미세먼지 API*/

http://openapi.seoul.go.kr:8088/6d4d776b466c656533356a4b4b5872/json/RealtimeCityAir/1/99

 

JSON

: 데이터를 주고 받는 형식으로 문자 기반의 표준 포멧

- KEY: VALUE로 구

 

GET요청: 클라이언트가 서버에 데이터 조회를 요청하는 타입

링크: https://movie.daum.net/moviedb/main?movieId=68593

- 서버위치: 첫 번째 / 전까지: https://entertain.daum.net

- 창구 이름: 첫 번째 /에서 ? 전까지: moviedb/main

- 가져가려는 데이터: ? 뒤의 부분: movieId=68590

 

?: ?부터 전달할 데이터가 작성됨

&: 전달할 데이터 더 있음

 

링크: google.com/search?q=아이폰&sourceid=chrome&ie=UTF-8

- 서버위치: google.com

- 창구 이름: search

------하단은 전달할 데이터------

- 검색어: q=아이폰

- 브라우저 정보: sourceid=chrome     // &로 연결

- 인코딩 정보: ie=UTF-8

 

POST 요청: 클라이언트가 서버에 데이터 생성, 변경, 삭제를 요청하는 타입

 

 

fetch 연습

: 서버에서 데이터 가져오기

        function hey() {
            let url = "http://spartacodingclub.shop/sparta_api/seoulair";
            fetch(url).then(res => res.json()).then(data => {
                console.log(data["RealtimeCityAir"]["row"][0])
            })
        }

 

 

 

/*작성한 전체 코드들은 vs에서 확인*/

 

 

 

 

 

 

 

 

 

 

 

<2주차>

 

1. 스파르타플릭스 프로젝트

- import 부트스트랩

- 폰트 적용

- 원하는 부트스트랩 위에서 오른쪽 마우스 -> 검사 -> 해당 부분(<div>) 찾기 -> edit as html -> 복붙

- <body>같이 태그가 하나밖에 존재하지 않는 경우: class 이름 안 붙여줘도 됨

- <img src="이미지 url 복붙" class="card-img-top" alt="...">

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>스파르타플릭스</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <style>
        @import url('https://fonts.googleapis.com/css2?family=Noto+Serif+KR:wght@200..900&display=swap');

        * {
            font-family: "Noto Serif KR", serif;
            font-optical-sizing: auto;
            font-weight: normal;
            font-style: normal;
        }

        .main {
            color: white;
            /*글씨*/

            /*배경*/
            background-image: url('https://occ-0-1123-1217.1.nflxso.net/dnm/api/v6/6AYY37jfdO6hpXcMjf9Yu5cnmO0/AAAABeIfo7VL_VDyKnljV66IkR-4XLb6xpZqhpLSo3JUtbivnEW4s60PD27muH1mdaANM_8rGpgbm6L2oDgA_iELHZLZ2IQjG5lvp5d2.jpg?r=e6e.jpg');
            background-position: center;
            background-size: cover;
        }

        body {
            background-color: black;
        }

        .mycards {
            width: 1200px;
            margin: 20px auto 20px auto;
        }

        .mypostingbox {
            width: 500px;
            margin: 20px auto 20px auto;
            border: 1px solid white;
            padding: 20px;
            border-radius: 5px;
        }
        .form-floating > input{
            background-color: transparent;
            color: white;
        }
        .form-floating > label{
            color: white;
        }
        .input-group > label{
            background-color: transparent;
            color: white
        }
        .mypostingbox > button{
            width: 100%;
        }
    </style>
</head>

<body>
    <header class="p-3 text-bg-dark">
        <div class="container">
            <div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
                <a href="/" class="d-flex align-items-center mb-2 mb-lg-0 text-white text-decoration-none">
                    <svg class="bi me-2" width="40" height="32" role="img" aria-label="Bootstrap">
                        <use xlink:href="#bootstrap"></use>
                    </svg>
                </a>

                <ul class="nav col-12 col-lg-auto me-lg-auto mb-2 justify-content-center mb-md-0">
                    <li><a href="#" class="nav-link px-2 text-danger">spartaflix</a></li>
                    <li><a href="#" class="nav-link px-2 text-white">홈</a></li>
                    <li><a href="#" class="nav-link px-2 text-white">시리즈</a></li>
                    <li><a href="#" class="nav-link px-2 text-white">영화</a></li>
                    <li><a href="#" class="nav-link px-2 text-white">내가 찜한 컨텐츠</a></li>
                </ul>

                <form class="col-12 col-lg-auto mb-3 mb-lg-0 me-lg-3" role="search">
                    <input type="search" class="form-control form-control-dark text-bg-dark" placeholder="Search..."
                        aria-label="Search">
                </form>

                <div class="text-end">
                    <button type="button" class="btn btn-outline-light me-2">Login</button>
                    <button type="button" class="btn btn-danger">Sign-up</button>
                </div>
            </div>
        </div>
    </header>
    <div class=main>
        <div class="container-fluid py-5">
            <h1 class="display-5 fw-bold">킹덤</h1>
            <p class="col-md-8 fs-4">병든 왕을 둘러싸고 흉흉한 소문이 떠돈다. 어둠에 뒤덮인 조선, 기이한 역병에 신음하는 산하. 정체 모를 악에 맞서 백성을 구원할 희망은 오직
                세자뿐이다.</p>
            <button type="button" class="btn btn-outline-light">영화 기록하기</button>
            <button type="button" class="btn btn-outline-light">상세정보</button>
        </div>
    </div>
    <div class=mypostingbox>
        <div class="form-floating mb-3">
            <input type="email" class="form-control" id="floatingInput" placeholder="영화 이미지 주소">
            <label for="floatingInput">영화 이미지 주소</label>
        </div>
        <div class="form-floating mb-3">
            <input type="email" class="form-control" id="floatingInput" placeholder="영화 제목">
            <label for="floatingInput">영화 제목</label>
        </div>
        <div class="input-group mb-3">
            <label class="input-group-text" for="inputGroupSelect01">별점</label>
            <select class="form-select" id="inputGroupSelect01">
                <option selected>별점 선택</option>
                <option value="1">⭐</option>
                <option value="2">⭐⭐</option>
                <option value="3">⭐⭐⭐</option>
                <option value="3">⭐⭐⭐⭐</option>
                <option value="3">⭐⭐⭐⭐⭐</option>
            </select>
        </div>
        <div class="form-floating mb-3">
            <input type="email" class="form-control" id="floatingInput" placeholder="영화 추천 이유">
            <label for="floatingInput">영화 추천 이유</label>
        </div>
        <button type="button" class="btn btn-danger">기록하기</button>
    </div>
    <div class=mycards>
        <div class="row row-cols-1 row-cols-md-4 g-4">
            <div class="col">
                <div class="card">
                    <img src="https://movie-phinf.pstatic.net/20210728_221/1627440327667GyoYj_JPEG/movie_image.jpg"
                        class="card-img-top" alt="...">
                    <div class="card-body">
                        <h5 class="card-title">영화 제목</h5>
                        <p class="card-text">⭐⭐⭐</p>
                        <p class="card-text">영화 코멘트</p>
                    </div>
                </div>
            </div>
            <div class="col">
                <div class="card">
                    <img src="https://movie-phinf.pstatic.net/20210728_221/1627440327667GyoYj_JPEG/movie_image.jpg"
                        class="card-img-top" alt="...">
                    <div class="card-body">
                        <h5 class="card-title">영화 제목</h5>
                        <p class="card-text">⭐⭐⭐</p>
                        <p class="card-text">영화 코멘트</p>
                    </div>
                </div>
            </div>
            <div class="col">
                <div class="card">
                    <img src="https://movie-phinf.pstatic.net/20210728_221/1627440327667GyoYj_JPEG/movie_image.jpg"
                        class="card-img-top" alt="...">
                    <div class="card-body">
                        <h5 class="card-title">영화 제목</h5>
                        <p class="card-text">⭐⭐⭐</p>
                        <p class="card-text">영화 코멘트</p>
                    </div>
                </div>
            </div>
            <div class="col">
                <div class="card">
                    <img src="https://movie-phinf.pstatic.net/20210728_221/1627440327667GyoYj_JPEG/movie_image.jpg"
                        class="card-img-top" alt="...">
                    <div class="card-body">
                        <h5 class="card-title">영화 제목</h5>
                        <p class="card-text">⭐⭐⭐</p>
                        <p class="card-text">영화 코멘트</p>
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>

</html>

 

최종 화면


자바 스크립트

: 브라우저 동적 기능 구현 위해 사용                             // 오랜 기간을 거쳐 표준이 됨

용도: 웹페이지, 서버 생성

문법

     1. 변수: 값 할당                    

         초기화

               let 변수명 = 정수 또는 실수

               let 변수명 = '문자열'

 

          출력(개발자 도구)

               console.log(변수명)

               console.log(변수명 + 변수명)     //사칙연산 또는 연결해서 출력

 

     2. 자료형

          배열: 순서 有

               let 변수명 = []

               let 변수명 = ['수박', '딸기', '체리']

               /*출력: console.log(변수명[0])*/

               /*배열 길이: console.log(변수명.length)*/

 

          딕셔너리: key - value 값의 묶음

               let 변수명 = {}

               let 변수명 = {'name': '영수', 'age': 27}

                /*출력: console.log(변수명)*/

                /*출력: console.log(a['name'])*/

 

          배열, 딕셔너리 조합

let a = [
	{'name':'영수','age':27},
	{'name':'철수','age':15},
	{'name':'영희','age':20}
]
console.log(a[0]['name']) //영수
console.log(a[1]['age']) //15

        

 

     3. 함수

          1. alert: 알림창 띄우는 함

          function 함수명(){

               alert('안녕하세요');

          }

          => 특정 버튼을 눌렀을 때 알림창 띄우고 싶은 경우: 해당 버튼의 태그로 가서 onclick = "함수명()" 작성

          <button onclick = "hey()" type="button" class="btn btn-outline-light">영화 기록하기</button>

 

          2. document.getElementById('title').style.color = 'red';

          - JQery로 단순화 가능하니 pass

 

     4. 조건문

           if{} else{}

 

     5. 반복문

          forEach: 변수명.forEach((a) => {코드코드})

          /*따로 찾아보니 for문도 가능한*/

 

 

 

 

 

 

 

 

 

 

 

 

<1주차>

 

3. CSS: 디자인

 

- 방법

*지칭 대상이 있어야 꾸미기 가능*

1단계: 꾸미고자 하는 대상에 이름 달기: <h1 class = "myTitle>로그인 페이지</h1>

2단계: head 안에 꾸미고자 하는 방식 서술: <head>.myTitle{color:red}</head>

 

- 태그

//배경 관련

1. background-color: 배경 색

2. background-image: 배경 이미지

3. background-size: 배경 크기

 

//사이즈

1. width: 가로

2. height: 세로

 

//폰트

1. font-size

2. font-weight

3. font-family

4. color

 

//간격

1. margin: 구역 바깥 여백

2. padding: 구역 안쪽 여백

3. border-radius: 곡선 경계

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>로그인</title>
    <style>
        .myTitle{
            /*px: 웹에서의 길이 단위*/
            width : 300px;  /*width: 가로*/
            height : 200px; /*height: 세로*/

            color:white;
            text-align: center; /*텍스트 가운데 정렬*/

            padding-top: 30px;
            border-radius: 8px;

            /*background-image는 아래 3줄이 세트로 다님님*/
            background-image: url('https://www.ancient-origins.net/sites/default/files/field/image/Agesilaus-II-cover.jpg');  /*''안에 url 넣어주기*/
            background-position:center;
            background-size: cover;

        }
        .whole{/*전체 가운데 정렬하기기*/
            background-color: green;
            width: 300px;
            /*auto: 끝까지 이동동*/
            margin: 50px auto 0px auto  /*위 오른 아래 왼*/
        }
    </style>
</head>
<body>
    <div class = "whole">
        <div class = "myTitle">
            <h1>로그인 페이지</h1>
            <h5>아이디, 비밀번호를 입력해주세요</h5>
        </div>
        <p>ID: <input type = "text"/></p>
        <p>PW: <input type = "text"/></p>
        <button>로그인하기</button>
    </div>
</body>
</html>

 

- 구글 폰트          //https://fonts.google.com/?subset=korean

1단계: 원하는 폰트 클릭

2단계: Get font 클릭

3단계: <> Get embed code 클릭

4단계: Web 탭에서 import 클릭

5단계: style 안에 태그 복붙          //태그 겹치지 않도록 유의

6단계: CSS class 탭 코드 복사 후 *{ }를 css에 넣기

 

- 부트스트랩

: 예쁜 CSS 모아둔 것     //남이 작성한 코드 사용: 설정 필요

https://getbootstrap.com/docs/5.3/getting-started/introduction/

 

예시: 추억 앨범

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>나만의 추억 앨범</title>
    
    /*부트스트랩 import*/
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <style>
    	
        /*폰트 import*/
        @import url('https://fonts.googleapis.com/css2?family=Nanum+Pen+Script&display=swap');

        * {
            font-family: "Nanum Pen Script", cursive;
            font-weight: 400;
            font-style: normal;
        }

        .mytitle {
            height: 250px;
            background-color: green;
            color: white;

            /*가운데 정렬*/
            display: flex;
            flex-direction: column;
            /*이거 외에 display, align 등은 바꿀 것 없음*/
            align-items: center;
            justify-content: center;

            /*background-image는 아래 3줄이 세트로 다님*/
            background-image: url(https://images.unsplash.com/photo-1511992243105-2992b3fd0410?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80);
            /*''안에 url 넣어주기*/
            background-position: center;
            background-size: cover;
        }

        /*mytitle 안의 button을 의미*/
        .mytitle>button {
            width: 150px;
            height: 50px;
            background-color: transparent;
            color: white;
            border: 1px solid white;
            /*선의 굵기 1px, 실선, 흰색*/
            border-radius: 5px;

            margin-top: 20px;
        }

        .mycards {
            width: 1200px;
            margin: 30px auto 0px auto;
        }

        .mypostingbox{
            width: 500px;
            margin: 30px auto 0px auto;
            padding:20px;
            box-shadow: 0px 0px 3px 0px black;
            border-radius: 5px;
        }

        .mybutton{
            /*가운데 정렬*/
            display: flex;
            flex-direction: row;
            /*이거 외에 display, align 등은 바꿀 것 없음*/
            align-items: center;
            justify-content: center;
        }
        .mybutton > button{
            margin-right: 5px;
        }
    </style>
</head>

<body>
    <div class="mytitle">
        <h1>나만의 추억앨범</h1>
        <button>추억 저장하기</button>
    </div>
    <div class="mypostingbox">
        <div class="form-floating mb-3">
            <input type="email" class="form-control" id="floatingInput" placeholder="앨범 이미지">
            <label for="floatingInput">앨범 이미지</label>
        </div>
        <div class="form-floating mb-3">
            <input type="email" class="form-control" id="floatingInput" placeholder="앨범 제목">
            <label for="floatingInput">앨범 제목</label>
        </div>
        <div class="form-floating mb-3">
            <input type="email" class="form-control" id="floatingInput" placeholder="앨범 내용">
            <label for="floatingInput">앨범 내용</label>
        </div>
        <div class="form-floating mb-3">
            <input type="email" class="form-control" id="floatingInput" placeholder="앨범 날짜">
            <label for="floatingInput">앨범 날짜짜</label>
        </div>
        <div class = mybutton>
            <button type="button" class="btn btn-dark">뒤로가기</button>
            <button type="button" class="btn btn-outline-dark">닫기기</button>
        </div>
    </div>
    <div class="mycards">
        <div class="row row-cols-1 row-cols-md-4 g-4">
            <div class="col">
                <div class="card h-100">
                    <img src="https://images.unsplash.com/photo-1446768500601-ac47e5ec3719?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1446&q=80"
                        class="card-img-top" alt="...">
                    <div class="card-body">
                        <h5 class="card-title">앨범 제목</h5>
                        <p class="card-text">앨범 내용</p>
                    </div>
                    <div class="card-footer">
                        <small class="text-body-secondary">앨범 날짜</small>
                    </div>
                </div>
            </div>
            <div class="col">
                <div class="card h-100">
                    <img src="https://images.unsplash.com/photo-1446768500601-ac47e5ec3719?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1446&q=80"
                        class="card-img-top" alt="...">
                    <div class="card-body">
                        <h5 class="card-title">앨범 제목</h5>
                        <p class="card-text">앨범 내용</p>
                    </div>
                    <div class="card-footer">
                        <small class="text-body-secondary">앨범 날짜</small>
                    </div>
                </div>
            </div>
            <div class="col">
                <div class="card h-100">
                    <img src="https://images.unsplash.com/photo-1446768500601-ac47e5ec3719?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1446&q=80"
                        class="card-img-top" alt="...">
                    <div class="card-body">
                        <h5 class="card-title">앨범 제목</h5>
                        <p class="card-text">앨범 내용</p>
                    </div>
                    <div class="card-footer">
                        <small class="text-body-secondary">앨범 날짜</small>
                    </div>
                </div>
            </div>
            <div class="col">
                <div class="card h-100">
                    <img src="https://images.unsplash.com/photo-1446768500601-ac47e5ec3719?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1446&q=80"
                        class="card-img-top" alt="...">
                    <div class="card-body">
                        <h5 class="card-title">앨범 제목</h5>
                        <p class="card-text">앨범 내용</p>
                    </div>
                    <div class="card-footer">
                        <small class="text-body-secondary">앨범 날짜</small>
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>

</html>

 

 

*코드를 정렬하는 것이 가장 중요*

: Shift + Alt + F          //항상 정렬하자

 

*다양한 태그들이 있으니 필요한 것을 잘 서치하자*

*많이 만들어 보는게 좋을 듯하다*

*태그 종류별로 외울 필요x*

<1주차>

 

1. 웹 브라우저 작동 원리

- 브라우저 역할

          1. 요청하기

                     - 주소를 통해 API로 요청 보냄

          2. 받은 HTML, CSS, JS 그려주기

                     - API가 요청에 맞는 파일 보내주고 브라우저가 그것을 그림

 

- 클라이언트 / 서버

          클라이언트: 요청하는 쪽

           서버: 보내주는 쪽

 

- HTML: 뼈대

- CSS: 꾸미기

- JS: 움직이기


2. HTML: 뼈대

- 기본 과정

1단계: 폴더 생성(sparta)

2단계: 하위 폴더 생성(f)

3단계: VSCODE에서 하위 폴더 아래에 HTML 파일 생성

//VS Code 코드 자동 정렬: Shift + Alt + F

 

- 영역

     - <head> 영역: 페이지 속성 정보

               요소: meta, script, style, link, title 등...

     - <body> 영역: 페이지 내용

          요소: span, img, input, text area 등...


- 태그          // 외우지 말고 필요할 때 찾아 작성

 

<title>

ex) <title>스파르타코딩클럽 | HTML 기초</title>


구역 나누는 태그 예시

1. <div> 구역 분리 </div>

 

2. <p> 문단 </p>

 

3. <ul>

          <li>    </li>

4. </ul>


구역 내 콘텐츠 태그 예시

1. <h1> 제목 태그 </h1>           //페이지마다 하나씩 써 주기: 구글 검색이 잘 됨

 

2. <h2> 소제목 태그 </h2>

 

3. <h3> </h3>, <h4> </h4> , <h5> </h5> , <h6> </h6>  

 

4. span 태그

          <span style = "color : red">꾸며진글자</span>

 

5. a 태그

          <a href = "http://naver.com/"> 링크명</a>

 

6. img 태그

          <img src = "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png" />

 

7. input 태그

          <input type = "text" />

 

8. button 태그

          <button> 버튼</button>

 

9. text area 태그

          <textarea>블라블라</textarea>

 

10. 가로줄

          <hr>

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>스파르타코딩클럽 | HTML 기초</title>
</head>

<body>
    <!-- 구역을 나누는 태그들 -->
    <div>나는 구역을 나누죠</div>
    <p>나는 문단이에요</p>
    <ul>
        <li> bullet point!1 </li>
        <li> bullet point!2 </li>
    </ul>

    <!-- 구역 내 콘텐츠 태그들 -->
    <h1>h1은 제목을 나타내는 태그입니다. 페이지마다 하나씩 꼭 써주는 게 좋아요. 그래야 구글 검색이 잘 되거든요.</h1>
    <h2>h2는 소제목입니다.</h2>
    <h3>h3~h6도 각자의 역할이 있죠. 비중은 작지만..</h3>
    <hr>
    span 태그입니다: 특정 <span style="color:red">글자</span>를 꾸밀 때 써요
    <hr>
    a 태그입니다: <a href="http://naver.com/"> 하이퍼링크 </a>
    <hr>
    img 태그입니다: <img src="https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png" />
    <hr>
    input 태그입니다: <input type="text" />
    <hr>
    button 태그입니다: <button> 버튼입니다</button>
    <hr>
    textarea 태그입니다: <textarea>나는 무엇일까요?</textarea>
</body>

</html>

 

 

- 로그인 페이지 만들기

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>로그인</title>
</head>
<body>
    <h1>로그인 페이지</h1>
    <p>ID: <input type = "text"/></p>
    <p>PW: <input type = "text"/></p>
    <button>로그인하기</button>
</body>
</html>

 

 


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

+ Recent posts