JavaScript 사용

천문성·2023년 2월 4일
0

<script> 안에 대충 적은 코드는 페이지 로드시 1회 실행됨

자주 중요하게 말하는 내용!

지금 "유저가 셔츠선택하면 form-hide 제거해주세요" 라고 코드짰는데

이 코드는 <script> 안에 적었기 때문에 그냥 페이지 로드시 1회 실행되고 다시는 실행되지 않습니다.

그래서 저 코드를 <select> 조작할 때 마다 실행한다면 의도대로 잘 동작하게 됨

<h1 id="hello">안녕하세요</h1>

<script>
  document.getElementById('hello').innerHTML = '안녕';
</script>

document -> 문서인데 여기선 html 웹문서

마침표 -> ~의

getElementById('hello') -> 아이디가 'hello'인 html 요소 (일명 element) 를 찾아달라

innerHTML -> 그냥 내부 HTML이라는 뜻

= -> 등호는 프로그래밍에서 오른쪽에 있는걸 왼쪽에 대입하라는 뜻

'바보' -> 바보라는 문자 (큰따옴표, 작은따옴표안에 담겨있으면 항상 문자)

.getElementById()는 셀렉터라고 부름 / html 요소를 찾기 위해 사용

.innerHTML / .style / .color 이렇게 점찍는데 괄호없는건 메소드(또는 함수) 라고 부름 / html 요소의 어떤 속성을 변경할지 결정하기 위해 사용

1. HTML CSS 로 미리 UI 디자인을 해놓고 필요하면 사용하고 평소엔 숨김

2. 버튼을 누르거나할 경우 UI를 보여달라고 자바스크립트 코드작성

<button id = "close" 
onclick="document.getElementById('alert').style.display='none'">X</button>

onclick에 자바스크립트 코드 작성

function()

함수는 길고 더러운 코드 한 단어로 축약하고 싶을 때 쓰는 문법

즉, 특정 기능을 다음에도 쓰기 위해 모듈화해놓는 문법

function alertOpen(){
    document.getElementById('alert').style.display = 'block';
  }

파라미터를 통해 비슷한 함수들을 하나로 구현가능

파라미터는 자유롭게 작명 가능, 2개이상 사용가능(콤마로 구분)

function alertOpenOrClose(mm){
  document.getElementById('alert').style.display = mm;
}

alertOpenOrClose('none'); //이거 실행하면 알림창닫힘
alertOpenOrClose('block');  //얘는 열림

버튼클릭시 텍스트변경

<div class="alertBox" id="alert">
    <p id="message">알림창</p>
    <button id = "close">닫기</button>
  </div>
  <button id = "id" onclick="alertChange('아이디를 입력하세요')">버튼1</button>
  <button id = "pass" onclick="alertChange('패스워드를 입력하세요')">버튼2</button>
  
  <script>

    document.getElementById('close').addEventListener('click', function(){
      document.getElementById('alert').style.display='none';
    });

    function alertChange(mm){
      document.getElementById('message').innerHTML= mm;
      document.getElementById('alert').style.display='block';
    }

클래스명으로 셀렉터를 통해 찾을 수 있다

📌 형식:getElementsByClassName('클래스명')[순서]

[0],[1] 순서는 넣어서 몇번째 요소를 바꿀지 꼭 붙여줘야함 - 위에서부터 순서

<p class="title1"> 테스트1 </p>
<p class="title1"> 테스트2 </p>
<script>
  document.getElementsByClassName('title1')[0].innerHTML = '안녕';
</script>

📌 이벤트리스너

이벤트 종류 : click / mouseover / scroll 등등

document.getElementById('아이디명').addEventListener('click', function(){
    //실행할 코드 
});

위의 코드인 addEventListerner에는 두개의 파라미터 자리가 존재한다.

두번째 파라미터로 함수가 들어가는데 이를 콜백함수라고 함 - 함수 파라미터자리에 들어가는 함수

navbar만들기 → bootstrap을 통해 사용(버튼,탭,메뉴 등을 복붙식으로 개발가능)

display 표현하는 다른방법 - class 탈부착

평소에 .list-group 붙은 요소는 숨겨놓도록 하고 거기에 show라는 클래스를 부착하면 보여주는 식으로 개발

⇒ class 부착하면 display에 다른 스타일 적용 가능

.list-group {
  display : none
}
.show {
  display : block
}

버튼 클릭 시 클래스명 추가 → 개발시 용이함

document.getElementsByClassName('navbar-toggler')[0].addEventListener('click', function(){
  document.getElementsByClassName('list-group')[0].classList.add('show');
}); //add를 toggle로 바꾸면 토글도 가능

📌 querySelector

getElementsByClassName 등과 다른방식으로 html요소를 찾아주는 셀렉터

querySelector() 안에는 css 셀렉터 문법을 사용가능

(css에서 마침표는 class라는 뜻이고 #은 id라는 뜻임)

다만 querySelector() 는 맨 위의 한개 요소만 선택해줌

<div class="test1">안녕하세요</div>
<div id="test2">안녕하세요</div>

<script>
  document.querySelector('.test1').innerHTML = '안녕';
  document.querySelector('#test2').innerHTML = '안녕';
</script>

querySelectorAll

test1이라는 클래스가 중복으로 여러개 있는데

X번째 요소를 선택하고 싶은 경우엔 querySelectorAll()을 사용

querySelectorAll() 은 해당하는걸 다 찾아서 [] 안에 담아줍니다.

그래서 [숫자] 를 뒤에 붙여서 원하는 위치에 있는 요소 찾아쓰면 됩니다.

<div class="test1">안녕하세요</div>
<div class="test1">안녕하세요</div>

<script>
  document.querySelectorAll('.test1')[1].innerHTML = '안녕';
</script>

자바스크립트 특징인데 코드가 매우 길고 더러움

그게 불만이면 html 조작을 쉽게 바꿔주는 라이브러리들을 사용가능

React, Vue, jQuery 이런 것들이 전부 html 조작 쉽게 바꿔주는 라이브러리들

React와 Vue는 자바스크립트 어느정도 문법을 알아야 사용가능

우선 jQuery를 사용

jQuery 설치 : jQuery cdn 검색 후 태그복붙

<p class="hello">안녕</p>
<p class="hello">안녕</p>
<p class="hello">안녕</p>
<button class="test-btn">버튼</button>

<script>
  $('.hello').html('바보'); //내용변경
	$('.hello').css('color', 'red'); //css스타일 변경
	$('.hello').addClass('클래스명'); //클래스부착
  $('.hello').removeClass('클래스명'); //클래스제거
  $('.hello').toggleClass('클래스명'); //클래스 토글
	$('.test-btn').on('click', function(){
    $('.hello').fadeOut();
	});
</script>

$ = querySelector와 동일

주의사항 : html셀렉터로 찾으면 html함수들을 붙이고 jQuery셀렉터로 찾으면 jQuery함수들을 붙여야함

$()셀렉터는 querySelectorAll처럼 여러개가 있으면 모두 찾아줌 →한번에 변경가능

addEventListener는 on으로 사용

📌 UI 애니메이션 만드는 법

[ one-way 일방향 애니메이션 만드는 법 ]

  1. 시작스타일 만들고 (class로)

  2. 최종스타일 만들고 (class로)

  3. 원할 때 최종스타일로 변하라고 JS 코드작성

(클래스 부착 →on.(’click’, function(){$(.클래스명).addClass’추가할 클래스명’)

  1. 시작스타일에 transition 추가
.black-bg {
  (생략)
  visibility : hidden;
  opacity : 0;
	transition: all 1s;
}
.show-modal {
  visibility : visible;
  opacity : 1;
}
  • display : none을 주면 애니메이션이 잘 동작하지 않기 때문에

그거랑 비슷한 역할을 할 수 있는 visibility : hidden 을 사용

  • opacity는 투명도 조절할 수 있는 속성

0이면 투명 1이면 불투명 0.5면 반투명

transition은 스타일이 변할 때 천천히 변경하라는 뜻

지금 class 탈부착시 opacity가 변하는데 그걸 천천히 1초에 걸쳐 변경

📌<form>만들기

폼 구조도 부트스트랩에서 복붙 가능

일반적인 if문 사용가능

로그인버튼클릭시 아이디입력창이 비어있으면 alert창 띄우기

$('#send').on('click', function(){
        if(document.getElementById('loginId').value == ''){
          alert('아이디를 입력하세요.');
        }
      })
$('form').on('submit', function(){
  if (document.getElementById('loginId').value == '') {
    alert('아이디 입력하쇼');
  }
});

버튼에 click 이벤트리스너 달아도 되고 <form>태그 찾아서 submit 이벤트리스너 달아도 똑같이 동작합니다. 왜냐면 폼전송이 되면 <form> 태그에서 submit 이벤트도 발생하기때문

원하는 html을 태그명으로 찾고 싶으면 마침표나 # 없이 $('태그명')만 적으면 찾을 수 있음

  • jQuery로 짧게 쓰려면 $('#loginId').val() == '' 쓰면 됩니다.

📌 input이벤트와 change이벤트

document.getElementById('email').addEventListener('input', function(){
  console.log('안녕')
});

input에 입력된 값이 변경될때마다 이벤트 발생

document.getElementById('email').addEventListener('change', function(){
  console.log('안녕')
});

input에 값을 입력하고 커서를 다른데 찍으면 안녕 출력

⇒input값이 변경되었을 때 코드실행하고싶으면 input,change 이벤트리스너활용

📌 다크모드 버튼 구현

-까매지는 class를 css파일에 미리 만들어놓고 버튼 누르면 부착하는 방식

var count = 0;

$('.badge').on('click', function(){
  count += 1;
  if (count % 2 == 1) {
    $('.badge').html('Light');
  } else {
    $('.badge').html('Dark')
  }
});

📌📌 변수

var - 재선언 ㅇ / 재할당 ㅇ / 범위 : 함수

let - 재선언 x / 재할당 ㅇ / 범위 : 중괄호

const - 재선언 x / 재할당 x / 범위 : 중괄호

setTimeout(함수(), 밀리초) : x초 후에 코드를 실행해줌

setTimeout(function(){ 
  console.log('안녕')
}, 1000);

setTimeout(함수, 1000); //이런식으로 콜백함수자리에 함수사용 가능 

function 함수(){ 
  console.log('안녕')
}
'문자'.includes('찾을단어')

찾을단어가 있으면 true 없으면 false

하지만

  • 한글이 들어있냐
  • 영어가 들어있냐
  • A로 끝나냐
  • 마침표 다음에 영어가 있냐

이런건 includes() 만으로 검사하기 어렵다

정규표현식

/abc/.test('abcdef') ->'abcdef'에 abc가 있는지 검사
/[a-z]/.test('aefg')  //true 소문자중 하나가 있는지
/[-]/.test('다라마바')  //true 가나다 중 하나가 있는지
/[a-zA-Z]/.test('반가워요')  //false 아무 알파벳중 하나
/[a-zA-Z]/.test('반가워요a') //true
/[-ㅎ가-힣ㅏ-]/.test('반가워요')  //true 아무 한글 하나
/\S/.test('abcde')   //true 특수문자표함 아무문자 하나
/^a/.test('abcde')   //true a로 시작하는지
/e$/.test('abcde') //true e로 끝나는지
/(e|f)/.test('abcde')   //true or기호, 둘중 아무거나 한문자가 있는지
/a+/ //모든 a를 다찾음
/\S+t/ //모든 문자 여러개, 다음에 t라는 글자가 있냐 ->aaaaat vavvbt
/\S+@\S+\.\S+/ //간단한 이메일 정규식 \. 이라는 기호는 왜 이렇게 썼냐면 마침표는 정규식에서 특수한 문법이기 때문에
//마침표 문법을 쓰는게 아니라 진짜 마침표를 찾아달라라는 의미로 쓰려면 백슬래시를 앞에 붙여야하기때문에

📌 캐러셀 - 슬라이드되는 UI

슬라이드되면서 보여지려면 가로로 길게 우선 만들어놔야함

<div style="overflow: hidden"> //overflow는 화면 크기 넘어간거 숨김
    <div class="slide-container">
      <div class="slide-box">
        <img src="car1.png">
      </div>
      <div class="slide-box">
        <img src="car2.png">
      </div>
      <div class="slide-box">
        <img src="car3.png">
      </div>
    </div>
 </div>
.slide-container {
  width: 300vw; //vw는 브라우저폭에 비례한 단위 100vw는 브라우저폭의 100%
  transition: all 1s;
	transform: translateX(-100vw); //x축 -100vw으로 이동 즉 왼쪽으로 이동
}
.slide-box {
  width: 100vw;
  float: left;
}
.slide-box img {
  width: 100%;
}
$('.slide-1').on('click', function() {
  $('.slide-container').css('transform', 'translateX(0vw)');
});

$('.slide-2').on('click', function() {
  $('.slide-container').css('transform', 'translateX(-100vw)');
});

$('.slide-3').on('click', function() {
  $('.slide-container').css('transform', 'translateX(-200vw)');
}); //이런식으로 버튼누르면 이동하게 

다음버튼 누르면 이동하도록

변수를 사용함

$('.next').on('click', function(){
        if(currentImg == 1){
          $('.slide-container').css('transform', 'translateX(-100vw');
          currentImg+=1;
        }
        else if(currentImg == 2){
          $('.slide-container').css('transform', 'translateX(-200vw');
          currentImg +=1;
        }
      })
      $('.prev').on('click',function(){
        if(currentImg == 3){
          $('.slide-container').css('transform', 'translateX(-100vw');
          currentImg -= 1;
        }
        else if(currentImg == 2){
          $('.slide-container').css('transform', 'translateX(0vw');
          currentImg -= 1;
        }
      })

문자 중간에 변수 집어넣는 방법

var count = 1;
console.log('문자' + count + '문자');
console.log(`문자${count}문자`) //둘다 같은 기능

함수 안에서 쓸 수 있는 return문법

return은 함수를 실행하고 나서 그 자리에 결과를 남김, 함수종료의 뜻도 가지고 있음

return뒤의 코드는 실행안됨

자바스크립트에서 소수점 연산시 주의점

console.log(1.1+3) //결과 1.4000000001

컴퓨터는 2진법으로 계산하기때문

해결하고 싶으면

  1. 덧셈하기 전에 10 곱해서 덧셈하고 10으로 나누거나
  2. 외부라이브러리 사용하거나
  3. 오차는 무시할 정도로 작으니 그냥 반올림을 하기
    아주 정확한 계산이 필요한게 아니면 대부분 반올림
console.log((1.1+3).toFixed(2));// 1의자리에서 반올림

toFixed를 사용하게 되면 ‘문자'로 변환해주기때문에 주의해야함

toFixed한 결과에 + 123을 하게되면 문자이기때문에 4.1123결과가 출력 (문자)

+기호 사용시 둘 중 적어도 하나가 문자가 있으면 문자덧셈을 하기 때문

문자덧셈은 그냥 문자두개 이어붙여줌

⇒숫자로 변환하려면

문자처럼생긴 숫자를 숫자로 변경해주는 유용한함수입니다.

parseFloat('123')
parseInt('123')

parseInt()는 정수로, parseFloat()는 실수로 변환해줍니다.

스크롤 관련 유용한 기능들

window.addEventListener('scroll', function(){
  console.log( window.scrollY )
});

window.scrollY 사용하면 현재 페이지를 얼마나 위에서 부터 스크롤했는지 px 단위로 알려줌 - 매우유용

window.scrollX 는 가로로 얼마나 스크롤했는지 알려줌(가로 스크롤바가 있으면)

window.scrollTo(0, 100) //window.scrollTo(x, y) 실행하면 강제로 스크롤바를 움직일 수 있습니다.
//위 코드는 위에서부터 100px 위치로 스크롤해줍니다.
window.scrollBy(0, 100)//window.scrollBy(x, y) 실행하면 현재 위치에서부터 스크롤해줍니다.
//위 코드는 현재 위치에서부터 +100px 만큼 스크롤해줍니다.

원래 저거 실행하면 스크롤 위치가 순간이동해야되는데

bootstrap을 설치했을 경우 이상하게 천천히 이동할 수 있습니다. →부트스트랩 사용할 경우에만

그게 싫으면 :root { scroll-behavior : auto } 이걸 css 파일 맨 위에 추가합시다.

$(window).on('scroll', function(){
  $(window).scrollTop();
})

📌 스크롤 숙제

		window.addEventListener('scroll', function(){ //유저가 스크롤할때마다 실행
        var scrollh=window.scrollY;
        if(scrollh>100){ //스크롤값이 100넘어가면 로고를 작게
          $('.main-logo').css('font-size','20px');
        }
        else{
          $('.main-logo').css('font-size','30px');
        }
      })
      
      $('.lorem').on('scroll',function(){
        var scrollamount=document.querySelector('.lorem').scrollTop; //스크롤양
        var realheight=document.querySelector('.lorem').scrollHeight; //실제높이
        var divheight=document.querySelector('.lorem').clientHeight; //div높이

        if(scrollamount + divheight > realheight - 10){ //오차가있을수있기때문에-10정도
          alert('finish');
        }
      })

스크롤 다룰 때 주의점

  1. 스크롤이벤트리스너 안의 코드는 1초에 60번 이상 실행

그래서 스크롤 이벤트리스너는 많이 달면 성능저하가 일어나니 스크롤바 1개마다 1개만 사용하는게 좋음

  1. 스크롤이벤트리스너 안의 코드는 1초에 여러번 실행되다보니 바닥체크하는 코드도 여러번 실행될 수 있다

숙제2에서 alert가 2번 뜨고 그럴 수 있다는 뜻입니다.
=>이런건 해결하려면 구글검색

  1. 웹페이지 scrollHeight 구할 땐 브라우저마다 아주 약간의 오차가있을 수 있어서 테스트해보는게 좋다

  2. 웹페이지 scrollHeight 구하는 코드는 페이지 로드가 완료되고나서 실행해야 정확합니다. 그래서 끝나기 전에 적는게 좋습니다.

현재 페이지를 끝까지 스크롤했는지 체크하려면

document.querySelector('html').scrollTop;  //현재 웹페이지 스크롤양
document.querySelector('html').scrollHeight; //현재 웹페이지 실제높이
document.querySelector('html').clientHeight; //현재 웹페이지 보이는 높이임

자바스크립트파일 모듈화하는 법

.js파일 만들고 끝에 <script src="어쩌구.js"></script> 붙임

📌 jQuery 셀렉터로 여러 요소 찾은 뒤 하나만 고르기

지금 class="tab-button" 가진 요소가 3개나 있습니다.

그래서 $('.tab-button').on() 이렇게 이벤트리스너 달면

3개 버튼에 전부 이벤트리스너를 달게됩니다.

그게 싫고 버튼0만 달고 싶으면

$('.tab-button').eq(0).on('click', function(){
  
});

$( ) 셀렉터로 찾은 요소 중에 x번째 요소만 선택하고 싶으면

$( ).eq(x) 쓰면 됩니다.

querySelectorAll() 쓰는 경우에도 [0] 이런거 붙여야 잘되는거 잊지맙시다.

for 안에서 var i = 0 쓰면

  • var 변수는 범위가 function입니다.
  • var i 들어있는 포스트잇은 for 바깥에 생성됩니다.

for 안에서 let i = 0 쓰면

  • let 변수는 범위가 { } 입니다.
  • let i 들어있는 포스트잇은 for 안쪽에 3개 생성됩니다.
for(let i =0; i<3; i++){
  $('.tab-button').eq(i).on('click',function(){
    $('.tab-button').removeClass('orange');
    $('.tab-button').eq(i).addClass('orange');
    $('.tab-content').removeClass('show');
    $('.tab-content').eq(i).addClass('show');
  })
} //확장성을 위해서 3대신 $('.tab-button').length쓰면 탭이 늘어나도 자동으로됨

📌좋은 관습 : 반복적인 셀렉터는 변수에 넣어서 쓰기→var 버튼 = $('.tab-button'); 이렇게

셀렉터 문법은 기본적으로 작동시간이 오래걸림

셀렉터 하나 쓸 때 마다 html을 쭉 읽고 찾아야해서 오래걸림

html이 길고 복잡할 수록 더 오래걸리기때문에 반복적으로 등장하면 그냥 변수에 넣어서 사용

querySelector 도 마찬가지

모달창 검정 배경 누르면 모달창 닫히는 기능

document.querySelector('.black-bg').addEventListener('click', function(){
  document.querySelector('.black-bg').classList.remove('show-modal');
}) //이렇게 하면 버블링이 일어나서 아무거나 눌러도 닫힘

⇒ 이렇게 하면 검은배경 뿐만 아니라 흰배경, input, 글자 등 모달창 내부의 어떤걸 눌러도 다 닫힘

📌📌 이벤트 버블링

어떤 HTML 태그에 이벤트가 발생하면 그의 모든 상위요소까지 이벤트가 실행되는 현상을 이벤트 버블링이라고 함

click이라는 이벤트로 예를 들어보면,

HTML 태그에 클릭이 발생하면 그의 모든 상위요소까지 자동으로 클릭된다는 뜻

이벤트리스너 안에서 쓰는 이벤트 함수들

이벤트리스너의 콜백함수에 파라미터 아무거나 추가하면

이벤트관련 유용한 함수들을 사용가능

파라미터 이름은 아무렇게나 작명하면 되고, 보통 대충 e라고 함

document.querySelector('.black-bg').addEventListener('click', function(e){
  e.target;
  e.currentTarget;
  e.preventDefault();
  e.stopPropagation();
})

e.target은 실제 클릭한 요소 알려줌 (이벤트 발생한 곳)

e.currentTarget은 지금 이벤트리스너가 달린 곳 알려줌 (참고로 this라고 써도 똑같음)

e.preventDefault() 실행하면 이벤트 기본 동작을 막아줌

e.stopPropagation() 실행하면 내 상위요소로의 이벤트 버블링을 중단해줌

여기서 중요한건 e.target인데

이벤트 버블링이 일어난다고 해도

사용자가 실제로 클릭한 그 요소는 저 문법으로 찾아낼 수 있음

document.querySelector('.black-bg').addEventListener('click', function(e){
        if(e.target == document.querySelector('.black-bg')){
          document.querySelector('.black-bg').classList.remove('show-modal');
        }
      }) //버블링 해결

⇒ 📌이벤트 버블링은 항상 일어나기 때문에 주의할것

⇒ 📌이벤트 버블링을 알고 있으면 이벤트리스너를 줄여가며 개발할 수 있음

📌 이벤트버블링을 알면 이벤트리스너 줄일 수 있음

버튼 3개의 부모인 <ul class="list"> 여기에 이벤트리스너 1개만 있어도 탭기능만들 수 있을듯?

버튼 뭘 누르든 간에 <ul class="list">에 붙은 이벤트리스너도 동작하기때문

왜냐면 이벤트버블링이 항상 일어나기 때문=>이벤트리스너를 줄이면 램용량을 절약할 수있음

<ul class="list">
        <li class="tab-button orange" data-id="0">Products</li>
        <li class="tab-button" data-id="1">Information</li>
        <li class="tab-button" data-id="2">Shipping</li>
</ul> 

for(let i =0; i<3; i++){
   $('.tab-button').eq(i).on('click',function(){
     tabtab(i);
   })
}
//버블링을 이용해 축약한 코드
$('.list').click(function(e){
  if (e.target == document.querySelectorAll('.tab-button')[0] ){
    tabtab(0)
  }
  if (e.target == document.querySelectorAll('.tab-button')[1] ){
    tabtab(1)
  }
  if (e.target == document.querySelectorAll('.tab-button')[2] ){
    tabtab(2)
  }
})

//함수로 코드를 싸맬 때 안에 변수가 들어있으면 변수를 전부 파라미터로 바꾸는게 좋습니다.
//그래야 잘 동작합니다. 그래서 i 부분을 전부 파라미터로 바꿨습니다.
function tabtab(num){
  $('.tab-button').removeClass('orange');
  $('.tab-button').eq(num).addClass('orange');
  $('.tab-content').removeClass('show');
  $('.tab-content').eq(num).addClass('show');
}

dataset 문법 (잡기술)

<div data-데이터이름=""></div>

html 안에 유저 몰래 정보를 숨겨놓을 수 있음

데이터이름 아무렇게나 작명하고 값도 넣으면 사용가능
=>실무에서 잘 쓰는지는 모름

document.querySelector().dataset.데이터이름;

이러면 html 요소에 숨겨놨던 데이터가 이 자리에 남습니다.

출력해보면 진짜로 아까 숨겨놓은 값이 남습니다.

<ul class="list">
        <li class="tab-button orange" data-id="0">Products</li>
        <li class="tab-button" data-id="1">Information</li>
        <li class="tab-button" data-id="2">Shipping</li>
</ul> 

$('.list').on('click',function(e){
  console.log(e.target.dataset.id);
  tabtab(e.target.dataset.id)
})

Array 자료형

여러가지 자료를 한곳에 저장하고 싶을 때 사용하는 자료형

var car = ['소나타', 50000, 'white'];
console.log(car[1]); // 50000출력
car[1] = 60000; //array자료수정

Object 자료형

중괄호를 열고 자료를 콤마로 구분해서 넣음

자료 왼쪽에 자료의 이름(key)를 붙여서 저장

key : value형태로 자료를 저장 -구분하기 편함

var car2 = { name : '소나타', price : 50000 };
console.log(car2['name']); //출력
console.log(car2.name); //같은거출력
car2['name'] = '그랜저'; // object 자료수정

⇒여러 자료를 변수 하나에 저장하고 싶으면 object 사용해도 편리

📌Array / Object 차이

상품명, 가격, 연식, 색상, 옵션여부, 카드할인여부 ... (뒤에 10개 더 있음)

이런 데이터를 변수하나에 보관하고 싶으면 array 쓸 것입니까 object ??

array쓰면 저장시엔 간단하겠지만

나중에 자료 뽑을 때 어려움

array는 순서개념이 있다. 왼쪽에 적을 수록 더 앞에 있는 자료임

object는 순서개념이 없음. 가장 왼쪽에 적었다고 해도 1임을 보장해주지 않는다

그래서 array 자료는 순서개념이 있다보니

  • 가나다순 정렬
  • x번 자료부터 x번 자료까지 자르기
  • x번 자료 바꾸기
  • 맨 뒤, 맨 앞에 자료 넣기
  • 원하는 자료가 들어있나 검색

순서개념이 필요한 많은 것들을 할 수 있음

array자료.sort() 하면 가나다순 정렬되고

array자료.slice(x, y) 하면 x번부터 y번 전까지 자를 수 있고

array자료.push(x) 하면 x를 맨 뒤에 입력할 수 있고

이런 기본함수들이 존재

복잡한 데이터에서 자료꺼내려면

무조건 모르겠다 싶으면 console.log해서 출력해서 보면 됨

콘솔창에선 복잡한 자료도 어떻게 생겼는지 쉽게 축약해서 알려주는데
여기서 시작기호만 잘보면 됨

시작기호가 { 이거면 무조건 object 자료형 (무조건은 아니고 90% 확률) →그래서 object 자료에서 자료꺼내는 문법부터 작성

시작기호가 ( 이거면 무조건 array 자료형 (무조건은 아니고 90% 확률) →그래서 array 자료에서 자료꺼내는 문법부터 작성

실제 웹서비스 개발할 땐 2개 방식이 있는데(html을 누가 완성하는지에 따라 개발방식의 차이가 있음)

1. 서버에서 html을 미리 완성해서 고객에게 보내줌

이걸 server-side rendering 이라고 함

2. 서버가 비어있는 html과 데이터만 보내줌

그리고 자바스크립트를 이용해서 고객 브라우저안에서 html을 완성합니다.

이걸 client-side rendering 이라고 함

요즘은 2번이 유행이라 데이터를 서버에서 가져와서 데이터바인딩하는 방법을 배우고 있는 것

근데 데이터바인딩하는 문법이 너무 길고 복잡하기 때문에 작은 사이트는 쌩 자바스크립트 써도 커버가능한데

큰거 만들 땐 사람들이 라이브러리 설치해서 쓰는 것

jQuery, React, Vue 이런거 사용하면 코드가 짧아진다

<body>

    <div class="card-group container">
      <div class="card">
        <img src="https://via.placeholder.com/600">
        <div class="card-body">
          <h5>Card title</h5>
          <p>가격 : 70000</p>
          <button class="btn btn-danger">주문하기</button>
        </div>
      </div>
      <div class="card">
        <img src="https://via.placeholder.com/600">
        <div class="card-body">
          <h5 class=>Card title</h5>
          <p class=>가격 : 70000</p>
          <button class="btn btn-danger">주문하기</button>
        </div>
      </div>
      <div class="card">
        <img src="https://via.placeholder.com/600">
        <div class="card-body">
          <h5>Card title</h5>
          <p>가격 : 70000</p>
          <button class="btn btn-danger">주문하기</button>
        </div>
      </div>
    </div>
    
    <script>
      var products = [
        { id : 0, price : 70000, title : 'Blossom Dress' },
        { id : 1, price : 50000, title : 'Springfield Shirt' },
        { id : 2, price : 60000, title : 'Black Monastery' }
      ];

      for(let i=0; i<3; i++){
        document.querySelectorAll('.card-body h5')[i].innerHTML = products[i].title;
        document.querySelectorAll('.card-body p')[i].innerHTML = `가격 : ${products[i].price}`;
      }

` ←백틱기호를 사용하면 문자중간에 엔터키를 칠 수 있고 중간에 ${변수명}문법을 이용가능함

select 들어간 폼

<form class="container my-5 form-group">
    <p>상품선택</p>
    <select class="form-select mt-2">
      <option>모자</option>
      <option>셔츠</option>
    </select>
</form>

<select><input> 이랑 똑같은데

사용자가 고를 수 있는 선택지를 드랍다운 메뉴로 제공하는 <input> 입니다.

선택지는 <option>으로 넣으면 됨

  • <select> 태그도 선택시 input, change 이벤트가 발생합니다.
  • <select> 태그도 .value로 유저가 입력한 값을 가져올 수 있습니다.

자주 중요하게 언급되는 내용

지금 "유저가 셔츠선택하면 form-hide 제거해주세요~" 라고 코드짰는데

이 코드는 <script> 안에 적었기 때문에 그냥 페이지 로드시 1회 실행되고 다시는 실행되지 않음

그래서 저 코드를 <select> 조작할 때 마다 실행한다면 의도대로 잘 동작할듯

$('.form-select').eq(0).on('input', function(e){
  console.log(e.currentTarget.value); //$(".form-select").eq(0).val() 같음
  console.log(this.value); //$(".form-select").eq(0).val() 같음
  
  if ($(".form-select").eq(0).val() == "셔츠") {
    $(".form-select").eq(1).removeClass("form-hidden");
  }
  else{
    $(".form-select").eq(1).addClass("form-hidden");
  }
})

자바스크립트로 html 생성하는 법 1

<div id="test">
  
</div>

<script>
  var a = document.createElement('p');
  a.innerHTML = '안녕';
  document.querySelector('#test').appendChild(a);
</script>
  • document.createElement() 쓰면 html 자료를 하나 생성해줍니다.
  • 그걸 맘대로 조작한 다음 appendChild() 써서 아무데나 넣으면 html이 생성됩니다.

자바스크립트로 html 생성하는 법 2

<div id="test">
  
</div>

<script>
  var a = '<p>안녕</p>';
  document.querySelector('#test').insertAdjacentHTML('beforeend', a);
	$('#test').append(a); //이게 더 간단
</script>
  • 문자자료로 html을 만든 다음
  • insertAdjacentHTML() 안에 넣으면 됩니다.
  • 'beforeend' 이건 안쪽 맨 밑에 추가하라는 뜻입니다. 싫으면 맘대로 변경가능

*안쪽에 추가하는게 아니라 아예 바꿀때

A. div찾아서 innerHTML = '

'

jQuery에선 .html() 입니다.

$('.form-select').eq(0).on('input', function(e){
  var value = $('.form-select').eq(0).val();
    if (value == '셔츠') {
      $('.form-select').eq(1).removeClass('form-hidden');
      $('.form-select').eq(1).html(''); //html내용 삭제
      var items = `<option>95</option><option>100</option>`;
      $('.form-select').eq(1).append(items)
    }
    else if (value == '바지'){
      $('.form-select').eq(1).removeClass('form-hidden');
      $('.form-select').eq(1).html(''); //html내용 삭제
      var items = `<option>28</option><option>30</option>`;
      $('.form-select').eq(1).append(items)
    }
    else{
      $('.form-select').eq(1).addClass('form-hidden');
    }
  
})

forEach 반복문

array 자료 뒤에 붙일 수 있는 forEach() 라는 기본함수가 있음
안의 데이터 갯수만큼 반복

var pants = [28,30,32]; //서버로 가정
var shirts = [95, 100 ,105];

$('.form-select').eq(0).on('input', function(e){
  var value = $('.form-select').eq(0).val();
    if (value == '셔츠') {
      $('.form-select').eq(1).removeClass('form-hidden');
      $('.form-select').eq(1).html('');
      shirts.forEach(function(data){//shirts안의 데이터갯수만큼 반복
        $('.form-select').eq(1).append(`<option>${data}</option>`)
      })
    }
    else if (value == '바지'){
      $('.form-select').eq(1).removeClass('form-hidden');
      $('.form-select').eq(1).html('');
      pants.forEach(function(data){ //pants안의 데이터갯수만큼 반복
        $('.form-select').eq(1).append(`<option>${data}</option>`)
      })
    }
    else{
      $('.form-select').eq(1).addClass('form-hidden');
    }
  
}) //이렇게 서버에서 받아오는걸로 작성하면 확장성 높음

foreach 콜백함수 안에 파라미터 2개까지 작명이 가능한데 (실은 3개까지)

첫 파라미터는 반복문 돌 때 마다 array 안에 있던 하나하나의 데이터가 되고

둘 째 파라미터는 반복문 돌 때 마다 0부터 1씩 증가하는 정수

var pants = [28, 30, 32];
pants.forEach(function(a, i){
  console.log(a)
});

object 자료 다룰 때 for in 반복문 가능

var obj = { name : 'kim', age : 20 }

for (var key in obj){
  console.log(key); //name age출력
	console.log(obj[key]); //value값들(kim 20) 출력
}

반복문의 주된 용도 2개

  1. 코드 복붙
  2. array, object 자료 다 꺼내고 싶을때

arrow function 문법 //이거 다시 검색해서 이해해야될듯

var pants = [28, 30, 32];

pants.forEach(function(a){
  console.log(a)
});

pants.forEach((a) => {
  console.log(a)
}); //둘다 같은결과

그냥 함수와 arrow function의 기능차이는 하나가 있는데

함수 안에서 this를 써야할 경우

  • 그냥 함수는 함수 안에서 this를 알맞게 재정의해줍니다.
  • arrow function은 함수 안에서 this를 재정의해주지 않고 바깥에 있던 this를 그대로 씁니다.

그래서 이벤트리스너 콜백함수안에서 this를 써야하면 arrow function 쓰면 의도와 다르게 동작할 수도 있습니다.

그런데선 쓰면 안됨

서버와 데이터를 주고받는 방법 중 하나

서버란?

유저가 데이터달라고 요청을 하면 데이터를 보내주는 간단한 프로그램일 뿐

네이버웹툰 서버 : 유저가 웹툰 달라고 하면 웹툰 보내주는 프로그램

유튜브 서버 : 유저가 영상 달라고 하면 영상 보내주는 프로그램

서버에 데이터를 요청할 때는

  1. 어떤 데이터인지 url로 잘 기재해야하고
  2. 어떤 방법으로 요청할지 결정해야 (GET/POST 등)

데이터를 보내줌

GET/POST 요청

GET요청은 서버에 있던 데이터를 읽고싶을 때 주로 사용하고

POST요청은 서버로 데이터를 보내고 싶을 때 사용

실은 PUT, DELETE 요청도 있음

GET요청을 날리고 싶으면 가장 쉬운 방법은 브라우저 주소창을 통한 방법

거기에 url 적으면 그 곳으로 GET요청을 보냄

POST요청을 날리고 싶으면

<form action="요청할url" method="post"> 태그 이용

그럼 폼이 전송되었을 때 POST요청을 날려줌

근데 GET, POST 요청을 저렇게 날리면 단점이 뭐냐면 브라우저가 새로고침

📌 AJAX란?

서버에 GET, POST 요청을 할 때 새로고침 없이 데이터를 주고받을 수 있게 도와주는 간단한 브라우저 기능을 AJAX

그거 쓰면 새로고침 없이도 쇼핑몰 상품을 더 가져올 수도 있고

새로고침 없이도 댓글을 서버로 전송할 수도 있음

📌jQuery로 AJAX요청하기

$.get() 라는 함수를 쓰고 안에 url만 잘 넣으면 됨
가져온 데이터가 어디 들어있냐면

.done 아니면 .then 뒤에 붙이고 콜백함수넣고 파라미터 하나 만들면 거기에 들어있음

서버로 데이터를 보낼 수 있는 POST요청을 날리고 싶으면
url 잘 적고 뒤에 서버로 보낼 데이터를 적으면 됩니다.

당연히 얘도 .done 이런거 붙이기 가능

$.get('https://codingapple1.github.io/hello.txt');
$.get('https://codingapple1.github.io/hello.txt').done(function(data){
  console.log(data)
});
$.post('url~~', {name : 'kim'})
$.get('https://codingapple1.github.io/hello.txt')
  .done(function(data){ //성공
    console.log(data)
  })
  .fail(function(error){ //실패
    console.log('실패함')
  });

생자바스크립트를 통한 ajax요청

fetch('https://codingapple1.github.io/price.json')
  .then(res => res.json()) //이거 한줄 더 필요
  .then(function(data){
    console.log(data)
  })
  .catch(function(error){
    console.log('실패함')
  });

근데 코드가 한 줄 더 필요한 이유가 뭐냐면

서버와 데이터를 주고받을 때는 문자만 주고받을 수 있음.

array, object 이런거 전송불가능

근데 아까 { price : 5000 } 이런 object 잘받은 이유는

어떻게 한거냐면 object를 JSON으로 바꿔서 전송해줘서

array 아니면 object에 따옴표를 다 쳐서 '{ "price" : 5000 }' 대충 이렇게 만들면 JSON이라는 자료가 된다

JSON은 문자로 인식하기 때문에 서버와 데이터주고받기가 가능

하지만

jQuery의 $.get() 이런건 JSON으로 자료가 도착하면 알아서 array/object 자료로 바꿔줌

기본함수 fetch() 이런건 JSON으로 자료가 도착하면 알아서 array/object 자료로 바꿔주지 않음

그래서 fetch() 로 가져온 결과를 array/object로 바꾸고 싶으면 res.json() 이런 코드 한 줄 추가

그게 귀찮으면 jQuery나 axios 이런 라이브러리 설치하면 ajax가 간편해짐

버튼클릭하면 서버에서 데이터받아와서 카드추가

var count = 0;
      $('#more').on('click',function(){
        count++;
        if(count == 1){
          $.get('https://codingapple1.github.io/js/more1.json').done(function(data){
            console.log(data);
            data.forEach(function(a,i){
              var cards= `<div class="col-sm-4">
              <img src="https://via.placeholder.com/600" class="w-100">
              <h5>${a.title}</h5>
              <p>가격 : ${a.price}</p>
              </div>`
              // console.log(a);
              // console.log(data[i]);//로그찍히는거 같음
              // console.log(a.title);
              // console.log(data[i].title); //같음 a.price = data[i].price
              $('.row').append(cards);
          })
          })
        }
        else if(count == 2){
          $.get('https://codingapple1.github.io/js/more2.json').done(function(data){
            console.log(data);
            data.forEach(function(a,i){
              var cards= `<div class="col-sm-4">
              <img src="https://via.placeholder.com/600" class="w-100">
              <h5>${a.title}</h5>
              <p>가격 : ${a.price}</p>
              </div>`
              $('.row').append(cards);
          })
          })
          $('#more').css('display', 'none');
        }
        })

array 정렬하는 법

그냥 문자 가나다순으로 정렬하려면 .sort() 붙이면 되는데

숫자정렬은 아래처럼 코드작성

var 어레이 = [7,3,5,2,40];
어레이.sort(function(a, b){
  return a - b
});

console.log(어레이);

동작원리

어레이.sort(function(a, b){
  return a - b
});
  1. a, b는 array 안의 자료들입니다.

//어레이가 [4,5,6,]이면 a와 b는 4 5 이런데이터를 가리킴

어레이가 [{name:’dd’, age:’15’}…]와 같이 array안에 object가 있는 형태이면 a는 중괄호 전체를 가리킴

  1. return 결과가 양수면 a를 오른쪽으로 정렬해줍니다.
  2. return 결과가 음수면 b를 오른쪽으로 정렬해줍니다.
  3. 그리고 array 안의 자료들을 계속 뽑아서 a, b에 넣어줍니다.

이렇게 동작해서 a - b 저렇게 쓰면 숫자순 정렬이 되는 것

예를 들면 a, b가 7과 3일 경우 7 - 3 하면 4가 남습니다.

4는 양수죠? 그러면 7을 3보다 오른쪽으로 보내줍니다.

그래서 숫자 오름차순 (123순) 정렬이 완성되는 것입니다.

⇒ 내림차순은 b-a

문자정렬과 문자역순정렬

  1. a, b가 '가', '다' 일 경우 return 우측에 양수가 들어가야 다나가순 정렬이 됩니다.

(2) a, b가 '다', '나' 일 경우 return 우측에 음수가 들어가야 다나가순 정렬이 됩니다.

(3) a, b가 '가', '나' 일 경우 return 우측에 양수가 들어가야 다나가순 정렬이 됩니다.

....

이렇게 대충 하나하나 대입해서 따져보면 규칙같은게 눈에 보이는데

a < b 일 경우 return 우측에 양수가 들어가면 되고

a > b 일 경우 return 우측에 음수가 들어가면 됩니다.

(자바스크립트는 문자끼리 부등호비교가 가능합니다. ㄱ보다 ㅎ 이게 더 큽니다.)

버튼누르면 products를 가격순 정렬해봅시다

$('#sorting').on('click',function(){
        products.sort(function(a,b){
          return a.price-b.price;
          //그냥 a-b하면 오브젝트a-오브젝트b임
        });
        $('.row').html('');
        products.forEach(function(a,i){
          var cards= `<div class="col-sm-4">
          <img src="https://via.placeholder.com/600" class="w-100">
          <h5>${a.title}</h5>
          <p>가격 : ${a.price}</p>
          </div>`
          $('.row').append(cards);
        })
      })

📌📌 array에 자주 쓰는 filter 함수

array 자료에서 원하는 자료만 필터링하고 싶으면 filter 함수를 씁니다.

var 어레이 = [7,3,5,2,40];

var 새어레이 = 어레이.filter(function(a){
  return a < 4
}); //4미만인 것만 저장
  1. a라고 작명한건 array 에 있던 데이터를 뜻하고
  2. return 우측에 조건식을 넣으면 조건식에 맞는 a만 남겨줍니다.
  3. 그리고 filter는 원본을 변형시키지 않는 고마운 함수기 때문에 새로운 변수에 담아써야합니다.

📌📌 array에 자주 쓰는 map 함수

array 안의 자료들을 전부 변형하려면 map 함수를 씁니다.

var 어레이 = [7,3,5,2,40];

var 새어레이 = 어레이.filter(function(a){
  return a * 4
}); //전부 4를 곱해서 저장
  1. a라고 작명한건 array 에 있던 데이터를 뜻하고
  2. return 우측에 변경될 수식같은걸 넣으면 됩니다.
  3. 그리고 filter는 원본을 변형시키지 않는 고마운 함수기 때문에 새로운 변수에 담아써야합니다.

이런거 응용하면 쇼핑몰에서 "달러 -> 원화로 변환하기" 이런 기능도 만들 수 있음

array 안에 있는 숫자들을 달러가격이라고 생각해봅시다. 이걸 전부 원화가격으로 변경하고 싶으면 아마 map 써서 1000얼마 곱해주면 끝일듯요.

(참고)

sort 함수는 원본을 변형시켜버립니다.

요즘 코드짤 때 원본을 변형시키는건 나중에 힘들어질 수 있어서

array/object 자료 조작시엔 원본을 따로 복사해두고 조작하는 경우가 많습니다.

📌각 버튼 누르면 다나가순 정렬 / 6만원 이하 상품만보기

$('#danaga').on('click',function(){
        products.sort(function(a,b){
          if(a.title < b.title){return 1;}
          else if (a.title > b.title){return -1;}
          else{return 0;}
        });
        console.log(products);

        $('.row').html('');
        products.forEach(function(a,i){
          var cards= `<div class="col-sm-4">
          <img src="https://via.placeholder.com/600" class="w-100">
          <h5>${a.title}</h5>
          <p>가격 : ${a.price}</p>
          </div>`
          $('.row').append(cards);
        })
      })
      
      $('#under').on('click',function(){
        var newp = products.filter(function(a){
          return a.price <= 60000;
        });
        console.log(newp);

        $('.row').html('');
        newp.forEach(function(a,i){
          var cards= `<div class="col-sm-4">
          <img src="https://via.placeholder.com/600" class="w-100">
          <h5>${a.title}</h5>
          <p>가격 : ${a.price}</p>
          </div>`
          $('.row').append(cards);
        })
      })

📌DOM이라는 용어 개념정리 & load 이벤트

  1. DOM = Document Object Model

자바스크립트가 HTML 조작을 하기 위해선 HTML을 자바스크립트가 해석할 수 있는 문법으로 변환해놓면 됩니다.

HTML을 자바스크립트가 좋아하는 array 혹은 object 자료형에 담아버리는게 좋지 않을까요?

그래서 실제로 브라우저는 HTML 페이지를 열어줄 때

HTML을 자바스크립트로 쉽게 찾고 바꾸기 위해 object와 비슷한 자료형에 담아줍니다.

<div style="color : red">안녕하세요</div>

예를 들어서 브라우저는 이런 html을 발견하면 object자료로 바꿔서 보관

var document = {
  div1 : {
    style : {color : 'red'}
    innerHTML : '안녕하세요'
  }
}

대충 이렇게 object 자료에 정리를 해놓는다는 소리입니다.

왜냐고요? 이래야 저렇게 점찍어서 원하는 자료를 출력하고 조작하고 할 수 있지 않겠습니까.

이제 document.div1.innerHTML = '안녕' 이렇게 자바스크립트를 짜면 HTML 조작이 가능할듯요

그래서 저렇게 object에 담아두는 것입니다.

(물론 실제 DOM과 생김새는 좀 다르겠지만)

위 변수를 document object라고 부릅니다. 간지나게 + model이라고 붙여서 Document Object Model이라고 합니다.

요약하자면 자바스크립트가 HTML에 대한 정보들 (id, class, name, style, innerHTML 등)을

object 자료로 정리한걸 DOM이라고 부릅니다.

2. 브라우저는 HTML 문서를 위에서 부터 읽으며 DOM을 생성합니다.

브라우저는 HTML문서를 위에서 부터 차례로 읽어내려갑니다.

읽을 때 마다 HTML을 발견하면 DOM에 추가해줍니다.

그래서 이걸 알면 왜 하단 코드가 에러가 나는지도 알 수 있겠군요.

(html 파일)

<script>
  document.getElementById('test').innerHTML = '안녕'
</script>

<p id="test">임시글자</p>

이렇게 코드짜면 에러남

왜냐면 브라우저는 HTML을 위에서부터 한줄한줄 읽습니다.

그런데 갑자기 자바스크립트로 <p id="test">인 요소를 DOM에서 찾고 바꾸라고하는겁니다.

그래서 에러가 날 뿐입니다.

왜냐면 아직 <p id="test">를 읽기 전이라 p태그에 대한 DOM이 아직 생성되지 않았으니까요.

이렇듯 자바스크립트는 DOM이 생성된 경우에만 HTML을 변경할 수 있습니다.

3. 혹은 자바스크립트 실행을 약간 나중으로 미루는 방법도 있음

$(document).ready(function(){ 실행할 코드 })
document.addEventListener('DOMContentLoaded', function() { 실행할 코드 })

둘 중 마음에 드는거 쓰면 됩니다.

이 이벤트리스너들은 "HTML을 다 읽어들였는지"를 알려주는 이벤트리스너입니다.

(html 파일)

<script>
  document.addEventListener('DOMContentLoaded', function() { 
    document.getElementById('test').innerHTML = '안녕'
  })
</script>

<p id="test">임시글자</p>

그래서 거기 안에 "저 밑에있는 <p id="test"> 변경해주세요~" 라고 코드 짜도 잘 동작함

그래서 예전스타일 강의들 보시면 ready 아니면 DOMContentLoaded 이벤트리스너를 꼭 쓰라고 가르칩니다.

안정적이니까요.

요즘은 그냥 자바스크립트를 <body>태그 끝나기 전에 전부 작성하기 때문에 그런 걱정은 안하셔도됩니다.

자바스크립트 위치를 내가 정할 수 없을 경우에만 유용한 방법이라고 보시면 되겠습니다.

4. load 이벤트리스너

load 라는 이벤트리스너를 사용하면 DOM 생성뿐만 아니라 이미지, css, js파일이 로드가 됐는지도 체크가능합니다.

셀렉터로찾은이미지.addEventListener('load', function(){
  //이미지 로드되면 실행할 코드 
})
//근데 외부 자바스크립트 파일에 저걸 적어놓으면
//그 js 파일보다 이미지가 더 먼저 로드되는 경우도 있으니 이벤트 발생체크를 못할 수도 있겠군요
$(window).on('load', function(){
  //document 안의 이미지, js 파일 포함 전부 로드가 되었을 경우 실행할 코드 
});

window.addEventListener('load', function(){
  //document 안의 이미지, js 파일 포함 전부 로드가 되었을 경우 실행할 코드
})

window에 붙이셔도 됩니다. document에 포함된 이미지, CSS파일 등 모든것이 로드가 되었는지 체크해줍니다.

ready 이런거랑 차이는 앞선 .ready()는 DOM 생성만 체크하는 함수인데,

이것보다 약간 더 나아가서 모든 파일과 이미지의 로드상태를 체크한다고 보시면 되겠습니다.

그래서 이거 써서 "이미지가 다 로드되면 사이트 보여주세요~" 이런 코드짜는 사람들이 있는데

한국인이라면 오히려 속터짐

브라우저 내의 저장공간

크롬 개발자도구의 Application 탭 들어가보면 구경가능합니다.

Local Storage / Session Storage (key : value 형태로 문자, 숫자 데이터 저장가능)

Indexed DB (크고 많은 구조화된 데이터를 DB처럼 저장가능, 문법더러움)

Cookies (유저 로그인정보 저장공간)

Cache Storage (html css js img 파일 저장해두는 공간)

골라쓰면 되는데 우린 범용적으로 쓸 수 있는 Local Storage를 써봅시다.

Local Storage / Session Storage 는

문자, 숫자만 key : value 형태로 저장가능하고

5MB까지만 저장가능합니다. - 문자 숫자 형태이기 때문에 5mb도 많음

Local Storage는 브라우저 재접속해도 영구적으로 남아있는데 Session Storage는 브라우저 끄면 날아갑니다.

유저가 브라우저 청소하지 않는 이상 반영구적으로 데이터저장이 가능합니다.

로컬스토리지 사용법

localStorage.setItem('이름', 'kim') //자료저장하는법
localStorage.getItem('이름') //자료꺼내는법
localStorage.removeItem('이름') //자료삭제하는법
//수정하는법은 없어서 꺼내서 수정하고 다시 저장해야함

로컬스토리지에 array/object 저장하려면

array/object를 로컬스토리지에 저장하면 강제로 문자로 바꿔서 저장됩니다.

그래서 자료가 깨지고 그럴 수 있습니다.

그래서 약간 편법같은건데 array/object를 JSON으로 바꾸면 문자취급을 받기 때문에 안전하게 로컬스토리지에 저장할 수 있습니다.

JSON은 그냥 따옴표친 array/object입니다.

  1. JSON.stringify() 안에 array/object 집어넣으면 JSON으로 바꿔줍니다. 그럼 문자취급받음

  2. 그걸 localStorage에 저장하라고 코드짰습니다.

그럼 깨지지 않게 저장가능합니다.

JSON으로 저장했으니 꺼내도 JSON입니다.

그래서 꺼낸걸 다시 array/object로 바꾸고 싶으면

JSON.parse() 안에 넣으면 됩니다.

아무튼 결론은

array/object -> JSON 변환하고 싶으면 JSON.stringify()

JSON -> array/object 변환하고 싶으면 JSON.parse()

var po=[1,2,3];

var newpo = JSON.stringify(po); //array,object를 JSON으로 변환
localStorage.setItem('num',newpo) //저장
var p=localStorage.getItem('num'); //데이터꺼냄
localStorage.removeItem('cart'); //삭제
console.log(JSON.parse(p)[0]); //다시 배열로 만들어서[0]번째 출력

구매버튼누르면 localstorage에 저장(기존꺼있으면 추가로 저장)

for(let a=0; a<3; a++){
        $('.buy').eq(a).click(function(){
          var sib = $('.buy').eq(a).siblings('h5').html(); //e.target사용해도될듯 siblings는 형제요소 가져오는거
          var newsib = JSON.stringify([sib]);
          
          console.log(newsib);
          
          if(localStorage.getItem('cart') === null){ //local storage에 cart가 비어있으면
            localStorage.setItem('cart',newsib);
          }
          else{ //기존 cart라는 항목이 있으면
            var store = localStorage.getItem('cart'); //꺼내서 저장
            store = JSON.parse(store); //배열로
            localStorage.removeItem('cart'); //기존꺼삭제
            store.push(sib); //수정
            var newst = JSON.stringify(store);
            localStorage.setItem('cart', newst);
          }
        })
      }

⇒ 응용

1. 같은 상품은 중복으로 추가되지 않게하고 싶으면?

상품을 추가하기 전에 상품명이 이미 localStorage에 있는지 검사하면 되겠군요

2. 아니면 같은 상품 구매 누르면 상품 갯수가 올라가게?

상품명을 localStorage에 저장시 갯수도 저장하면 됩니다.

[ '상품명a 2개', '상품명b 4개' ... ] 이렇게 저장해도 되겠지만 여러 정보를 한 곳에 넣고 싶으면 array/object 쓰면 됩니다.

[ {title : '상품명a', num : 2}, {title : '상품명b', num : 4}  ... ] 이렇게 저장해놓으면 편리할듯요

스크롤 위치에 따라 opacity가 변하는 애니메이션 만들기

(일단 예제를 보면 스크롤을 내릴 때 카드가 1. opacity가 변하고 2. 사이즈가 줄어듭니다. 일단 1번 opacity만 구현해보도록 합시다)

여태까지 한 애니메이션은 one-way 애니메이션이었습니다.

그냥 시작화면과 최종화면만 있었을 뿐인데, 지금은 스크롤 위치에 따라 opacity가 0에서 1까지 무수히 많은 중간단계가 존재합니다.

스크롤함수 써서 위치를 찾은뒤에 코드 작성하면 될듯

$(window).scroll(function(){
    var 높이 = $(window).scrollTop();
    console.log(높이);
});

스크롤 높이가 955 → 1420될때 1→0이 되는 가변적인 값이 필요함

가변적인 값 구하는 방법(1차함수) y = ax+b

높이가 955일때 y는 1 / 높이가 1420일때 y는 0

$(window).scroll(function(){
      var scrollHeight = $(window).scrollTop();
      console.log(scrollHeight);
      //1=a*955+b  0=a*1420+b
      //955 ->1420으로 스크롤 내리면 첫째카드의 opacity를 1->0으로 서서히 변경
      //a = -1/465 b=1420/465
      var y = (-1/465) * scrollHeight + 1420/465;
      $('.card-box').eq(0).css('opacity',y);
      //955 -> 1420으로 스크롤 내리면 첫째카드의 scale을 1->0.9로 서서히 변경
      // a= -1/4650 b=1+955/4650
      var size = (-1/4650) * scrollHeight + 1+955/4650;
      $('.card-box').eq(0).css('transform',`scale(${size})`);
    })

mouse 이벤트 3개

마우스로 어떤 html 요소를 조작할 때 발동하는 이벤트가 있습니다.

mousedown (어떤 요소에 마우스버튼 눌렀을 때)

mouseup (어떤 요소에 마우스버튼 뗐을 때)

mousemove (어떤 요소위에서 마우스 이동할 때)

알아두면 유용합니다.

마우스를 100이상 움직이고 떼면 이미지가 순간이동함

마우스 떼면 2번사진으로 이동하라고 코드짰기 때문입니다.

서서히 이동하는 애니메이션 추가는 안했으니까요.

애니메이션주고 싶으면 이동할 박스에 css transition 추가하면 됩니다.

근데 문제가 있는데

이전 강의에서 기능1 만들 때 불편해서 .slide-container 박스에 있던 transition을 제거했습니다.

왜냐면 누르고 사진을 스와이프할 때는 transition이 있으면 느리게 동작했으니까요.

  • 그래서 평소엔 transition이 필요가 없는데
  • 사진에서 마우스를 떼면 transition이 필요합니다.

그럼 "마우스 떼면 잠깐 0.5초정도 transition 붙였다가 떼주세요"

라고 코드짜면되지않을까요?

예전에 배운 타이머같은거 활용하면 가능합니다. transition 붙여놓고 0.5초 후에 떼라고 하면 됩니다.

모바일은 터치 이벤트리스너 달아야함

사이트를 모바일기기로 테스트하고 싶으면 크롬개발자도구 좌상단 toggle device toolbar 버튼누르면 됩니다.

touchstart (터치시작시 발동)

touchmove (터치중일 때 계속 발동)

touchend (터치종료시 발동)

e.clientX를 e.touches[0].clientX 이걸로 바꾸면 됩니다.

왜냐면 터치는 여러 손가락으로 할 수 있어서 그 중 몇번째 손가락인지 지정해줘야합니다.

touchend 이벤트리스너에선 e.clientX 말고 e.changedTouches[0].clientX 쓰면 됩니다.

let startLoca = 0; //전역변수
      let downtrue  = false;
      $('.slide-box').eq(0).on('mousedown',function(e){
        startLoca = e.clientX; //눌렀을때 x축좌표
        downtrue = true;
      })
      
      $('.slide-box').eq(0).on('mousemove',function(e){
        
        if(downtrue == true){ //눌렀으면
          console.log(e.clientX - startLoca);
          $('.slide-container').css('transform',`translateX(${e.clientX - startLoca}px)`);
          
        }
      })

      $('.slide-box').eq(0).on('mouseup',function(e){
        downtrue = false;
        if(e.clientX - startLoca < -100){
          $('.slide-container').css('transition','all 0.5s').css('transform', 'translateX(-100vw)');
        } //jquery는 점찍고 계속 추가가능
        else{
          $('.slide-container').css('transition','all 0.5s').css('transform', 'translateX(0vw)');
        }
        setTimeout(() => { //딜레이 주고 트렌지션 없앰
          $('.slide-container').css('transition','none');
        }, 500);
          
      })
//이밑은 모바일터치
      $('.slide-box').eq(0).on('touchstart',function(e){
        startLoca = e.touches[0].clientX; //눌렀을때 x축좌표 touches[0]을 써야함
        downtrue = true;
      })
      
      $('.slide-box').eq(0).on('touchmove',function(e){
        
        if(downtrue == true){ //눌렀으면
          console.log(e.touches[0].clientX - startLoca);
          $('.slide-container').css('transform',`translateX(${e.clientX - startLoca}px)`);
          
        }
      })

      $('.slide-box').eq(0).on('touchend',function(e){
        downtrue = false;
        if(e.changedTouches[0].clientX - startLoca < -100){ //end에서는 changedtouches
          $('.slide-container').css('transition','all 0.5s').css('transform', 'translateX(-100vw)');
        }
        else{
          $('.slide-container').css('transition','all 0.5s').css('transform', 'translateX(0vw)');
        }
        setTimeout(() => { //딜레이주기
          $('.slide-container').css('transition','none');
        }, 500);
          
      })

⇒Hammer.js 같은거 가져다쓰면 조금 쉽게 기능개발이 가능합니다

switch 사용법

switch의 소괄호엔 조건식이 아니라 검사해볼 변수

그리고 코드실행을 끝내고 싶으면 break라는걸 추가해주면 됩니다. 그럼 switch 중괄호를 탈출해줍니다.

else같은걸 쓰고 싶으면 default : 추가해주면 됩니다.

switch (변수){
  case 3 :
    alert('변수가 3이네요');
    break
  case 4 :
    alert('변수가 4네요');
    break
  default : 
    alert('다 아니네')
}

if로도 모든걸 만들 수 있는데 switch를 쓰는 이유는

변수값에 따른 조건분기를 만들고 싶을 때 조금 더 간편하게 적을 수 있어서 그렇습니다.

if else보다 괄호가 적으니까요. 그 이유밖에 없습니다.

props를 통해서 state를 전송하고 전송받은 js파일에서 state를 재정의하게되면 수정시 두번수정을 거쳐야하기때문에 일반적으로 전송받은 state를 재정의하지 않음

페이지 여러개 만들기

<Route path="/detail/:id" element={ <Detail shoes={shoes}/> }/>

URL파라미터 문법 사용

path 작명할 때 /:어쩌구 이렇게 사용하면 "아무 문자"를 뜻함

이렇게 하면 해당 Route는 주소창에 /detial/ 아무거나 입력했을때 <Detail>컴포넌트를 보여줌

profile
프론트엔드 공부

0개의 댓글