[유데미x스나이퍼팩토리] 10주 완성 프로젝트 캠프 14일차

🍊 JS

1. JavaScript

HTML, CSS, JS 작동 순서

  1. 사용자 웹 페이지 방문
  2. Web Brower 시작
  3. 웹 문서 읽기
  4. DOM 생성
  5. 페이지 로딩 완료

DOM(Document Object Model) 이란?

DOM은 넓은 의미로 웹 브라우저가 HTML 페이지를 인식하는 방식을 의미

문제 객체가 생성되는 방식👇🏻

  1. 정적으로 문서 객체 생성: 웹 브라우저가 HTML 페이지에 적혀 있는 태그를 읽으면 생성 2.동적으로 문서 객체 생성: 원래 HTML 페이지에 없던 문서객체를 JavaScript를 이용해서 생성

JavaSCript는 HTML 콘텐츠 변경 가능

<script>
  document.getElementById("demo").innerHTML = "My First JavaScript";
</script>

<head> or <body> JavaScript

<head>
<script>
  function myFunction() {
    document.getElementById("demo").innerHTML = "Paragraph changed.";
  }
</script>
</head>
<body>
  <p id="demo">A  Paragraph</p>
  <button type="button" onclick="myFunction()">Try it</button>
</body>

외부 자바스크립트 장점

  • HTML과 코드를 분리
  • HTML 및 JavaScript를 더 쉽게 읽고 유지 관리할 수 있음
  • 캐시된 JavaScript 파일은 페이지 로드 속도를 높임

innerHTML 사용

HTML요소에 액세스하기 위해 JavaScript는 document.getElementById(id)메소드를 사용

<script>
  document.getElementById("demo").innerHTML = 5 + 6;
</script>

window.alert() 사용

경고 상자를 사용하여 데이터 표시 가능

<script>
  window.alert(5 + 6);
</script>

JavaScript 변수와 상수

  • 변수(variable): 데이터 값을 넣을 수 있는 저장소, 바뀔 수 있는 값
  • 상수(constant): 값이 변하지 않는 변수
  키워드 재할당 재선언
변수(구JS) var O O
변수 let O X
상수 const X X

var는 잘 안쓰는 추세임.

JavaScript 함수 구문

  • JavaScript 함수는 function키워드, 이름, 괄호()로 정의
  • 함수 이름에는 문자, 숫자, 밑줄 및 달러 기호 포함 가능
  • 괄호는 쉼표로 구분된 매개변수 이름 포함 가능
  • 함수에 의해 실행될 코드는 중괄호 안에 배치
function name(parameter1, parameter2, parameter3) {
  // code to be executed
}

개체 정의

  • 객체 리터럴을 사용하여 JavaScript 객체를 정의
const person = {
  firstName: 'John',
  lastName: 'Doe',
  age: 50,
  eyeColor: 'blue'
};

this

  • this는 person 개체를 나타냄
  • this.firstName은 this의 firstName속성을 의미
  • this.firstName은 person의 firstName 속성을 의미
const person = {
  firstName: 'Park',
  lastName: 'Ji yun',
  id: 5566,
  fullName: function() {
    return this.firstName + " " + this.lastName;
  }
};

HTML 이벤트

HTML 이벤트는 브라우저가 수행하는 것 or 사용자가 수행하는 것

  1. HTML 웹 페이지 로드
  2. HTML 입력 필드 변경
  3. HTML 버튼 클릭

자바스크립트 이벤트 핸들러

이벤트 핸들러는 사용자 입력, 사용자 작업 및 브라우저 작업을 처리하고 확인하는 데 사용

  1. 페이지가 로드될 때마다 수행해야 하는 작업
  2. 페이지가 닫힐 때 해야 할 일
  3. 사용자가 버튼을 클릭할 때 수행해야 하는 작업
  4. 사용자가 데이터를 입력할 때 확인해야 하는 콘텐츠

문자열 메서드

let text1 = "asfd"
let length = text.length;

let text2 = "Apple, Banana, Kiwi"
let part = text.slice(7, 13);

let text3 = "Hello World!";
let text4 = text3.toUpperCase();
let text5 = text3.toLowerCase();

let text6 = "Hello";
let text7 = "World";
let text8 = text6.concat(" ", text7);

문자열 검색

let text = "Please locate where 'locate' occurs!";
let index = text.lastIndexOf("John");

let index2 = text.indexOf("locate", 15);

템플릿 리터럴

템플릿 리터럴은 따옴표(“”) 대신 백틱(``)을 사용하여 문자열을 정의

let text = `Hello World`;

let firstName = 'Park';
let lastName = 'Ji yun';

let name = `Welcome ${firstName}, ${lastName}`;

HTML 템플릿

let header = "Templates Literals";
let tage = ["template literals", "javascript", "es6"];

let html = `<h2>${header}</h2><ul>`
for(const x of tage) {
  html += `<li>${x}</li>`;
}

html += `</ul>`;

배열을 문자열로 변환

  • toString(): 배열 값을 문자열로 변환

HTML element

함수 설명
getElementById(id) 특정 ID 요소 조회
getElementsByName(name) name 요소 조회
getElementsByTagName(tagName) tag name 기준 요소 조회
getElementsByClassName(className) 특정 class 요소 조회
innerText 요소 안에 있는 글자르 가지고 옴
HTMLElement.innerHTML 태그 내 새로운 요소 객체나 내용을 저장 및 조회
HTMLInputElement.value input 태그의 value값을 저장 및 조회

DOM element

Dom element 함수 설명
생성 document.createElement const newTag = document.createElement(“div”);
조회 document.querySelector(첫번째 element 변환) document.querySelector(“input”);
조회 document.querySelectorAll(해당하는 모든 element 변환) document.querySelectorAll(“.children”);
삽입 appendChild parentElement.appendChild(newElement)
삭제 removeChild(자식 element 지정 삭제) parentElement.removeChild();
삭제 remove(해당 element 삭제) targetElement.remove();

함수(특정 코드를 하나의 명령으로 실행 할 수 있게 해주는 기능)

// 기본 함수 정의
function add(a,b) {
  return a+b;
}

// 화살표 함수 정의
const add = (a,b) => {
  return a+b;
}

화살표 함수를 쓰면 안되는 경우

// 객체 메소드
const cat = {
  name: 'ABC';
  callName () => console.log(this.name); 
}

cat.callName(); // undefined

// 생성자 함수
const Foo = () => {};
const foo = new Foo()
// TypeError: Foo is not a constructor

// addEventListener()의 콜백함수
button.addEventListener('click', function(){
  console.log(this);
  this.innerHTML = 'clicked';
});

객체 - 비구조화 할당

const ironMan = {
  name: '토니스타크',
  actor: '로버트 다우니 주니어',
  alias: '아이언맨'
}

const {name, actor, alias} = ironMan;
console.log(name);
console.log(actor);
console.log(alias);
const onChange = (event) => {
  const {target:{value}} = event;
  console.log(value);
}
//console.log(value) == console.log(event.target.value)

2. 과제 - (구)세이프홈즈 반응형 퍼블리싱

CSS

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: 'Spoqa Han Sans Neo', 'sans-serif';
}

a {
  text-decoration: none;
}

li {
  list-style: none;
}

main {
  width: 100%;
}

/* Header */
header {
  width: 60%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 0 auto;
  height: 70px;
}

header img {
  width: 195px;
  height: 32px;
}

header .menu a {
  display: inline-block;
  width: 90px;
  height: 30px;
  text-align: center;
  line-height: 30px;
  font-size: 12px;
  border-radius: 4px;
}

header .menu a.btn-white {
  background: #fff;
  color: #000;
}

header .menu a.btn-green {
  background: #0E7159;
  color: #fff;
}


/* Visual */
.visual {
  width: 100%;
  position: relative;
}

.visual img {
  width: 100%;
  filter: brightness(20%);
}

.visual div.text-box {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  width: 100%;
}

.visual h1 {
  font-size: 60px;
  color: #fff;
}

.visual a {
  margin-top: 50px;
  font-size: 24px;
  color: #fff;
  display: flex;
  justify-content: center;
  align-items: center;
}


/* Article Services-area */
article {
  width: 1100px;
  margin: 125px auto;
}

article .title {
  margin-bottom: 50px;
  text-align: center;
  font-size: 40px;
  color: #0E7159;
}

article .services-area {
  display: flex;
  justify-content: space-between;
  text-align: center;
}

article .services-area h3,
article .services-area p {
  text-align: left;
  padding: 20px 35px 0;
}

article a {
  display: block;
  text-align: center;
  margin-top: 50px;
  font-weight: bold;
  font-size: 18px;
  color: #0E7159;
  display: flex;
  justify-content: center;
  align-items: center;
}


/* Article Check-list */
article .check-list {
  display: flex;
  gap: 20px 2%;
  flex-wrap: wrap;
}

article .check-list div {
  width: 32%;
}

article .check-list strong {
  color: #0E7159;
  font-size: 21px;
}

article .check-list h4 {
  font-size: 21px;
  margin: 9px 0 16px 0;
}


article .check-list p {
  font-size: 16px;
}


/* Article Phone */
article .phone .phone-list {
  width: 100%;
  display: flex;
  justify-content: space-between;
}

article .phone .phone-list div {
  width: 50%;
  padding-bottom: 50px;
}

article .phone .phone-list .phone-img img, article .phone .img-r img {
  border-radius: 50px;
  box-shadow: 10px 5px 5px rgba(0, 0, 0, 0.5);
}

article .phone .img-r {
  text-align: right;
}

article .phone strong {
  color: #0E7159;
  font-size: 24px;
}

article .phone h4 {
  color: #333D4B;
  margin: 20px 0 30px 0;
  font-size: 48px;
}

article .phone p {
  color: #6B7684;
  margin-bottom: 20px;
  font-size: 24px;
}

article .phone .msg {
  margin: 10px 0;
}


/* Article Price */
article .price {
  display: flex;
  justify-content: space-between;
}

article .price div {
  background: #F2F3F4;
  border-radius: 20px;
  padding: 30px 24px;
  margin-left: 20px;
  width: 340px;
}

article .price div h4 {
  font-size: 24px;
  margin-bottom: 30px;
}

article .price div p {
  color: #6B7684;
  font-size: 16px;
  margin-bottom: 30px;
}

article .price div strong {
  color: #0E7159;
  font-size: 32px;
}

article .price div .btn {
  background: #0E7159;
  color: #fff;
  border-radius: 8px;
  height: 64px;
}


/* Review */

.review {
  width: auto;
  height: 500px;
  position: relative;
  overflow: hidden;
  transition: height .4s;
}

.review .title {
  font-size: 48px;
  color: #0E7159;
  text-align: center;
}

.review.hide {
  height: 0;
}

.review .swiper-container {
  /* 819px 슬라이드 3개와 그 사이 여백 50px씩 =  */
  width: calc(750px * 3 + 100px);
  position: absolute;
  top: 150px;
  left: 50%;
  margin-left: calc((750px * 3 + 100px) / -2);
}

.review .swiper-slide {
  position: relative;
  opacity: .5;
  transition: opacity 1s;
  background-color: #F2F3F4;
  border-radius: 20px;
  padding: 50px;
}

.review .swiper-slide .info {
  display: flex;
  padding-bottom: 20px;
}

.review .swiper-slide .info p {
  padding-left: 20px;
}

.review .swiper-slide-active {
  opacity: 1;
}

.review a {
  display: block;
  text-align: center;
  font-weight: bold;
  font-size: 18px;
  color: #0E7159;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
  top: 400px;
}

/* Bg-full */
.bg-full {
  width: 100%;
  height: 608px;
  background: #0E7159;
  text-align: center;
  display: flex;
  margin: 180px auto 0;
  justify-content: center;
}

.bg-full div h1 {
  margin-top: 180px;
  margin-bottom: 75px;
  font-weight: bold;
  font-size: 60px;
  color: #fff;
}

.bg-full div .btn-white {
  display: inline-block;
  width: 170px;
  height: 60px;
  line-height: 60px;
  background: #fff;
  font-weight: bold;
  font-size: 16px;
  color: #0E7159;
  border-radius: 10px;
}


/* Footer */
footer {
  height: 159px;
}

footer div {
  width: 60%;
  margin: 0 auto;
  padding: 25px 0;
}

footer div p {
  margin-bottom: 15px;
  font-size: 16px;
  font-weight: bold;
  color: #333D4B;
}

footer div small {
  line-height: 24px;
  font-size: 14px;
  color: #6B7684;
}

footer div small a {
  color: #6B7684;
}



@media screen and (max-width:1024px) {
  header .menu a.btn-white  {
    display: none;
  }

  .visual h1 {
    font-size: 48px;
  }

  .visual a { display: none; }

  article {
    width: 100%;
  }

  article .title { font-size: 32px; }

  article .services-area {
    flex-wrap: wrap;
  }

  article .services-area div {
    width: 50%;
    padding: 20px 75px 0;
  }

  article .check-list {
    justify-content: space-between;
  }

  article .check-list div {
    width: 48%;
    padding: 0 20px;
  }

  article .phone .phone-list {
    flex-wrap: wrap;
    text-align: center;
  }

  article .phone .phone-list div {
    width: 100%;
    text-align: center;
  }

  article .phone .phone-list .phone-text {
    width: 70%;
    margin: 0 auto;
  }

  article .phone .phone-list .phone-img {
    order:2;
  }

  article .phone .phone-list .phone-img img, article .phone .img-r img {
    box-shadow: none;
  }

  article .phone .msg {
    display: none;
  }

  article .price {
    flex-wrap: wrap;
    margin: 0 auto;
    width: 95%;
  }

  article .price div {
    margin-bottom: 30px;
  }

  .screen-none {
    display: none;
  }

  .review .title {
    font-size: 34px;
  }

  
}


@media screen and (max-width:768px) {

  header {
    width: 90%;
  }

  .visual h1 {
    font-size: 36px;
  }
  article {
    width: 100%;
  }
  
  article .services-area div {
    padding: 20px 20px 0;
  }

  article .services-area div img {
    width: 100%;
  }

  article .services-area h3, article .services-area p {
    padding: 20px 0;
  }

  article .check-list div {
    padding: 0 40px;
  }

  article .price div {
    margin-left: 0;
  }

  .review .swiper-container {
    width: calc(650px * 3 + 50px);
    position: absolute;
    top: 150px;
    left: 50%;
    margin-left: calc((650px * 3 + 50px) / -2);
  }

  .bg-full div h1 {
    font-size: 48px;
  }
}

@media screen and (max-width:480px) {
  .visual h1 {
    font-size: 24px;
  }

  article .title {
    font-size: 21px;
  }

  article .services-area div {
    width: 82%;
    margin: 0 auto;
  }

  article .check-list div {
    width: 82%;
    margin: 0 auto;
  }

  article .phone .phone-list .phone-text {
    width: 100%;
  }

  article .phone h4{
    font-size: 36px;
  }

  article .price {
    justify-content: center;
  }

  .review .title {
    font-size: 24px;
  }

  .review .swiper-container {
    width: calc(450px * 3 + 50px);
    position: absolute;
    top: 80px;
    left: 50%;
    margin-left: calc((450px * 3 + 50px) / -2);
}
  
  .review a {
    top: 400px;
  }

  .bg-full div h1 {
    font-size: 36px;
  }
}

JS

new Swiper('.review .swiper-container', {
    slidesPerView: 3,       // 한번에 보여줄 슬라이드 개수
    spaceBetween: 50,     // 슬라이드 사이 여백
    centeredSlides: true, // 1번 슬라이드가 가운데 보이기
    autoplay: { delay: 4000 },
    loop: true,
  });

결과

1920px

1920

1024px

1024

768px

768

480px

480

3. 회고

금요일에는 JS에 대해 배우면서 복습하는 시간을 가졌다. slide를 직접 만들어본건 너무 오랜만이여서 헤매였다..
왜 합쳐지는게 안됄까 하고 있었는데 아무 생각없이 부모에 max-width: 800px;을 넣어줬더니 완성ㅠ 나는 멍청이였던 걸까🥲
내가 생각보다 JS를 못하는거 같아서 충격적인 하루였다.. 느낀게 많으니 더 열심히 공부해야겠다 생각이 듬!!
이번 과제는 저번에 html 한 걸 이어서 css + js 로 반응형까지 하는 게 과제인데 html을 만들면서 css도 어느정도 만들어 놨더니 그렇게 시간이 오래 걸리진 않았다.
덕분에 어제는 쉬는 시간을 가질 수 있었어 좋았음 하핳😊😊
대략적으로 하기는 했는데 잘 했는지는 모르겠다 반응형 막해버렸ㅇ.. 그래도 좀 비슷하지 않ㄴ..? 아니면 말고욤..
열심히 하긴 했지만 내 마음엔 약간 불만족! 암튼튼 담주 React 수업이 기대된당



본 후기는 유데미-스나이퍼팩토리 10주 완성 프로젝트캠프 학습 일지 후기로 작성 되었습니다.

#프로젝트캠프 #프로젝트캠프후기 #유데미 #스나이퍼팩토리 #웅진씽크빅 #인사이드아웃 #IT개발캠프 #개발자부트캠프 #리액트 #react #부트캠프 #리액트캠프

Leave a comment