백엔드 개발툴(Bootstrap, Tailwind)
프론트 개발툴(scss,sass / css 심화 / postCss
https://www.w3schools.com/bootstrap5/index.php
(부트 스트랩 사이트)
https://getbootstrap.com/docs/5.0/getting-started/introduction/
(부트 스트랩 공식 사이트)
https://getbootstrap.kr/docs/5.0
(부트 스트랩 한글 공식 사이트)
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css"
rel="stylesheet"
/>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body></body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css"
rel="stylesheet"
/>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body>
<div class="container-fluid" style="background-color: red">
<h1>My First Bootstrap Page</h1>
<p>This part is inside a .container class.</p>
<p>The .container class provides a responsive fixed width container.</p>
<p>
Resize the browser window to see that the container width will change at
different breakpoints.
</p>
</div>
</body>
</html>

<!DOCTYPE html>
<html lang="en">
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css"
rel="stylesheet"
/>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body>
<nav class="navbar navbar-expand-sm navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="javascript:void(0)">Logo</a>
<button
class="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#mynavbar"
>
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="mynavbar">
<ul class="navbar-nav me-auto">
<li class="nav-item">
<a class="nav-link" href="javascript:void(0)">Link</a>
</li>
<li class="nav-item">
<a class="nav-link" href="javascript:void(0)">Link</a>
</li>
<li class="nav-item">
<a class="nav-link" href="javascript:void(0)">Link</a>
</li>
</ul>
<form class="d-flex">
<input class="form-control me-2" type="text" placeholder="Search" />
<button class="btn btn-primary" type="button">Search</button>
</form>
</div>
</div>
</nav>
<div class="container">
<div
id="cardGroup"
class="card-group row-cols-1 row-cols-md-2 row-cols-lg-3 row-cols-xl-4 row-cols-xxl-5"
></div>
<!--창크기에 따라 카드가 1,2,3,4,5열씩 나열-->
</div>
</body>
<script>
// const cards = [0, 0, 0, 0, 0, 0, 0];
const cards = new Array(7).fill(0);
const cardGroup = document.getElementById("cardGroup");
cards.forEach((value, index) => {
//col m-3 -> 카드 사이 넓이 3 으로 고정
cardGroup.insertAdjacentHTML(
"beforeend",
`<div class="col ">
<div class="card m-3">
<img
src="https://w.namu.la/s/dc42bb0527e08b0d65f370f3a8ad1c471ccbd90a5f01b85343e6471c7f4100486b9be8514d380c33651c70fdc1c7da610cd2effaa9696b1226d29082faa22131e41b8bd7a75491abd0819c4789a517c0f34511a2defbefe71296ccb382a08b337ae0c3be5daae0f3da9ad3fb8934625c"
class="card-img-top"
alt="..."
/>
<div class="card-body">
<h5 class="card-title">Card title ${index}</h5>
<p class="card-text">
This is a wider card with supporting text below as a natural
lead-in to additional content. This content is a little bit
longer.
</p>
<p class="card-text">
<small class="text-muted">Last updated 3 mins ago</small>
</p>
</div>
</div>
</div>`
);
});
</script>
</html>

<script>
//break, continue
//while, for문 안에서 break 가 선언되면 반복문이 종료된다.
//array.some -> 예를들어 100개의 요소 중에서 하나라도 조건에 맞으면
//멈추는게 효율적이다.
//만약에 2번째에서 조건이 맞으면 break
const breakFunc = () => {
let count = 0;
while (count < 100) {
console.log(`${count} break테스트`);
if (count > 10) {
break;
}
count = count + 1;
}
console.log("break 빠져나옴");
};
//breakFunc()
//while, for 문에서 continue 를 선언하면 다음 반복으로 넘어간다
//array.filter -> 원래 있던 배열에서 필터링할때
//[1,2,3] 에서 [] 빈 배열로 push 할때
//조건이 홀수인 것만 필터링.
//짝수일 경우는 continue, 홀수일 경우 push
const continueFunc = () => {
let count = 0;
while (count < 100) {
count = count + 1;
if (count == 98) {
continue;
}
console.log(`${count} continue테스트`);
}
console.log("continue 빠져나옴");
};
continueFunc();
//return
//함수안에서 return 이 선언되면 함수가 종료된다.
//계산이 완료되어 더 이상 함수 내의 코드를 실행할 필요가 없을때
//매개변수가 "" 빈 스트링이면 0을 리턴하고
//"가나다" 빈 스트림이 아니면 ["가","나","다"]로 만들어주세요.
const strFunc = (str) => {
if (str.length == 0) {
return 0;
}
return str.split("");
};
console.log(strFunc(""));
console.log(strFunc("가나다"));
const returnFunc = () => {
let count = 0;
while (count < 100) {
console.log(`${count} return테스트`);
if (count > 10) {
return;
}
count = count + 1;
}
console.log("return 빠져나옴");
};
//returnFunc();
</script>
- 프로미스는 자바스크립트 비동기 처리에 사용되는 객체입니다. 여기서 자바스크립트의 비동기 처리란 ‘특정 코드의 실행이 완료될 때까지 기다리지 않고 다음 코드를 먼저 수행하는 자바스크립트의 특성’을 의미한다.
$.get('url 주소/products/1', function(response) {
// ...
});
위 API가 실행되면 서버에다가 ‘데이터 하나 보내주세요’ 라는 요청을 보내죠. 그런데 여기서 데이터를 받아오기도 전에 마치 데이터를 다 받아온 것 마냥 화면에 데이터를 표시하려고 하면 오류가 발생하거나 빈 화면이 뜹니다. 이와 같은 문제점을 해결하기 위한 방법 중 하나가 프로미스입니다.
프로미스를 사용할 때 알아야 하는 가장 기본적인 개념이 바로 프로미스의 상태(states)입니다. 여기서 말하는 상태란 프로미스의 처리 과정을 의미합니다. new Promise()로 프로미스를 생성하고 종료될 때까지 3가지 상태를 갖는다.
- Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태
- Fulfilled(이행) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태
- Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태
<script>
//setTimeout 시한폭탄
// console.log(Date.now());
// setTimeout(() => {
// console.log("안녕");
// console.log(Date.now());
// }, 2000);
//setInterval() 자동반복
//setInterval();
// const myInter = setInterval(() => {
// console.log(Date.now());
// }, 2000);
// setTimeout(() => {
// clearInterval(myInter);
// }, 10000);
//promise
//마법택배상자
//값이 들어오기 전까지 안열림
//값이 들어몬 열 수 있음.
//보통 통신시 사용, 또는 입출력
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("택배도착");
}, 2000);
});
promise
.then((response) => {
console.log(response);
return "택배개봉";
})
.catch((error) => {
console.log(error);
})
.finally(() => {
//통신이 성공하든 실패하든 작동
//reject("택배분실");
console.log("finally");
})
.then((response) => {
console.log(response);
});
</script>
async와 await라는 특별한 문법을 사용하면 프라미스를 좀 더 편하게 사용할 수 있다. async, await는 놀라울 정도로 이해하기 쉽고 사용법도 어렵지 않다.
async 키워드부터 알아봅시다. async는 function 앞에 위치한다.
async function f() {
return 1;
}
function 앞에 async를 붙이면 해당 함수는 항상 프라미스를 반환한다. 프라미스가 아닌 값을 반환하더라도 이행 상태의 프라미스(resolved promise)로 값을 감싸 이행된 프라미스가 반환되도록 한다.
아래 예시의 함수를 호출하면 result가 1인 이행 프라미스가 반환된다.
async function f() {
return 1;
}
f().then(alert); // 1
명시적으로 프라미스를 반환하는 것도 가능한데, 결과는 동일하다.
async function f() {
return Promise.resolve(1);
}
f().then(alert); // 1
async가 붙은 함수는 반드시 프라미스를 반환하고, 프라미스가 아닌 것은 프라미스로 감싸 반환한다. 그런데 async가 제공하는 기능은 이뿐만이 아니다. 또 다른 키워드 await는 async 함수 안에서만 동작한다.
await 문법은 다음과 같다.
// await는 async 함수 안에서만 동작합니다.
let value = await promise;
자바스크립트는 await 키워드를 만나면 프라미스가 처리될 때까지 기다린다. 결과는 그 이후 반환된다.
1초 후 이행되는 프라미스를 예시로 사용하여 await가 어떻게 동작하는지 살펴보자.
async function f() {
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("완료!"), 1000)
});
let result = await promise; // 프라미스가 이행될 때까지 기다림 (*)
alert(result); // "완료!"
}
f();
함수를 호출하고, 함수 본문이 실행되는 도중에 ( * ) 로 표시한 줄에서 실행이 잠시 '중단’되었다가 프라미스가 처리되면 실행이 재개된다. 이때 프라미스 객체의 result 값이 변수 result에 할당된다. 따라서 위 예시를 실행하면 1초 뒤에 '완료!'가 출력된다.
await는 말 그대로 프라미스가 처리될 때까지 함수 실행을 기다리게 만든다. 프라미스가 처리되면 그 결과와 함께 실행이 재개되죠. 프라미스가 처리되길 기다리는 동안엔 엔진이 다른 일(다른 스크립트를 실행, 이벤트 처리 등)을 할 수 있기 때문에, CPU 리소스가 낭비되지 않는다.
await는 promise.then보다 좀 더 세련되게 프라미스의 result 값을 얻을 수 있도록 해주는 문법이다. promise.then보다 가독성 좋고 쓰기도 쉽다.
<script>
//async await
//1. async 없는 함수에서 promise
const noAsyncFunc = () => {
const pro1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("pro1 완료");
}, 2000);
});
const pro2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("pro2 완료");
}, 1000);
});
//then 안의 함수를 콜백 함수라고 한다.
pro1.then((response) => {
console.log(response);
});
pro2.then((response) => {
console.log(response);
});
};
//noAsyncFunc();
//2. async 있는 함수에서 promise
const AsyncFunc = async () => {
const pro1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("pro1 완료");
}, 2000);
});
const pro2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("pro2 완료");
}, 1000);
});
//await 사용시
//promise 결과는 순서대로 작동된다.
const res1 = await pro1; //2초 뒤에 풀림
console.log(res1);
const res2 = await pro2; //이미 풀려있음
console.log(res2);
};
//async 함수는 promise를 리턴한다
AsyncFunc();
</script>
- 함수 + 함수를 둘러싼 렉시컬 환경(Lexical environnment)
외부 함수 호출이 종료된 후에도 함수의 내부변수에 대한 메모리할당을 유지하지만 직접 볼 수 없게 은닉화 하기 때문이다.
<script>
//클로저 closure
//var, let, const
//-> 스코프가 함수를 넘지 못한다
//함수를 객체처럼 사용할 때 클로저 이용
/* class Count {
constructor() {
this.Count = 0;
}
increase() {
//this.count++;
this.count = this.count + 1;
return this.count;
}
}
const count = new Count();
console.log(count.increase());
console.log(count.increase());
console.log(count.increase()); */
const makeCounter = () => {
//원래 함수가 끝나면 없어져야되는 count
let count = 0;
return () => {
//함수를 리턴하면 부모 함수의 변수를 가지고 있을 경우
//부모 함수의 변수가 어딘가에 살아남는다.
count = count + 1;
return count;
};
};
const counter = makeCounter();
console.log(counter());
console.log(counter());
console.log(counter());
</script>

배포할 파일의 폴더를 생성 후 index.html 파일로 저장한다.
이후 깃허브에 새로운 파일 생성 후 깃허브 명령어를 통해 파일을 깃에 저장한다.

깃허브에 settings 를 클릭

Pages -> Branch메뉴에 master 클릭후 save

몇분 정도 기다린 후 페이지를 새로고침하면 Visit site 라는 버튼이 생겨 배포한 파일의 사이트를 방문할 수 있다.
