// 필터
// react.js -> redux사상(사용자 정의 구현 수준 필요), vue.js
// + typescript(바닐라스크립트 기반 위에 얹혀진 언어 -> 객체지향: 캡슐화, 상속, 추상화, 다형성)
// arr.filter(callback(element[, index[, array]])[, thisArg])
// 자바스크립트에서도 사용자정의 객체를 만들 수 있다 -> function
// 사용자 정의 함수를 정의할 때는 prototype을 사용한다
// prototype을 이용하면 자바스크립트처럼 사용자 정의 객체를 선언한 뒤 사용자 정의 함수를 정의할 수 있다
// prototype을 사용하여 함수를 정의한다는 건 사용자 정의 API를 만드는 것이다
// 우리가 정의한 객체 Counter는 표준이 아니다
// 또한 배포가 되지 않았다 -> 그러니까 구글에서 사용이 불가
function Counter() {
this.sum = 0;
this.count = 0;
}
Counter.prototype.add = function (array) {
//파라미터 array [3, 5, 15]
array.forEach(function (item) {
this.sum += item;
++this.count;
}, this); // this를 빼면 콜백실행x, 0찍힘(내가 정의한 것이니까 this 필요함)
};
const obj = new Counter();
obj.add([3, 5, 15]);
console.log(obj.sum); // 23
console.log(obj.count); // 3
// 자바스크립트에서는 함수를 만들 때에도 function을 사용하고
// 객체를 선언할 때도 function을 사용한다
// 객체가 정의하는 함수를 만들 때는 prototype 사용
// 바닐라 스크립트(순수한JS)에서는 전역변수 선언 없이도 생성자에서 초기화 가능하다
// 나도 API(객체와 함수 그리고 변수[let, const])를 만들 수 있다
function Sonata() {
this.wheelNum;
this.speed;
this.carName;
}
Sonata.prototype.stop = function (wheelNum) {
console.log("stop 호출 " + wheelNum);
};
const myCar = new Sonata();
myCar.stop(4); // stop 호출 4
// 구조분해 할당
// 배열일 때 []
const fruits = ["🍌", "🍓", "🍒"];
// 각각 넣는 방법
const fr1 = fruits[0];
const fr2 = fruits[1];
const fr3 = fruits[2];
console.log(fr1, fr2, fr3); // 🍌 🍓 🍒
// 구조 분해 할당
const [f1, f2, f3] = fruits;
console.log(f1, f2, f3); // 🍌 🍓 🍒
// 객체일 때 {}
const dept = {
deptno: 30,
dname: "개발부",
loc: "제주",
};
const { deptno, dname, loc } = dept;
console.log(deptno, dname, loc); // 30 개발부 제주
// 전개 구문을 사용하면 배열이나 문자열과 같이 반복 가능한 문자를
// 0개 이상의 인수 (함수로 호출할 경우) 또는 요소 (배열 리터럴의 경우)로 확장하여,
// 0개 이상의 키-값의 쌍으로 객체로 확장시킬 수 있다
// 배열[] fruits
const fruits = ["🍌", "🍓", "🍒"];
const fruits2 = ["🥝", "🍇", "🍉"];
const fruits3 = ["🍈", ...fruits2];
fruits3.forEach((fruit, index) => {
console.log(`${index}-${fruit}`); // 0-🍈 1-🥝 2-🍇 3-🍉
});
const fruits4 = [...fruits, ...fruits2];
fruits4.forEach(function (fruit, index) {
console.log(`${index}-${fruit}`); // 0-🍌 1-🍓 2-🍒 3-🥝 4-🍇 5-🍉
});
// 전개구문이 아닐 경우
const fruits5 = [fruits, fruits2];
fruits5.forEach(function (fruit, index) {
console.log(`${index}-${fruit}`); // 0-🍌,🍓,🍒 1-🥝,🍇,🍉
});
// 객체{} dept, emp
const dept = {
deptno: 30,
dname: "개발부",
loc: "제주",
};
const emp = {
empno: 7566,
ename: "SCOTT",
sal: 2500,
};
const deptNemp = { ...dept, ...emp };
console.log(deptNemp);
// {
// deptno: 30,
// dname: '개발부',
// loc: '제주',
// empno: 7566,
// ename: 'SCOTT',
// sal: 2500
// }
// emp에 추가되는 것이 아니라 새로운 객체 emp2가 만들어짐
const emp2 = { ...emp, empno: 7499, ename: "TIGER", sal: 3000 };
console.log(emp); // { empno: 7566, ename: 'SCOTT', sal: 2500 }
console.log(emp2); // { empno: 7499, ename: 'TIGER', sal: 3000 }
// 밖은 배열[], 안은 객체{}
let items = [
{ id: 1, name: "벤치프레스", count: 0 },
{ id: 2, name: "랫풀다운", count: 0 },
{ id: 3, name: "스쿼트", count: 0 },
];
// 배열 안에 새로운 객체가 생성됨
let items2 = [...items, { id: 4, name: "런지", count: 0 }];
console.log(items2);
// [
// { id: 1, name: '벤치프레스', count: 0 },
// { id: 2, name: '랫풀다운', count: 0 },
// { id: 3, name: '스쿼트', count: 0 },
// { id: 4, name: '런지', count: 0 }
// ]
items2 = [...items, { id: 5, name: "플랭크" }];
console.log(items2);
// [
// { id: 1, name: '벤치프레스', count: 0 },
// { id: 2, name: '랫풀다운', count: 0 },
// { id: 3, name: '스쿼트', count: 0 },
// { id: 5, name: '플랭크' }
// ]
// 위의 4, 5 전부 나오게하려면 ...item2로 바꿔주기
items2 = [...items2, { id: 5, name: "플랭크" }];
console.log(items2);
// [
// { id: 1, name: '벤치프레스', count: 0 },
// { id: 2, name: '랫풀다운', count: 0 },
// { id: 3, name: '스쿼트', count: 0 },
// { id: 5, name: '플랭크' },
// { id: 5, name: '플랭크' }
// ]
이벤트
무언가 일어난다(액션, 요청, request)
이벤트 종류
1. 사용자가 발생시키는 이벤트 (click, mouseover, mousemove, mousewheel, scrool 등)
2. 시스템이 발생시키는 이벤트 (load, error)
이벤트 연결 방법
1. 이벤트 핸들러 이용 DOM요소.onclick = () => {}
2. 내장 함수 이용 DOM요소.addEventListener('이벤트명', () => {})
DOM(문서 객체 모델) 구조
웹 페이지(HTML이나 XML 문서)의 콘텐츠 및 구조, 스타일 요소를 구조화시켜 표현하여 프로그래밍 언어가 해당 문서에 접근하여 읽고 조작할 수 있도록 API를 제공하는 일종의 인터페이스
웹 페이지( HTML 문서)를 계층적 구조와 정보로 표현하며, 이를 제어할 수 있는 프로퍼티와 메서드를 제공하는 트리 자료구조
아래와 같은 트리구조 → window - document - html(root태그) - head / body(화면을 그려줌) - a
서버(LiveServer-정적페이지만 처리, 프론트서버, 포트 5500) → 서버가 바라보는 물리적인 공간(dev_ui 폴더, 프로젝트가 관리되는 폴더)
사용자는 화면(모니터, 브라우저)을 통해 요청(request, url을 통해서) → 통신이 되어야 함, 이때 사용하는 프로토콜이 HTTP(stateless 비상태프로토콜, 상태유지안해줌) → 쿠키(클라이언트사이드 관리), 세션(서버사이드 관리)으로 비상태프로토콜 단점 보완
오라클 서버에 요청, 응답받아서 서버에서 처리(자바) → 톰캣(백 서버) 필요(jsp, sevlet 해석 엔진 탑재)
다운로드가 일어남(클라이언트 쪽에 다운로드하고 실행하기 위해 DOM Tree를 그리고 css를 통해 스타일주고 그것이 사용자 화면에 출력됨)
사용자가 입력, 수정, 삭제 요청 → restful API가 지원(get, post, put 등)
<!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>Document</title>
<script defer src="main.js"></script>
</head>
<body>
<a href="#">링크</a>
</body>
</html>
// 클래스 값이면 .붙이고 태그 이름이면 안붙임
const a = document.querySelector("a");
console.log(a);
console.dir(a); // dir로 출력하면 DOM 구조를 볼 수 있음
// 처음의 onclick은 처리x, 두번째만 실행됨
a.onclick = () => {
console.log("링크클릭-onclick"); // 출력x
};
a.onclick = () => {
console.log("링크클릭-onclick 다시"); // 이것만 출력됨
};
// 두 개의 이벤트리스너 모두 적용됨
a.addEventListener("click", () => {
console.log("링크 클릭-EventListener");
});
a.addEventListener("click", () => {
console.log("링크 클릭-EventListener 다시");
});
이벤트 버블링(Event Bubbling)
한 요소에 이벤트가 발생하면 이 요소에 할당된 핸들러가 동작하고, 이어서 부모 요소의 핸들러가 동작하고 최상단의 부모 요소를 만날 때까지 반복되면서 핸들러가 동작하는 현상
<!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>Document</title>
<link rel="stylesheet" href="./style.css" />
<script defer src="./main2.js"></script>
</head>
<body>
<main>
<section>
<article>
<nav>
<div></div>
</nav>
</article>
</section>
</main>
</body>
</html>
* {
margin: 0px;
padding: 0px;
box-sizing: border-box;
}
main {
width: 100%;
height: 100vh;
padding: 70px;
background-color: #ddd;
}
main section {
width: 100%;
height: 100%;
padding: 70px;
background-color: #bbb;
}
main section article {
width: 100%;
height: 100%;
padding: 70px;
background-color: #999;
}
main section article nav {
width: 100%;
height: 100%;
padding: 70px;
background-color: #777;
}
main section article nav div {
width: 100%;
height: 100%;
padding: 100px;
background-color: #555;
}
// 이벤트가 발생한 대상을 알아내기
/**
* a.curentTarget
* 이벤트문상 선택자 요소를 반환
*
* a.target
* 마우스 포인터 위치에 있는 요소 반환
*/
const main = document.querySelector("main");
main.addEventListener("click", (e) => {
console.log(e.currentTarget); // main만 뜸
console.log(e.target); // 선택한 부분이 뜸
});
// arrow function 안쓴 경우
main.addEventListener("click", function (e) {
console.log(e.currentTarget); // main만 뜸
console.log(e.target); // 선택한 부분이 뜸
});
<!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>Document</title>
<link rel="stylesheet" href="./style2.css" />
<script defer src="./main3.js"></script>
</head>
<body>
<a href="https://www.naver.com">링크</a>
<div class="box"></div>
</body>
</html>
a {
display: block;
width: 100px;
height: 50px;
background-color: aquamarine;
text-align: center;
margin: 10px 30px 50px 10px;
font: bold 16px/50px "arial";
}
.box {
width: 500px;
height: 500px;
background-color: bisque;
}
const a = document.querySelector("a");
a.addEventListener("click", (event) => {
event.preventDefault(); // 이벤트 호출 막음
});
// arrow 안썼을 경우
// a.addEventListener("click", function (event) {});
// 클래스 이름이기에 . 찍음
const box = document.querySelector(".box");
box.addEventListener("mousemove", (event) => {
// console.log(event);
console.log(`현재 x축 위치: ${event.pageX}, 현재 y축 위치: ${event.pageY}`);
});
window.addEventListener("mousewheel", (e) => {
console.log(e);
if (e.deltaY > 0) console.log("wheel down");
if (e.deltaY < 0) console.log("wheel up");
});
<!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>키보드이벤트</title>
</head>
<body>
<script>
window.addEventListener("keyup", (e) => {
// console.log(e.key);
if (e.key === "Enter") {
console.log("엔터 입력");
}
});
</script>
</body>
</html>
<!--
keydown: 특정 키를 누르고 있을 때
keyup: 특정 키를 누르다 손을 떼면
keypress: 키를 누르고 있을 때(alt, shift, ctrl 제외)
-->
<!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>Document</title>
<link rel="stylesheet" href="./menu.css" />
<script defer src="./menu.js"></script>
</head>
<body>
<!-- ul.list>(li>a{메뉴$})*5 자동완성 -->
<ul class="list">
<li><a href="#">메뉴1</a></li>
<li><a href="#">메뉴2</a></li>
<li><a href="#">메뉴3</a></li>
<li><a href="#">메뉴4</a></li>
<li><a href="#">메뉴5</a></li>
</ul>
</body>
</html>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
display: flex;
justify-self: center;
align-items: center;
}
ul {
display: flex;
justify-content: space-between;
}
li {
width: 150px;
height: 50px;
border: 1px solid greenyellow;
list-style: none;
}
li.on a {
background-color: teal;
color: white;
}
a {
width: 100%;
height: 100%;
text-decoration: none;
display: flex;
justify-content: center;
align-items: center;
}
const btns = document.querySelectorAll(".list li"); //array
let isFlag = 1;
for (let i = 0; i < btns.length; i++) {
// 인자가 1개이면 괄호 생략 가능
btns[i].addEventListener("click", (e) => {
// 0이 아닌 숫자는 전부 true
if (isFlag) {
btns[i].setAttribute("class", "on");
--isFlag;
} else {
btns[i].setAttribute("class", "off");
++isFlag;
}
console.log(e.target);
});
}
<!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>Document</title>
<script defer src="./main.js"></script>
</head>
<body>
<button>버튼</button>
</body>
</html>
if (true) {
console.log(this); // window객체
}
for (let i = 0; i < 5; i++) {
console.log(this); // window객체
}
setTimeout(() => {
console.log(this); // window객체
}, 2000);
const btn = document.querySelector("button");
btn.addEventListener("click", function (e) {
console.log(this); // button
});
btn.addEventListener("click", function (e) {
console.log(this);
}.bind(window)); //bind(window)하면 this는 window객체
btn.addEventListener("click", function (e) {
console.log(this);
}.bind('tomato')); // bind('tomato')하면 this는 String {'tomato'}
btn.addEventListener("click", (e) => {
console.log(this); // window객체
});
<!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>자유게시판</title>
</head>
<body>
<!-- 태그 안에는 태그를 보완하는 속성이 제공됨 -->
<table border="1" bordercolor="blue" width="800px" height="300px">
<thead>
<tr>
<!-- 태그와 자바스크립트가 함께할 수 없다 그러나 리액트에서는 가능함(XXX.jsx) -->
<!-- th는 td태그와 동일, 다만 가운데 정렬됨 -->
<th>글번호</th>
<th>제목</th>
<th>작성자</th>
<th>작성일</th>
<th>조회수</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">1</td>
<td>제목1</td>
<td>작성자1</td>
<td>2023-01-10</td>
<td>0</td>
</tr>
<tr>
<td>2</td>
<td>제목2</td>
<td>작성자2</td>
<td>2023-01-10</td>
<td>20</td>
</tr>
<tr>
<td>3</td>
<td>제목3</td>
<td>작성자3</td>
<td>2023-01-10</td>
<td>10</td>
</tr>
</tbody>
</table>
</body>
</html>
<!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>
a {
text-decoration: none;
}
</style>
</head>
<body>
<!-- 태그는 중첩해서 사용 가능함 -->
<!-- 크기는 %로 주는 것이 좋다(가변적이니까) -->
<table border="1" align="center" width="1000px">
<tr>
<td width="100%" height="50px">
<!-- top 시작 -->
<table border="1" width="100%" height="100%" bordercolor="green">
<tr>
<td>top 영역</td>
</tr>
</table>
<!-- top 끝 -->
</td>
</tr>
<tr>
<td>
<!-- body 시작 -->
<table>
<tr>
<!-- 메뉴 시작 -->
<td width="200px" height="400px">
<table border="1" width="100%" height="100%" bordercolor="blue">
<tr>
<td valign="top">
<table>
<tr>
<td>
<a href="#">소개</a>
</td>
</tr>
<tr>
<td>
<a href="#">로그인</a>
</td>
</tr>
<tr>
<td>
<a href="#">게시판</a>
</td>
</tr>
<tr>
<td>
<a href="https://www.google.com">구글</a>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
<!-- 메뉴 끝 -->
<!-- 메인 시작 -->
<td width="800px" height="400px">
<table border="1" width="100%" height="100%" bordercolor="red">
<tr>
<td>body 메인 영역</td>
</tr>
</table>
</td>
<!-- 메인 끝 -->
</tr>
</table>
<!-- body 끝 -->
</td>
</tr>
<tr>
<td width="1000px" height="30px">
<!-- bottom 시작 -->
<table border="1" width="100%" height="100%" bordercolor="yellow">
<tr>
<td>bottom 영역</td>
</tr>
</table>
<!-- bottom 끝 -->
</td>
</tr>
</table>
</body>
</html>
<!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>Document</title>
<style>
* {
box-sizing: border-box;
}
div {
width: 200px;
height: 200px;
position: absolute;
}
.d1 {
background-color: aquamarine;
/* margin: 20px; */
padding: 20px; /* border-box를 줘야 d2와 같은 위치, 크기임 */
position: absolute;
top: 30px;
left: 50px;
z-index: 1; /* position을 줘야 z-index 적용 가능 */
}
.d2 {
background-color: blueviolet;
position: relative;
z-index: 2; /* 숫자가 클수록 윗 레이어로 올라옴 */
}
</style>
</head>
<body>
<div class="d1">d1</div>
<div class="d2">d2</div>
</body>
</html>
<!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>디자인 - A안</title>
<script
src=""
crossorigin="anonymous"
></script>
<link rel="stylesheet" href="./index.css" />
</head>
<body>
<!-- 소개 및 탐색에 도움을 주는 콘텐츠틑 header에 담음 -->
<header>
<div class="container">
<h1>
<img src="../../images/home-solid.svg" width="50px" height="50px"></img></h1>
<nav class="main-navigation">
<a href="#">HTML</a>
<a href="#">CSS</a>
<a href="#">JAVASCRIPT</a>
<a href="#">REACT</a>
<a href="" class="btn">문의하기</a>
</nav>
<button class="more-btn"><i class="icon"></i></button>
<script>
const moreBtn = document.querySelector('.more-btn')
const mainNavigation = document.querySelector('.main-navigation')
moreBtn.addEventListener('click', ()=>{
alert("11");
moreBtn.classList.toggle('active');
mainNavigation.classList.toggle('active');
})
</script>
</div>
</header>
<!-- 문서<body>의 주요 콘텐츠를 main에 담음 -->
<main class="main_bg">
<div class="video-wrap">
<video src="../../images/forest.mp4" muted autoplay loop></video>
</div>
<div class="container">
<div class="text-wrap">
<h2>MVC패턴<br>계층형게시판</h2>
<h3>JAVA + Servlet + JSP + Spring</h3>
<h3>HTML5 + CSS3 + JavaScript + React</h3>
<p>Front-End에서 부터 Back-End까지<br>풀스택 개발자를 양성하는 강좌입니다</p>
<div class="btn-wrap">
<a href="#" class="btn">강좌 등록하기</a>
<a href="#" class="btn ghost-btn">가입하기</a>
</div>
</div>
</div>
</main>
</body>
</html>
/* *는 모든 요소를 의미 */
* {
box-sizing: border-box; /* 내부여백 외부여백을 포함한 크기로 계산 */
}
body {
background-color: black;
}
header {
top: 0;
left: 0;
width: 100%;
padding: 20px 0px;
position: absolute;
z-index: 2;
}
header h1 {
height: 40px;
margin: 0px;
float: left;
}
header h1 img {
display: block;
top: 10px;
background-color: white;
}
a {
font-size: 16px;
text-decoration: none;
}
.main-navigation {
float: right;
}
.main-navigation a {
color: white;
margin-left: 20px;
}
.btn {
display: inline-block;
font-weight: bold;
padding: 12px 20px;
background-color: darkcyan;
border-radius: 8px;
}
/* 가입, 등록버튼 */
.btn-wrap a {
background-color: darkcyan;
color: white;
}
/* 내용 처리 */
.main-bg {
position: relative;
width: 100%;
height: 100vh;
}
.video-wrap {
position: absolute;
left: 0;
width: 100%;
height: 100vh;
z-index: 1;
}
.video-wrap video {
width: 100%;
height: 100%;
object-fit: fill;
}
.container {
width: 100%;
max-width: 1480px;
padding: 0 20px;
margin: auto;
position: relative;
}
.text-wrap {
width: 520px;
height: 100vh;
padding: 240px 20px;
top: 0;
left: 0;
position: absolute;
z-index: 1;
}
.text-wrap h2 {
color: white;
font-size: 64px;
line-height: 1.25;
margin-bottom: 40px;
}
.text-wrap h3 {
color: white;
font-size: 24px;
line-height: 1.25;
margin-bottom: 20px;
}
.text-wrap p {
color: white;
font-size: 16px;
line-height: 1.8;
margin-bottom: 20px;
}
.more-btn {
display: none;
}
/* 반응형 웹 추가 */
@media screen and (max-width: 768px) {
.main-navigation {
position: fixed;
top: 0;
right: 0;
padding: 80px 20px;
width: 100%;
height: 100vh;
visibility: hidden;
opacity: 0;
}
.main-navigation.active {
opacity: 1;
visibility: visible;
transform: translateX(0);
transition: 0.3s;
}
.more-btn {
display: block;
position: absolute;
border-radius: 8px;
border: none;
right: 12px;
top: 8px;
width: 40px;
height: 40px;
background-color: transparent;
}
.more-btn.active .icon {
background: url(../../images/icon-close.svg);
background-size: contain;
}
.icon {
display: block;
width: 24px;
height: 24px;
background: url(../../images/icon-menu.svg);
background-size: contain;
}
}
'국비학원 > 수업기록' 카테고리의 다른 글
국비 지원 개발자 과정_Day45 (0) | 2023.01.31 |
---|---|
국비 지원 개발자 과정_Day44 (0) | 2023.01.30 |
국비 지원 개발자 과정_Day42 (0) | 2023.01.26 |
국비 지원 개발자 과정_Day41 (0) | 2023.01.25 |
국비 지원 개발자 과정_Day40 (0) | 2023.01.20 |
댓글