반응형

제이쿼리에서는 js로 애니메이션 효과를 구현하려면 편하게 .animate 메소드를 사용할 수 있었지만

바닐라 js로 애니메이션을 구현하려고 하면 비교적 복잡한 코드로 구현이 필요하다는걸 알 수 있다.

 

애니메이션 작동 원리를 생각해보면 일정한 시간 간격으로 특정 위치로 이동하게 되는 소스를 구현해야 하는데 일정 시간을 반복하는걸 생각해보면 setInterval이나 setTimeout 를 생각할 수 있는데 두 가지 방법 보다는 requestAnimationFrame이 브라우저 측면에서는 훨씬 효율적이다.

 

1. requestAnimationFrame 란?

requestAnimationFrame는 (줄여서 RAF라고 부른다.) 브라우저에서 제공하는 메소드로 애니메이션과 같이 반복적인 작업을 수행할 때 사용한다. 

requestAnimationFrame의 특징을 설명하기 위해서는 setInterval, setTimeout 함수와 비교를 해보면 쉽게 알 수 있다.

setInterval / setTimeout requestAnimationFrame (RAF)
타이머의 주기가 정확하지 않기 때문에 애니메이션이 일정하지 않게 보이거나 끊겨 보일 수 있다. 브라우저의 리페인트 주기에 맞게 콜백 함수를 예약하기 때문에 브라우저가 화면을 갱신할 때에 맞춰 애니메이션을 실행한다. 따라서 부드러운 애니메이션을 볼 수 있다.
고정된 타이머 주기를 사용해서 타이머 기능이 필요하지 않더라도 불필요하게 작업이 되거나 배터리 소모가 된다. 브라우저에 최적화하여 애니메이션을 처리하기 때문에 사용자 디바이스의 사양이나 배터리 수명 등을 최적화 하여 실행한다.
브라우저가 비활성된 상태에서 혹은 백그라운드에서 실행을 멈추지 않고 계속해서 작업을 실행하기 때문에 불필요한 리소스를 소비하게 된다. 브라우저가 비활성된 상태이거나 백그라운드에서 실행을 할 때 애니메이션 처리를 조정하여 성능을 최적화한다. 
정해진 시간 간격에 따라 비동기적으로 작업을 예약하고 실행하기 때문에 다른 브라우저 작업과 동기화가 보장되지 않을 수 있다. 브라우저의 리페인트 주기에 맞게 콜백 함수를 실행하기 때문에 다른 브라우저 작업과 동기화 되어 실행한다.

 

그리고 

requestAnimationFrame은 초가 60프레임 정도를 구현한다.

(브라우저 상황에 따라 다를 수 있다. 하지만 최대한 구현하려한다.)

 

2. requestAnimationFrame 사용

기본적인 사용은 아래와 같다.

const callBackFnc = (timeStamp) => {
	console.log(timeStamp);  // timeStamp 값이 시간에 따라 계속 증가한다.
}

// requestAnimationFrame(콜백함수);
requestAnimationFrame(callBackFnc);

 

requestAnimationFrame(콜백함수) 로 사용하는데

이때 사용하는 콜백함수는 첫 번째 파라미터 값으로 타임 스탬프를 가져온다.

그리고 그 타임 스탬프는 시간의 경과에 따라 증가한다.

 

 

requestAnimationFrame의 간단한 사용 예시를 보자면

const testBtn = document.querySelector('.btn_test');
let testDuration = 0;

const scrollEvt = () => {
  testDuration += 50;
  const rafScroll = requestAnimationFrame(scrollEvt);
	
  window.scrollTo(0, testDuration);
  if(testDuration > 500){
    cancelAnimationFrame(rafScroll);
    testDuration = 0;
  }
}
testBtn.addEventListener('click', scrollEvt);

 

위 코드는 실무에서 쓰일 일은 없는 소스지만 간단하게 보자면

testBtn 버튼을 누르면 브라우저의 스크롤이 내가 지정한 위치만큼 이동하게 된다.

 

window.scrollTo(0, 원하는 위치);

로 지정을 하는데 testDuration이라는 반복되는 값을 만들어서 requestAnimationFrame 함수가 실행 될 때 마다

50씩 증가를 시켜 스크롤 위치에 변화를 준다.

 

그리고 증가하는 testDuration 변수 값이 500이 넘어가게 되면 requestAnimationFrame 함수의 반대 성격의  cancelAnimationframe() 함수를 사용해서 애니메이션을 멈출 수 있다.

 

(버튼 클릭 -> 50씩 스크롤 위치 증가 -> 증가된 값이 500이 넘어가면 멈춤)

 

 

3. requestAnimationFrame 활용

실무에서 쓸법한 내용으로 예시를 들자면

const duration = 500;  // 애니메이션 속도 조정
const moveEtc = (target) => {
  const targetEl = document.querySelector(target);	// 함수를 실행할 때 목적지 엘리먼트를 받아옴

  if(targetEl){
    let start;
    const targetPosition = targetEl.getBoundingClientRect().top;  // 파라미터로 받아온 target의 위치값 구하기
    const startPosition = window.scrollY;	// 애니메이션 이벤트가 발생했을 때의 현재 위치 값
    const distance = targetPosition;
    const easings = {	// 애니메이션의 easing 효과
      linear(t) {
        return t;
      },
      easeInQuad(t) {
        return t * t;
      },
      easeOutQuad(t) {
        return t * (2 - t);
      },
      easeInOutQuad(t) {
        return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
      },
      easeInCubic(t) {
        return t * t * t;
      },
      easeOutCubic(t) {
        return (--t) * t * t + 1;
      },
      easeInOutCubic(t) {
        return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
      },
      easeInQuart(t) {
        return t * t * t * t;
      },
      easeOutQuart(t) {
        return 1 - (--t) * t * t * t;
      },
      easeInOutQuart(t) {
        return t < 0.5 ? 8 * t * t * t * t : 1 - 8 * (--t) * t * t * t;
      },
      easeInQuint(t) {
        return t * t * t * t * t;
      },
      easeOutQuint(t) {
        return 1 + (--t) * t * t * t * t;
      },
      easeInOutQuint(t) {
        return t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * (--t) * t * t * t * t;
      }
    };
    const moveScroll = function(timeStamp){  // requestAnimationFrame를 적용할 함수, 첫 번째 파라미터로 타임 스탬프 받아오기
      if(start === undefined){
        start = timeStamp;  // requestAnimationFrame 함수의 타임스탬프를 기준으로 시작 시간을 지정
      }

      const elapsed = timeStamp - start;  // 시작 시간, 타임 스탬프를 이용해서 애니메이션 경과 시간을 구한다.
      const targetPos = startPosition + distance * easings.linear(elapsed / duration);  // 현재 위치, 목표 위치, easing 등으로 최종 목적지까지의 애니메이션 형태를 구성
      window.scrollTo(0, targetPos);

      if(elapsed <= duration){
        requestAnimationFrame(moveScroll);
      }else if(timeStamp >= elapsed){
        // 애니메이션 종료 후
        const targetPosFix = window.scrollY + targetEl.getBoundingClientRect().top;
        window.scrollTo(0, targetPosFix);
      }
    };
    requestAnimationFrame(moveScroll);
  }
}

 

위와 같이 작성할 수 있다.

requestAnimationFrame(콜백함수)의 콜백함수는 첫 번째 파라미터로 받아온 타임 스탬프 값(timeStamp)을 이용해서 애니메이션 시작점, 목적지, 애니메이션의 경과 시간 등을 계산한다.

 

 

 


참고

https://developer.mozilla.org/ko/docs/Web/API/window/requestAnimationFrame

https://codepen.io/pawelgrzybek/pen/ZeomJB

https://velog.io/@y_jem/react-%EC%8A%AC%EB%A1%AF-%EC%B9%B4%EC%9A%B4%ED%8A%B8-%EA%B8%B0%EB%8A%A5

 

 

 

반응형
반응형

브라우저는 html 파일을 상단 head 태그의 내용부터 순차적으로 파싱을 하게된다.

 

그래서 자바스크립트를 css를 추가하는 것 처럼 head 태그 안에서 사용하게 되면 문제가 발생하게 된다.

<!doctype html>
<html lang="ko">
  <head>
    <script>
      const btn = document.querySelector('#btn');
      btn.addEventListener('click', function(){
        console.log('Hello World');  // undefined btn 에러 출력
      })
    </script>
  </head>
  <body>
    <button id="btn">버튼</button>
  </body>
</html>

 

 

위 소스로 보았을 때 브라우저는 head태그에 있는 script를 먼저 파싱하고

body 태그 안에 있는 DOM 요소를 파싱하기 때문에 

id가 btn인 button 태그를 불러오기 전에 스크립트로 해당 태그를 불러오려고 했으니 undefined 에러가 출력이 된다.

 

위와 같은 이슈를 해결하기 위해서 몇 가지 방법이 있다.

 

1. </body> 태그 상단에 스크립트 작성

보통 스크립트 태그는 </body> 태그 위에 위치해서 사용하는 경우가 많은데

습관적으로 사용해서 의식을 못할 수도 있지만 DOM 파싱 순서 이슈 때문에 사용하게 된다.

<!doctype html>
<html lang="ko">
  <head></head>
  <body>
    <button id="btn">버튼</button>
    
    <script>
      const btn = document.querySelector('#btn');
      btn.addEventListener('click', function(){
        console.log('Hello World');  // 콘솔창에 'Hello World' 정상 출력
      })
    </script>
  </body>
</html>

 

2. load 이벤트 리스너 사용

window.onload나 DOMContentLoaded 이벤트 리스너를 사용해서 HTML이 파싱된 후에 스크립트를 실행할 수 있도록 처리할 수 있다.

  •  window.onload : HTML 파싱으로 DOM 생성, 외부 콘텐츠(이미지, css, script 등) 모든 요소가 로드된 후 발생하는 이벤트
  • DOMContentLoaded : HTML 파싱으로 DOM 생성만 한 후 발생하는 이벤트

 

*window.onload

모든 요소를 다 로드한 후 스크립트를 뿌려주다보니 페이지 내에 요소가 많을 경우 스크립트를 실행하기까지 초기 로딩 시간이 길어질 수 있다.

<!doctype html>
<html lang="ko">
  <head>
    <script>
      window.onload = function(){
        const btn = document.querySelector('#btn');
        btn.addEventListener('click', function(){
          console.log('Hello World');
        })
      }
    </script>
  </head>
  <body>
    <button id="btn">버튼</button>
  </body>
</html>

 

 

* DOMContentLoaded 

HTML DOM만 생성되고 스크립트를 실행하다보니 window.onload 보다 빠르게 실행된다.

<!doctype html>
<html lang="ko">
  <head>
    <script>
      documnet.addEventListener('DOMContentLoaded', function(){
        const btn = document.querySelector('#btn');
        btn.addEventListener('click', function(){
          console.log('Hello World');
        })
      });
    </script>
  </head>
  <body>
    <button id="btn">버튼</button>
  </body>
</html>

 

 

3. defer, async 속성으로 script 로드

HTML5에 추가된 속성으로 script태그에 defer, async 속성을 추가해서 사용한다.

  • defer : HTML 파싱과 함께 비동기로 script를 불러온다.(script 파일은 가져오지만 바로 실행하지 않는다.)
  • async : HTML 파싱과 함께 비동기로 script를 불러온다.(script 파일을 가져오면서 바로 실행한다.)
더보기

*비동기: 브라우저가 HTML 파싱을 하면서 스크립트 태그를 만났을 때하던 작업 (HTML 파싱)을 멈추지 않고 script 파일을 병렬적으로 가져온다.

defer 속성은 HTML을 파싱하면서 script 파일만 불러오고 실행은 나중에 하지만

async 속성은 HTML을 파싱하면서 script 파일을 불러옴과 동시에 실행을 같이 하고 실행하는 순간에는 HTML 파싱을 일시 정지하기 때문에 경우에 따라 에러가 발생할 수 있다.

 

그렇기 때문에 대부분의 경우에는 defer 속성을 사용하고 async는 필요에 따라 사용하면 좋을 것 같다.

 

 

 

 

 

 

 


참고

https://www.youtube.com/watch?v=7qVc4Ez0fnY&list=PLlaP-jSd-nK9LiA2n07uBhzOn9wI53xGV&index=4

 

 

반응형
반응형

특정한 영역에서 텍스트 효과를 눈에 띄게 보이게 하기 위해서 텍스트가 입력되는 형태의 타이핑 효과를 자바스크립트를 이용해서 구현할 수 있다. 

 

1. 스크립트 작성

구글링을 해보면 한 줄/여러 줄일 경우를 나눠서 타이핑 효과 스크립트를 다르게 작성하는데

작업을 하다보면 한 줄 혹은 여러 줄로 수정이 많이 발생할 수 있기 때문에 여러 줄 기준으로 스크립트를 작성해놓고 그 때 그 때 맞춰서 텍스트만 수정해주는게 좋아 여러 줄 기준으로 스크립트를 작성했다.

 

아래 소스의 변수들을 간략히 설명하면

 

- txtString : 내가 작성할 문자열 (두 줄로 입력할 경우 문자열에 \n 기호 입력)

- txtSpeed : 타이핑 속도를 조절할 숫자

- txtDelay : 타이핑 완료 후 새로 입력되는데까지 대기 시간

- txtIndex : 타이핑 되는 현재의 문자열 index

- *typeControl : 타이핑 완료 후에 타이핑을 멈추게 하기 위해 on/off 기능을 위한 변수

- *txtNow : txtIndex를 setInterval을 돌리면서 하나씩 증가시켜 txtString에 작성했던 문자열을 하나씩 받아온다. 추가로 받아오는 문자열에 \n (줄바꿈) 특수기호가 있으면 <br> 태그를 입력해준다.

const txtWrap = document.querySelector('.typing');
const txtString = '안녕하세요! \n Hello World!';
const txtSpeed = 300;
const txtDelay = 2000;
let txtIndex = 0;
let typeCotrol = true;

function typingEvent(){
    if(typeCotrol === true){  // true일 경우 타이핑 진행, false일 경우 타이핑 중지
        let txtNow = txtString[txtIndex++];
        txtWrap.innerHTML += txtNow === "\n" ? "<br>": txtNow;
        if(txtIndex >= txtString.length){  // 문자열 index와 문자열 length를 비교해 문자열 마지막을 판별
            txtIndex = 0;  // 문자 입력을 다 하면 index를 0으로 초기화
            typeCotrol = false;  // 입력 완료시 typeControl을 false로 바꿔 입력 막기
        }
    }else{
        // typeControl이 false일 경우
        clearInterval(setTyping);  // setInterval 제거 (타이핑 멈춤)
        setTimeout(function(){
            txtWrap.innerHTML = '';
            typeCotrol = true;
            setTyping = setInterval(typingEvent, txtSpeed);  // txtDelay만큼 시간 후 재 입력
        }, txtDelay)
    }
}

let setTyping = setInterval(typingEvent, txtSpeed);  // setInterval을 통한 텍스트 입력

 

기본적으로 setInterval을 통해 인덱스를 증가시켜 변수로 담아놓을 문자열을 하나씩 받아온다.

이 때 주의해야할 점은 

txtWrap.innerHTML = 문자열이 아니라

txtWrap.innerHTML += 문자열 로 작성해야 문자열이 하나씩 추가가 된다. (+=)

 

 

2. CSS 작성

단순 텍스트 입력만 구현하는 것 보다 실제 텍스트를 입력하는 것 같이 깜빡이는 커서 효과도 줄 수 있다.

.typing:after  {
  display:inline-block;
  margin-left:2px;
  vertical-align:middle;
  content:'';
  background:#000;
  width:2px;
  height:22px;
  animation:blink infinite 1s ease;
}

@keyframes blink {
  0%	{opacity:0;}
  100%	{opacity:1;}
}

 

위와 같이 가상 선택자 after를 사용해서 임의의 바(bar)를 만들고

animation을 사용해서 깜빡임 효과를 주면 보다 리얼하게 텍스트 입력 효과를 만들 수 있다.

 

 

 

예시 화면

 

See the Pen Typing by KK (@hyunjin-k) on CodePen.

 

 

반응형
반응형

자바스크립트 공부를 하거나 면접을 보다보면 호이스팅에 대해 설명을 하거나 이해를 요구할 때가 많다.

그렇기 때문에 호이스팅에 대해 완벽하게 이해를 하고 있어야 원활한 자바스크립트 사용을 할 수 있다.

 

1. 호이스팅이란?

변수나 함수를 스코프 범위 안에서 언제든지 사용할 수 있도록 하는 것을 말한다.

예시를 보면 위의 말이 어떤 내용인지 이해할 수 있다.

console.log(a);  // undefined

var a = 123;

위의 코드를 보면 console.log를 통해 a라는 변수를 불러왔는데 해당 구문 위에는 a변수 선언이 없었음에도 에러메시지가 뜨는 것이 아니라 undefined가 뜨는 것을 볼 수 있다.

var a;

console.log(a);

a = 123;

즉 실제 코드의 실행은 위의 소스와 같이 적용이 됐다는 것을 알 수 있다. a라는 변수 선언을 호이스팅하고 그 a를 console.log를 통해 불러왔으니 아직 할당 된 값이 없기 때문에 undefined가 노출이 되는 것이다.

[!] 호이스팅은 선언된 변수가 스코프 범위 내에서 최상단으로 이동해서 하단에 있는 영역에서 그 변수들을 사용할 수 있도록 해주는 것이라 이해하면 쉽다. (실제로 변수의 위치가 상단으로 이동하는 것은 아니다.)

 

하지만 변수 선언은 var만 있는 것이 아니라 let, const 변수 선언이 있다.

그리고 let과 const는 var와 같은 호이스팅의 형태를 가지고 있지 않다.

 

2. var 변수 호이스팅

위의 예시와 같이 var는 변수 선언을 스코프 내에서 호이스팅한다. (선언과 동시에 초기화)

그리고 var 변수 선언은 특징이 있는데 함수(function) 내부에서 선언한 변수는 지역변수로 호이스팅이 되지만

함수 외에 if문, for문, while문 등의 문법에서는 해당 구문 안에서 사용된 var 변수 선언들을 전역변수로 호이스팅 시켜버린다.

 

- 함수

function test(){
  var a = 123;
  console.log(a);
}

test();  // 123 출력
console.log(a);  // 에러

- for 문

for (var i = 0; i < 5; i++){
  console.log(i);
  // 1
  // 2
  // 3
  // 4
}

console.log(i); // 5

위 for문의 예시를 보면 for문 안에서 변수 i를 선언했지만 for문 밖에서 console.log를 통해 i를 호출했을 때 for문이 다 돈 후 숫자 5가 출력이 되는 것을 볼 수 있다. 즉 for문 밖에서도 for문 안에서 선언한 변수를 사용할 수 있다는 것을 알 수 있다.

 

함수를 제외한 모든 구문 및 환경에서 var로 선언한 변수는 변수 선언 자체를 최상단으로 다 올린다고 생각하면 된다. (실제로 변수들을 제일 위로 올리는 것은 아니다)

 

이처럼 함수 내부에서만 지역 변수로 사용이 되는 var 변수는

함수 레벨 스코프 변수이다.

3. let, const 변수 호이스팅

위에서 설명한 var 변수 선언과 let, const 변수 선언은 다르다. 예시를 보면 쉽게 알 수 있다.

console.log(a);  // 에러

let a = 123;

console.log(a); // 123

var였다면 위의 소스는 undefined가 출력이 됐을텐데 let으로 변수 a를 선언하면 위의 소스는 에러가 출력된다. 이게 let과 var의 호이스팅에 가장 큰 차이인데, var는 선언된 변수들을 함수를 제외하곤 호이스팅하여 모든 곳에서 사용할 수 있도록 하고 let은 변수가 선언된 위치에 도달했을 때 그 기점을 기준으로 변수를 초기화한다. const 변수도 동일한 특성을 가진다.

즉 해당 let, const 변수 선언 이후에서야 비로소 해당 변수 값을 사용할 수 있다는 뜻이다.

 

그렇다고 let이나 const가 호이스팅을 안하는 것은 아니다. 위와 같이 변수가 선언된 이후에야 그 변수를 사용할 수 있는 이유는 TDZ(Temporal Dead Zone) 영역의 특징 때문이다.

let과 const변수가 선언되기 이전에 내용들은 일시적으로 죽은 영역이 된다. 즉 사용할 수 없는 영역이 된다.

console.log(a);

//////////////// TDZ (let으로 선언한 변수 a를 사용할 수 없다)

let a = 123;

console.log(a); // 123

그리고 var와는 또 다른 특징이 있는데 var는 함수에서만 지역변수로 호이스팅되고 for, if문 과 같은 다른 구문에서는 전역 변수로 호이스팅이 되었었는데 let, const는 모든 구문에서 지역변수 단위로 호이스팅이 된다. 이를 블록 레벨 스코프라고 부른다.

각 {} 중괄호 안에 있는 블록 블록마다의 요소들에 각각의 지역 변수를 선언해준다는 뜻이다.

for(let i = 0; i < 5; i++){
  console.log(i);
}

console.log(i);  // 에러

var에서 예시로 봤던 for문을 예로 들면

for문 안에 let으로 변수 i를 선언하고 그 바깥에서 console.log로 i를 호출했을 때 for문 안에서 i를 선언했기 때문에 에러메시지가 뜨는 것을 알 수 있다.

 

만약 for문 바깥에서도 i를 사용하고 싶다면 let i 변수 선언을 for문 바깥에서 해주는 것도 방법이다.

let i;

for(i = 0; i < 5; i++){
  console.log(i);
}

console.log(i);  // 5

 

var, let, const 변수 선언에 대한 추가적인 설명은 하단 링크에도 작성해놓았다.

2020.06.03 - [Frontend/Javascript] - Javascript (자바스크립트) - 변수 선언 (var, let, const)

 

4. 함수 호이스팅

변수와 마찬가지로 함수도 호이스팅이 있다.

(단, 함수 선언문 형식으로 선언 된 함수만 해당한다. ex. function aa(){})

aa(); // 'test' 출력

function aa(){
  console.log('test');
}

위와 같이 코드를 작성한다 했을 때 aa 함수는 aa() 호출보다 아래쪽에 있어서 함수 실행이 안될 것 같지만

함수 호이스팅으로 인해 function aa(){} 부분이 스코프 내에서 언제든지 사용할 수 있게 되고 스코프 범위 안에서는 어디서든 함수를 호출하고 실행할 수 있다.

aa(); // 'test' 출력

function aa(){
  console.log('test');
  
  function bb(){
    console.log('test2');
  }
}

bb(); // 함수 내부에서 선언한 함수는 밖에서 사용할 수 없기 때문에 에러 출력
반응형
반응형

자바스크립트를 사용하면서 내가 모든 소스를 짜고 최적화와 모든 예외 상황들을 고려하여 작업을 할 수 있다면 좋겠지만 많은 리소스가 들고 또 내가 생각하지 못하는 부분들도 존재하기 때문에 간단하게 사용할 수 있는 플러그인을 많이 사용한다. 대표적인 플러그인이 슬라이더(slick, swiper 등...), 차트(chart.js, 구글차트) 등이 있다.

 

그리고 오늘 알아볼 AOS라는 플러그인도 스크롤에 따른 애니메이션 효과를 구현할 때 많이 쓰인다.

 

1. AOS 란? 

AOS는 Animate on scroll library의 약자로 스크롤을 이용한 애니메이션 효과를 구현하는 플러그인이다. 스크롤을 내리는 위치에 따라 내가 지정한 영역이 fade효과와 더불어 아래쪽에서 올라오거나 왼쪽에서 오른쪽으로 이동하거나 하는 효과를 구현할 수 있다.

AOS에서 구현하는 애니메이션 효과는 css3 transition과 transform을 사용하며 작동한다.

 

2. AOS 사용 방법

AOS를 사용하기 위해서는 aos.css 파일과 aos.js 파일이 필요하다.

https://michalsnik.github.io/aos/

aos 페이지에서 관련 내용을 CDN으로 가져올 수도 파일을 다운 받을 수도 있다.

<head>
  <link rel="stylesheet" href="https://unpkg.com/aos@2.3.1/dist/aos.css">
</head>
<body>
  <div class="wrap">
    <div class="section">
      <div data-aos="fade-up"></div>
    </div>
  </div>
  
  <script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
</body>

위와 같이 AOS css와 js 파일을 문서에 연결시킨 다음 바로 aos를 실행 시킬 수 있는 것은 아니다.

script 태그 안에 AOS의 초기화를 선언해줘야 비로소 AOS를 사용할 수 있다.

 

<head>
  <link rel="stylesheet" href="https://unpkg.com/aos@2.3.1/dist/aos.css">
</head>
<body>
  <div class="wrap">
    <div class="section">
      <div data-aos="fade-up"></div>
    </div>
  </div>
  
  <script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
  <script>
    AOS.init();  // 초기화 선언 필수
  </script>
</body>

위와 같이 aos.js 파일 뒤에 AOS.init()을 통해 AOS 초기화를 선언해줘야 aos효과를 적용할 수 있다.

 

3. AOS 사용 방법 (옵션 값)

AOS 페이지에 이미 너무 자세히 예시와 함께 나와있기 때문에 간단하게 많이 사용하는 옵션 값을 정리하자면

 

1. data-aos : aos의 기본 효과를 선언한다. (fade-up, fade-down, fade-right, fade-left, fade-up-right, zoom-in, flip-up...와 같은 방향, 효과 설정)

2. data-aos-duration : aos를 통한 애니메이션의 움직임 시간을 설정한다. (data-aos-duration이 길수록 애니메이션 효과가 느리가 나타난다.)

3. data-aos-delay :  특정 스크롤 위치에 도달했을 때 애니메이션 효과가 나타나야 하지만 스크롤 위치에 도달 후에 일정 시간동안의 지연을 주고 싶을 때 사용한다.

 

<head>
  <link rel="stylesheet" href="https://unpkg.com/aos@2.3.1/dist/aos.css">
</head>
<body>
  <div class="wrap">
    <div class="section">
      <div data-aos="fade-up"></div> <!-- fade-up 효과로 나타난다. -->
      <div data-aos="fade-down" data-aos-duration="1000"></div> <!-- fade-down 효과로 1초간의 시간동안 나타난다. -->
      <div data-aos="fade-left" data-aos-delay="2000"></div> <!-- fade-left 효과로 2초간의 시간 지연 후에 나타난다. -->
    </div>
  </div>
  
  <script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
</body>

 

 

 


참고

https://michalsnik.github.io/aos/

 

 

 

반응형
반응형

마크업을 하고 페이지를 만드는 과정에서 스크립트를 이용해 만드는 이벤트 중 스크롤, 탭과 마찬가지로 많이 사용하는게 있다면 아마 팝업이 될 것이다.

특정 버튼이나 영역을 클릭하면 그 버튼에 해당하는 내용을 가진 팝업은 웹페이지 작업시 빼놓을 수 없는 이벤트이다.

 

1. 클릭 이벤트 발생 시키기

팝업을 노출시키기 위해선 특정 버튼이나 영역을 클릭해야한다.

이 때 .addEventListener 메소드를 사용한다.

<a href="#pop_info_1" class="btn_open">팝업 열기</a>
<a href="#pop_info_2" class="btn_open">팝업 열기2</a>

<!-- 팝업1 -->
<div id="pop_info_1" class="pop_wrap" style="display:none;">
  <div class="pop_inner">
    <p class="dsc">팝업 안내문구 입니다.</p>
    <button type="button" class="btn_close">닫기</button>
  </div>
</div>

<!-- 팝업2 -->
<div id="pop_info_2" class="pop_wrap" style="display:none;">
  <div class="pop_inner">
    <p class="dsc">팝업 안내문구 입니다222.</p>
    <button type="button" class="btn_close">닫기</button>
  </div>
</div>


<script>
  var target = document.querySelectorAll('.btn_open'); // 클릭할 버튼요소를 변수 처리

  // 팝업 열기
  for(var i = 0; i < target.length; i++){
    target[i].addEventListener('click', function(){
      targetID = this.getAttribute('href');
      document.querySelector(targetID).style.display = 'block';
    });
  }
</script>

위와 같이 target이라는 팝업을 열 버튼을 변수 처리한 후에

addEventListner로 click 이벤트를 걸어준다.

 

이 때, 클릭 이벤트는 .btn_open이 하나가 아니기 때문에

for 문을 돌려 .btn_open의 갯수에 맞춰 각각 버튼에 클릭 이벤트를 걸어준다.

 

2. 버튼 클릭 후 노출 될 팝업 영역 호출하기

버튼을 클릭하는 액션은 만들었다면

버튼 클릭 액션 동작 후 팝업 영역을 노출되게 만들어야한다.

<a href="#pop_info_1" class="btn_open">팝업 열기</a>
<a href="#pop_info_2" class="btn_open">팝업 열기2</a>

<!-- 팝업1 -->
<div id="pop_info_1" class="pop_wrap" style="display:none;">
  <div class="pop_inner">
    <p class="dsc">팝업 안내문구 입니다.</p>
    <button type="button" class="btn_close">닫기</button>
  </div>
</div>

<!-- 팝업2 -->
<div id="pop_info_2" class="pop_wrap" style="display:none;">
  <div class="pop_inner">
    <p class="dsc">팝업 안내문구 입니다222.</p>
    <button type="button" class="btn_close">닫기</button>
  </div>
</div>


<script>
  var target = document.querySelectorAll('.btn_open');
  var targetID;  // 버튼 클릭시 버튼에 해당하는 팝업의 id값 담는 변수

  // 팝업 열기
  for(var i = 0; i < target.length; i++){
    target[i].addEventListener('click', function(){
      targetID = this.getAttribute('href');
      document.querySelector(targetID).style.display = 'block';
    });
  }
</script>

팝업열기 버튼을 (btn_open)을 클릭 할 때

a 태그의 href의 값과 팝업의 id값을 일치시켜줘서 접근성으로도 해당 버튼과 팝업이 연결되도록 작업하고

추가로 여러 버튼과 팝업이 나오더라도 스크립트를 추가하지 않고

a태그의 href와 팝업의 id값만 맞춘다면 언제든지 수월하게 팝업을 만들 수 있게 위와 같이 작업하였다.

(현재 클릭한 a태그의 href를 가져오는 this.getAttribute('href');)

 

3. 팝업 닫기

팝업을 열었으면 닫기 버튼의 동작도 필요하다.

팝업을 열 때와 마찬가지로 페이지에 있는 .pop_wrap 내부에 있는 .btn_close 닫기 버튼을

for문을 돌려 각각 클릭 이벤트를 걸어준 뒤

해당 버튼의 부모 노드(pop_wrap)을 찾아서 해당 div를 닫아준다.

<a href="#pop_info_1" class="btn_open">팝업 열기</a>
<a href="#pop_info_2" class="btn_open">팝업 열기2</a>

<!-- 팝업1 -->
<div id="pop_info_1" class="pop_wrap" style="display:none;">
  <div class="pop_inner">
    <p class="dsc">팝업 안내문구 입니다.</p>
    <button type="button" class="btn_close">닫기</button>
  </div>
</div>

<!-- 팝업2 -->
<div id="pop_info_2" class="pop_wrap" style="display:none;">
  <div class="pop_inner">
    <p class="dsc">팝업 안내문구 입니다222.</p>
    <button type="button" class="btn_close">닫기</button>
  </div>
</div>


<script>
  var target = document.querySelectorAll('.btn_open');
  var targetID;

  // 팝업 열기
  for(var i = 0; i < target.length; i++){
    target[i].addEventListener('click', function(){
      targetID = this.getAttribute('href');
      document.querySelector(targetID).style.display = 'block';
    });
  }
  
  // 팝업 닫기
  for(var j = 0; j < target.length; j++){
    btnPopClose[j].addEventListener('click', function(){
      this.parentNode.parentNode.style.display = 'none';
    });
  }
</script>

 

 

4. 예시 화면

버튼이 여러개, 팝업이 여러개인 예시를 통해서

왜 위와 같이 a태그의 href 속성을 통한 팝업을 작업하는지 예시를 들어보려한다.

 

 

 

 

반응형
반응형

페이지를 만들 때 탭 메뉴만큼 많이 사용하는게

스크롤과 관련된 스크립트이다.

 

특히 스크롤과 함께 특정 영역을 고정하는 식의 작업이 많이 있다.

 

1. 고정을 시작 할 영역의 좌표 값 구하기

스크롤을 통한 영역 고정을 하려면

우선, 스크롤이 어느 정도에 위치했을 때 고정할 영역을 구할 지에 대한 생각을 해야한다.

<style>
  *{margin:0; padding:0;}
  .wrap{width:1100px; margin:0 auto;}
  .header{height:200px; background:palegreen;}
  .content{position:relative;}
  .content:after{display:block; clear:both; content:'';}
  .main{float:left; margin-right:10px; background:skyblue; width:790px; height:1500px;}
  .wing{overflow:hidden;}
  .wing .inner{width:300px; height:300px; background:plum;}
  /* 스크롤시 고정 될 윙배너 css */
  .wing.fixed .inner{position:fixed; top:0;} 
</style>

<div class="wrap">
  <div class="header">Header</div>
  
  <div class="content">
    <div class="main">Main Area</div>

    <div class="wing">
      <div class="inner">Wing Banner</div>
    </div>
  </div>
</div>

위와 같은 구조로

header와 content 영역이 분리 되어 있고

content 영역 안에 스크롤시 고정 될 윙배너 영역이 있다고 가정할 때

 

표시해놓은 스크롤 기준선의 좌표값을 구해서

그 값을 윈도우 스크롤이 넘어갈 경우에 윙배너에 클래스를 추가해서 fixed 효과를 구현할 수 있다.

const content = document.querySelector('.content');

// 컨텐츠 영역부터 브라우저 최상단까지의 길이 구하기
const contentTop = content.getBoundingClientRect().top + window.scrollY;

main영역과 wing 영역을 품고 있는 content라는 변수를 선언해준 후

해당 영역의 좌표 값을 getBoundingClientRect().top 와 window.scrollY를 더해줘서 구한다.

 

*getBoundingClientRect().top는 뷰포트 상의 좌표값을 나타내고

window.scrollY는 브라우저 최상단에서 부터 현재까지 스크롤 된 좌표 값을 구한다.

 

2. 스크롤이 지정해놓은 좌표 값을 넘어갈 때 클래스 주기 (window.scrollY >= 좌표 값)

위 1번에서 구한 content의 좌표 값을 윈도우 스크롤이 넘어갈 경우

.wing에 클래스를 추가해줘서 fixed 효과를 구현할 수 있다.

const content = document.querySelector('.content');
const wing = document.querySelector('.wing');

// 컨텐츠 영역부터 브라우저 최상단까지의 길이 구하기
const contentTop = content.getBoundingClientRect().top + window.scrollY;

window.addEventListener('scroll', function(){
  if(window.scrollY >= contentTop){
    wing.classList.add('fixed');
  }else{
    wing.classList.remove('fixed');
  }
});

wing이라는 변수를 선언해줘서 클래스를 추가할 영역을 미리 담아둔다.

 

그리고 window에 addEventListener로 'scroll' 이벤트를 걸어준 후

if문을 사용해 1번에서 구한 content 영역의 위치값을 윈도우 스크롤이 넘길 경우에

미리 구해놓은 wing에 fixed 클래스를 추가해준다.

 wing.classList.add('fixed') 

 

 

 

(*CodePen 화면은 0.25x 로 축소해서 확인하시면 수월하게 예시화면을 확인할 수 있습니다.)

 

 

반응형
반응형

자바스크립트를 이용해서 작업을 하게 될 경우에

html 요소의 높이나 너비를 구해야 할 경우가 많이 있다.

 

높이나 너비를 구해야할 때 고려해야할 점이 있다면

내가 구하는 높, 너비가 padding이나 border의 값이 포함된 값인지 아닌지를 고려해서

아래의 프로퍼티들을 구분하여 사용할 수 있다.

 

1. offsetWidth, offsetHeight

높이와 너비를 구할 때 가장 많이 쓰이는 속성으로

padding, border 값을 포함한 컨텐츠의 높이를 가져온다. (margin은 포함하지 않는다.)

<style>
  .box1{
    padding:10px; 
    border:5px solid red; 
    width:250px; 
    height:300px; 
    background:skyblue; 
    overflow:auto; 
    color:#fff;
  }
</style>

<div class="box1">
  <p>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.
  </p>
</div>

<script>
  const box = document.querySelector('.box1');

  console.log(box.offsetWidth, box.offsetHeight);
  // 280 330 출력
</script>

위의 예시와 같이 border padding값과 내부 컨텐츠 높, 너비를 포함한 값이 콘솔창에 출력된다.

 

 

2. clientWidth, clientHeight

1번에서 소개한 offsetWidth, offsetHeight와 다르게 border 값은 포함하지 않는다.

즉, 컨텐츠 높, 너비과 padding 값만 적용해서 값을 계산한다.

<style>
  .box1{
    padding:10px; 
    border:5px solid red; 
    width:250px; 
    height:300px; 
    background:skyblue; 
    overflow:auto; 
    color:#fff;
  }
</style>

<div class="box1">
  <p>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.
  </p>
</div>

<script>
  const box = document.querySelector('.box1');

  console.log(box.clientWidth, box.clientHeight);
  // 253 320 출력
</script>

높이의 경우 offsetHeight값에서 border 위 아래 5px씩을 뺀 320이 출력이 되었지만

너비의 경우 border 5px씩 즉, 10px이 빠진 270px이 아닌 253이 출력되었다.

 

이유는 가로 영역에 있는 스크롤의 크기를

clientWidth 값이 계산하지 않았기 때문이다.

 

스크롤이 생기면 해당 스크롤의 크기를 뺀 나머지 영역이 너비나 높이 값이 되기 때문에

내가 .box1에 적용시킨 width:250px 값은 실제론 스크롤의 크기를 제외한 233px만 값이 적용이 된 것이다.

 

 

3. scrollWidth, scrollHeight

컨텐츠 안에 숨겨진 스크롤 영역까지 계산한다.

그리고 padding값을 포함한다.

 

예시를 보면 이해할 수 있다.

<style>
  .box1{
    padding:10px; 
    border:5px solid red; 
    width:250px; 
    height:300px; 
    background:skyblue; 
    overflow:auto; 
    color:#fff;
  }
</style>

<div class="box1">
  <p>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.<br>
    테스트용 텍스트입니다.
  </p>
</div>

<script>
  const box = document.querySelector('.box1');

  console.log(box.scrollWidth, box.scrollHeight);
  // 253 360 출력
</script>

scrollWidth값은 clientWidth 값과 동일하게 스크롤바와 border를 제외한 너비값이 들어갔고

scrollHeight의 경우 .box1 안에 있는 p태그의 총 영역까지 계산하여

360이 출력되었다.

 

 

위의 예시들 처럼

내가 단순 영역에 border를 포함하고 싶다면 offsetWidth, offsetHeight,

단순 영역에 border를 포함하지 않고 스크롤바의 크기도 고려할 필요가 없을 때clientWidth, clientHeight,

영역 내부의 컨텐츠 크기까지 (총 스크롤 크기) 고려해야 한다면 scrollWidth, scrollHeight 값을 사용하면 될 것이다.

 

 

 

 

반응형
반응형

작업을 하면서 가장 많이 구현하게 되는 기능 중 하나인 탭메뉴를 바닐라 스크립트를 사용하여 구현하려한다.

구현은 크게 2가지 방법으로 할 것이다.

 

1. 탭 버튼과 탭 컨텐츠가 한 영역으로 묶여 있는 경우

<style>
  .tab_menu{position:relative;}
  .tab_menu .list{overflow:hidden;}
  .tab_menu .list li{float:left;}
  .tab_menu .list .btn{font-size:13px; margin-right:14px;}
  .tab_menu .list .cont{display:none; position:absolute; background:#555; color:#fff; text-align:center; width:250px; height:100px; line-height:100px;}
  .tab_menu .list li.is_on .btn{font-weight:bold; color:green;}
  .tab_menu .list li.is_on .cont{display:block;}
</style>

<div class="tab_menu">
  <ul class="list">
    <li class="is_on">
      <a href="#tab1" class="btn">Tab Button1</a>
      <div id="tab1" class="cont">Tab Content1</div>
    </li>
    <li>
      <a href="#tab2" class="btn">Tab Button2</a>
      <div id="tab2" class="cont">Tab Content2</div>
    </li>
    <li>
      <a href="#tab3" class="btn">Tab Button3</a>
      <div id="tab3" class="cont">Tab Content3</div>
    </li>
  </ul>
</div>

위와 같이 .btn과 .cont가 하나의 li 태그로 묶여서 li태그를 제어하면

버튼과 컨텐츠 영역을 모두 제어할 수 있게 마크업을 하는 방법에선

특별하게 많은 스크립트가 필요하지 않다.

 

이 방법은 스크립트를 간소화 할 수 있는 장점과 동시에

마크업 구조도 접근성을 높일 수 있는 구조로 작성을 했기 때문에 좀 더 괜찮은 소스라 생각한다.

(!)
키보드 접근성을 고려하면 위의 소스처럼 버튼 영역 다음에 바로 해당 버튼과 연관 된 컨텐츠가 잡히기 때문에
접근성 측면에서 위와 같은 구조로 탭 메뉴를 작성하는 것을 추천한다.

 

<style>
  .tab_menu{position:relative;}
  .tab_menu .list{overflow:hidden;}
  .tab_menu .list li{float:left; margin-right:14px;}
  .tab_menu .list .btn{font-size:13px;}
  .tab_menu .list .cont{display:none; position:absolute; background:#555; color:#fff; text-align:center; width:250px; height:100px; line-height:100px;}
  .tab_menu .list li.is_on .btn{font-weight:bold; color:green;}
  .tab_menu .list li.is_on .cont{display:block;}
</style>

<div class="tab_menu">
  <ul class="list">
    <li class="is_on">
      <a href="#tab1" class="btn">Tab Button1</a>
      <div id="tab1" class="cont">Tab Content1</div>
    </li>
    <li>
      <a href="#tab2" class="btn">Tab Button2</a>
      <div id="tab2" class="cont">Tab Content2</div>
    </li>
    <li>
      <a href="#tab3" class="btn">Tab Button3</a>
      <div id="tab3" class="cont">Tab Content3</div>
    </li>
  </ul>
</div>

<script>
  const tabList = document.querySelectorAll('.tab_menu .list li');
  
  for(var i = 0; i < tabList.length; i++){
    tabList[i].querySelector('.btn').addEventListener('click', function(e){
      e.preventDefault();
      for(var j = 0; j < tabList.length; j++){
        tabList[j].classList.remove('is_on');
      }
      this.parentNode.classList.add('is_on');
    });
  }
</script>

위와 같이 스크립트를 작성하면 간단하게 탭을 구현할 수 있다.

 

 

1. .tab_menu .list의 li안에 있는 각 버튼에 addEventListener로 'click' 이벤트를 걸어준다. (for문을 통해)

2. 해당 이벤트에 preventDefault()로 a태그 클릭시 href로 인한 화면 이동을 막아준다.

3. 버튼을 클릭시 해당 버튼의 부모요소(li태그)에 is_on 클래스를 준다.

4. 3번 단계 전에 버튼 클릭했을 때 다른 부모요소(다른 li태그들)의 is_on 클래스를 해제시켜준다.

 

* 기존에 css로 .is_on 클래스에 의해 컨텐츠의 display가 none/block 되도록 설정해놓았기 때문에 is_on 클래스로 탭을 구현한다.

 

*버튼 (a태그)마다 href를 통해 해당 탭에 해당하는 컨텐츠의 id값과 연결시켜준 이유는
해당 버튼과 컨텐츠의 접근성을 위해 연결해놓은 것이다. (버튼과 컨텐츠를 연결)

 

 

2. 탭 버튼과 탭 컨텐츠가 다른 영역에 위치하고 있을 때

<style>
  .tab_menu{position:relative;}
  .tab_menu .list{overflow:hidden;}
  .tab_menu .list li{float:left; margin-right:14px;}
  .tab_menu .list li.is_on .btn{font-weight:bold; color:green;}
  .tab_menu .list .btn{font-size:13px;}
  .tab_menu .cont_area .cont{position:absolute; top:25px; left:0; background:#555; color:#fff; text-align:center; width:250px; height:100px; line-height:100px;}
</style>

<div class="tab_menu">
  <ul class="list">
    <li class="is_on">
      <a href="#tab1" class="btn">Tab Button1</a>
    </li>
    <li>
      <a href="#tab2" class="btn">Tab Button2</a>
    </li>
    <li>
      <a href="#tab3" class="btn">Tab Button3</a>
    </li>
  </ul>
  
  <div class="cont_area">
    <div id="tab1" class="cont">
      Tab Content1
    </div>
    <div id="tab2" class="cont">
      Tab Content2
    </div>
    <div id="tab3" class="cont">
      Tab Content3
    </div>
  </div>
</div>

작업을 하다보면 1번에서 소개한 바와 같이 버튼과 컨텐츠를 한 군데 묶기 힘든 경우도 많이 생긴다.

위의 소스와 같이 탭과 컨텐츠가 마크업상 분리 되어있을 때 사용할 수 있는 탭 구현 방법을 소개한다.

 

여기서 중요한 점은 1번과 마찬가지로 버튼(a태그)의 href 속성과
각 탭에 해당하는 컨텐츠 영역의 id값을 일치 시켜서 접근성을 높여주는 것이다.

 

<style>
  .tab_menu{position:relative;}
  .tab_menu .list{overflow:hidden;}
  .tab_menu .list li{float:left; margin-right:14px;}
  .tab_menu .list li.is_on .btn{font-weight:bold; color:green;}
  .tab_menu .list .btn{font-size:13px;}
  .tab_menu .cont_area{margin-top:10px;}
  .tab_menu .cont_area .cont{display:none; background:#555; color:#fff; text-align:center; width:250px; height:100px; line-height:100px;}
</style>

<div class="tab_menu">
  <ul class="list">
    <li class="is_on">
      <a href="#tab1" class="btn">Tab Button1</a>
    </li>
    <li>
      <a href="#tab2" class="btn">Tab Button2</a>
    </li>
    <li>
      <a href="#tab3" class="btn">Tab Button3</a>
    </li>
  </ul>
  
  <div class="cont_area">
    <div id="tab1" class="cont">
      Tab Content1
    </div>
    <div id="tab2" class="cont">
      Tab Content2
    </div>
    <div id="tab3" class="cont">
      Tab Content3
    </div>
  </div>
</div>

<script>
  const tabList = document.querySelectorAll('.tab_menu .list li');
  const contents = document.querySelectorAll('.tab_menu .cont_area .cont')
  let activeCont = ''; // 현재 활성화 된 컨텐츠 (기본:#tab1 활성화)

  for(var i = 0; i < tabList.length; i++){
    tabList[i].querySelector('.btn').addEventListener('click', function(e){
      e.preventDefault();
      for(var j = 0; j < tabList.length; j++){
        // 나머지 버튼 클래스 제거
        tabList[j].classList.remove('is_on');

        // 나머지 컨텐츠 display:none 처리
        contents[j].style.display = 'none';
      }

      // 버튼 관련 이벤트
      this.parentNode.classList.add('is_on');

      // 버튼 클릭시 컨텐츠 전환
      activeCont = this.getAttribute('href');
      document.querySelector(activeCont).style.display = 'block';
    });
  }
</script>

위와 같이 작성할 경우 아래의 화면처럼

 

 

동일한 탭 효과를 구현할 수 있다.

 

1번과 다르게 탭 버튼과 탭 컨텐츠가 따로 떨어져 있더라도

위의 소스의 activeCont 처럼 현재 활성화 할 탭 컨텐츠를 변수로 받아서

탭 버튼을 클릭할 때마다 a태그의 href 값을 받아와 해당하는 id값을 가진 컨텐츠를 보여준다.

 

 

반응형
반응형

2020/03/29 - [Frontend/Javascript] - Javascript (자바스크립트) - 요소(Element) 찾기

 

이전에 아이디, 클래스, 태그 등을 이용해

getElementById, getElementsByClassName, getElementsByTagName 의 명령어 사용과 함께

요소를 찾는 방법을 알아봤다.

 

이러한 방법 외에 제이쿼리와 유사하게 .(클래스), #(아이디) 와 같이 . # 를 이용해서 원하는 요소를

찾는 방법이 있다.

 

1. querySelector()

원하는 요소를 아이디(#), 클래스(.), 태그 값을 입력해서 하나만 찾는다.

(리스트나 반복되는 영역에서 해당 명령어를 사용하게 되면 가장 첫번째로 있는 DOM 요소를 찾는다.)

<div id="wrap">
  <ul>
    <li>리스트 1</li>
    <li>리스트 2</li>
    <li>리스트 3</li>
  </ul>
</div>

<script>
  var wrapper = document.querySelector('#wrap');
  var lists = wrapper.querySelector('li');
  
  console.log(wrapper);  // <div id="wrap"> 영역을 찾는다.
  console.log(lists);  // #wrap 하위에 있는 첫 번째 li를 찾는다.
</script>

 

2. querySelectorAll()

원하는 요소를 아이디(#), 클래스(.), 태그 값을 입력해서 여러 요소들을

Nodelist (유사배열)의 형태로 가져온다.

<div id="wrap">
  <ul>
    <li>리스트 1</li>
    <li>리스트 2</li>
    <li>리스트 3</li>
  </ul>
</div>

<script>
  var wrapper = document.querySelector('#wrap');
  var lists = wrapper.querySelectorAll('li');
  
  console.log(wrapper);  // <div id="wrap"> 영역을 찾는다.
  console.log(lists);  // #wrap 하위에 있는 모든 li를 유사 배열 형태로 가져온다.
  
  // lists → [<li>리스트 1</li>, <li>리스트 2</li>, <li>리스트 3</li>]
</script>

 

 

반응형
반응형

ES6가 나오기 전 까지 변수를 선언하는 방법은 var 선언을 통해서 할 수 있었다.

 

var 변수 선언 외에 ES6이상 부터는 let, const라는 변수 선언이 가능해졌다.

 

1. var 변수 선언의 특징

- 함수 레벨 스코프

변수의 범위가 함수의 범위 내에만 적용이 된다.

if문이나 for 문과 같은 블록 영역에 선언된 변수는 전역변수가 된다.

var test = 'test 문구';

function testFnc(){
   var test2 = 'test2 문구';
}

console.log(test);   // 'test 문구' 출력
console.log(test2);  // Uncaught ReferenceError: test2 is not defined 출력

위의 예시와 같이 함수 안에 선언한 var 변수는 함수 안에서만 사용이 가능하다.

 

 

- 변수 중복 선언 가능

변수를 이미 선언한 후에 다른 영역에서 언제든지 변수를 재선언, 중복선언이 가능하다.

이 경우 기존에 선언한 변수를 덮어버리는 경우가 되기 때문에 유의할 필요가 있다.

var test = 'test 문구';

console.log(test);   // 'test 문구' 출력

var test = '또 다른 test 문구';

console.log(test);   // '또 다른 test 문구' 출력

위의 예시를 통해 보이는 코드와 같이 test 변수를 선언 후에

다른 데이터 값으로 test 변수를 또 한번 선언하여 test 함수의 값을 변경하였다.

 

2. let, const 변수 선언의 특징

let, const 변수 선언은

es6 부터 등장한 문법으로 기존의 var 변수 선언과는 조금 다른 특징을 가지고 있다.

 

- 블록 레벨 스코프

var 변수가 함수 레벨 스코프로 함수 내에서 변수의 범위(스코프)를 잡았다면

let과 const의 변수의 범위는 블록 레벨 스코프의 형식이다.

 

즉, var 변수 선언과 다르게 if문, for문 등의 블록 영역 안에서 변수의 범위가 형성된다.

var testBool = true;

/* var 변수 선언 */
if(testBool == true){
   var test = 'test 문구';
}

console.log(test);  // 'test 문구' 출력


/* let, const 변수 선언 */
if(testBool == true){
   let test2 = 'test2 문구';
   const test3 = 'test3 문구';
}

console.log(test2);  // Uncaught ReferenceError: test2 is not defined
console.log(test3);  // Uncaught ReferenceError: test3 is not defined

위의 예시와 같이 var 변수 선언if문 안에서 사용이 되어도 전역에서 사용이 가능하고

 

let, const 변수 선언의 경우 if문과 같은 블록 영역 안에서 선언된 변수는

그 안에서만 사용이 가능하고 전역이나 다른 영역에서는 사용할 수 없다.

 

3. let 변수 선언과 const 변수 선언의 차이

위에서 let, const 변수 선언이 var 변수 선언과 다른 차이를 알아봤다면

let과 const 변수선언의 차이를 알아보려한다.

 

- let

변수 선언 후 데이터 변경만 가능, 재선언 불가능

 

- const

변수 선언 후 데이터 변경 및 재선언 불가능

 

위 내용과 같은 특징이 있다.

/* let 변수 선언 */
let test = 'test 문구';
let test2 = 'test2 문구';

let test = '또 다른 문구';
// Uncaught SyntaxError: Identifier 'test' has already been declared

test2 = '또 다른 2 문구';

console.log(test2);   // '또 다른 2 문구' 출력


/* const 변수 선언 */
const test3 = 'test3 문구';

const test3 = '또 다른 3 문구';
// Uncaught SyntaxError: Identifier 'test' has already been declared

test3 = '또 다른 3 문구';
// Uncaught SyntaxError: Identifier 'test' has already been declared

 

 

 

 

 

 


참고

https://poiemaweb.com/es6-block-scope

 

 

 

반응형
반응형

자바스크립트에서 특정 아이디(id), 클래스(class), 태그(tag)의 dom 요소를 찾기 위해서

사용되는 메소드가 있다.

 

1. 아이디(Id)값 찾기

- getElementById()

<div id="content">
   <p class="txt_red">안녕하세요</p>
   <p>반갑습니다.</p>
   <span class="txt_red">Hello world</span>
</div>

<script>
   var Content = document.getElementById('content');
   // id가 content인 요소를 가져온다.
</script>

 

2. 클래스(Class)값 찾기

- getElementsByClassName()

 : 가져온 값은 HTML Collection 객체(유사배열) 로 가져온다.

<div id="content">
   <p class="txt_red">안녕하세요</p>
   <p>반갑습니다.</p>
   <span class="txt_red">Hello world</span>
</div>

<script>
   var textRed = document.getElementsByClassName('txt_red');
   // class가 txt_red인 요소를 HTMLCollection 배열로 가져온다.
   
   console.log(textRed[0]);
   // <p class="txt_red">안녕하세요</p>
</script>

 

3. 태그(Tag) 값 찾기

- getElementsByTagName()

 : 가져온 값은 HTML Collection 객체(유사배열) 로 가져온다.

<div id="content">
   <p class="txt_red">안녕하세요</p>
   <p>반갑습니다.</p>
   <span class="txt_red">Hello world</span>
</div>

<script>
   var tag_P = document.getElementsByTagName('p');
   // document에서 p태그 요소를 HTMLCollection 배열로 가져온다.
   
   console.log(tag_P[1]);
   // <p>반갑습니다.</p>
</script>

 

 

위의 3가지 방법 외에도

querySelector, querySelectorAll과 같은 방법이 있다.

 

2020.10.12 - [Frontend/Javascript] - Javascript (자바스크립트) - 요소 찾기 (querySelector, querySelectorAll)

 

 

 

 

 

 

반응형
반응형

자바스크립트 배열에 요소들을 추가 혹은 제거할 때,

또 원하는 영역을 빼올 때 쓰는 메소드가 있다.

 

1. 배열에 요소 추가 (push(), unshift())

push, unshift는 배열에 원하는 요소들을 추가하는 메소드이다.

 

- push() : 배열의 끝에 요소 추가

- unshift() : 배열의 앞에 요소 추가

var arr01 = [1, 2, 3, 4, 5];

arr01.push(6, 7);
// arr01 = [1, 2, 3, 4, 5, 6, 7]

arr01.unshift('a', 'b', 'c');
// arr01 = ['a', 'b', 'c', 1, 2, 3, 4, 5, 6, 7]

 

2. 배열에서 요소 제거 (pop(), shift())

pop, shift는 배열의 앞이나 뒤에서 요소를 제거하는 메소드이다.

 

- pop() : 배열의 마지막 요소 제거

- shift() : 배열의 첫 번째 요소 제거

var arr02 = [1, 2, 3, 4, 5];

arr02.pop();
// arr02 = [1, 2, 3, 4]

arr02.shift();
// arr02 = [2, 3, 4]

 

3. 원하는 영역만큼 제거 (splice())

splice 메소드는 배열에서 원하는 영역만큼을 제거할 수 있다.

 

- splice(pos, length) : pos번째 부터 length까지 요소 제거

var arr03 = [1, 2, 3, 4, 5];

var splice = arr03.splice(1, 3);
// splice = [2, 3, 4]
// arr03 = [1, 5]

 

4. 원하는 영역만큼 복제하여 잘라내기 (slice())

slice 메소드는 splice 메소드와는 다르게 

원하는 영역만큼 요소를 제거하는 것이 아니라 

복제를 할 수 있다.

 

- slice(pos, lastpos) : pos(첫 위치) 부터 lastpos(마지막 위치) 만큼 잘라오기

var arr04 = [1, 2, 3, 4, 5, 6, 7];

var slice = arr04.slice(5);
// slice = [6, 7]
// arr04 = [1, 2, 3, 4, 5, 6, 7]

var slice02 = arr04.slice(2, 5);
// slice02 = [3, 4, 5]
// arr04 = [1, 2, 3, 4, 5, 6, 7]

var slice03 = arr04.slice(4, -1);
// slice03 = [5, 6]
// arr04 = [1, 2, 3, 4, 5, 6, 7]

* slice(pos) 처럼 한 숫자만 입력할 경우 시작점부터 끝까지 복제

* lastpos 값까지 복제 하는 것이 아니라 lastpos 값 바로 앞 위치 값까지 복제

* slice(pos, -lastpos) 처럼 마지막 위치 값이 -(음수) 일 경우 뒤에서 부터 계산

 

 

반응형
반응형

자바스크립트 데이터 타입 중 하나인 배열은 객체에 포함되는 개념이다.

 

1. 배열의 형태

형태는

var fruits = [
   "apple",
   "grape",
   "pineapple"
]

의 형태를 갖고있다.

 

2. 배열의 생성

배열을 만들 땐 객체와 유사하게

 

new 연산자를 사용하여 생성할 수 있고

리터럴 방식으로도 생성할 수 있다.

// new 연산자 사용
var 배열 = new Array();  // ()괄호 안에 숫자를 넣게되면 그 숫자에 맞는 빈 배열값들이 생성된다.

// var 배열 = new Array(3);
// var 배열 = [empty x 3]; // 빈 배열값 3개가 생성된다.


// 리터럴 방식
var 배열 = []

 

3. 배열에 접근 방법

배열에 접근하기 위해서는

[] 대괄호를 사용한다.

var fruits = [
   "apple",
   "grape",
   "pineapple"
]

fruits[0]  // "apple" 출력
fruits[1]  // "grape" 출력
fruits[2]  // "pineapple" 출력

fruits 라는 배열이 있다는 가정을 했을 때,

해당 배열에서 grape라는 값을 가져오고 싶다면 fruits[1]를 사용하고

원하는 값에 따라 그 순서를 맨 처음 0부터

그 자릿수로 접근할 수 있다.

 

또한,

원하는 값에 접근하여 내용을 수정할 수도 있다.

fruits[0] = "blueberry";

// fruits의 값은
// fruits = ["blueberry", "grape", "pineapple"];

 

4. 배열에 값 넣고 빼기

이미 생성된 배열에 내가 원하는 값을

추가로 넣거나 이미 들어가 있는 값을 뺄 수도 있다.

 

그 때 사용하는 함수가 push(), pop() 함수이다.

push()와 pop()은 각각 배열에 가장 뒤에 값을 추가하거나

가장 뒤에 있는 값을 제거할 수 있다.

var fruits = [
   "apple",
   "grape",
   "pineapple"
]

fruits.push("mango");

// fruits = ["apple", "grape", "pineapple", "mango"]
var fruits = [
   "apple",
   "grape",
   "pineapple"
]

fruits.pop();
// fruits = ["apple", "grape"]

fruits.pop("apple");  // pop에 빼고싶은 값을 넣으면 맨 뒤가 아닌 빼고싶은 값이 제거된다.
// fruits = ["grape"]

 

5. 배열의 길이 가져오기

배열에 저장되어 있는 값이 총 몇개가 들어가 있는지

그 길이를 가져오는 프로퍼티가 있다.

 

바로 length 이다.

var fruits = [
   "apple",
   "grape",
   "pineapple",
   "avocado"
]

fruits.length;  // 4 출력

 

 

 

반응형
반응형

객체 또한 자바스크립트에서 많이 사용되는 데이터 타입이다.

 

1. 객체의 형태

형태는

객체 = {
   속성1 : 값1,
   속성2 : 값2
}

의 형태를 갖고있다.

 

객체에 일반적인 값만 있을 경우

해당 속성을 그냥 속성, 혹은 프로퍼티라 부르고

 

객체의 속성에 함수가 들어가 있으면

그 속성은 메서드(method)라 부른다.

객체 = {
   속성(프로퍼티) : 값1,
   속성(메서드) : function(){} // 함수
}


var str = "안녕하새우";
str.length  // 문자열에서 length라는 속성의 값을 가져오는 프로퍼티
str.repeat() // 문자열에서 str에 있는 값을 반복하는 함수, 즉 메서드

 

 

2. 객체 만들기

일반적으로 객체를 만들 때는

var object = {};
var object2 = new Object();

위와 같이 {} 중괄호만 사용하여 객체를 생성하거나 (리터럴 방식)

new Object() 처럼 new 키워드를 통해 객체를 만들 수도 있다.

 

var student = {
   이름 : "박새로이",
   나이 : 45,
   키 : 235
}

그리고 위와 같이 처음 객체를 만들 때

바로 객체에 해당하는 값을 넣고 만들 수 있다.

 

3. 객체에 접근 방법

만들어진 객체에 접근을 하기 위해서는

크게 2가지 방법이 있다.

 

- .(점)을 이용한 접근

- [] 대괄호를 이용한 접근

 

이 2가지 방법의 차이는

변수를 넣을 수 있느냐 없느냐의 차이를 갖고 있다.

 

var student = {
   이름 : "박새로이",
   나이 : 45,
   키 : 235
}

예를 들어 위와 같은 student라는 객체가 있다고 했을 때,
해당 객체에 접근을 하기 위해서는

student.이름 
// or
student["이름"] 

 

의 방법으로 이름이라는 속성에 접근을 할 수 있는데

나이 라는 속성의 name을 변수로 만든다는 가정을 했을 때,

var 값 = "나이"; 

student.값   // 아무 값도 호출할 수 없다. 
student[값]  // student["나이"]로 변수값이 적용되어 값 45를 가져온다.

 

객체를 사용할 때 주로 .(점)을 사용하지만

 

위와 같이 변수를 가져와 특정 값을 가져와야 할 경우

[] 대괄호도 사용한다.

 

그리고 객체에 접근하여 객체에 저장된 값을 수정할 수도 있다.

var student = {
   이름 : "박새로이",
   나이 : 45,
   키 : 235
}

student.이름 = "벽세로이"

// console.log(student);
// {이름 : "벽세로이", 나이 : 45, 키 : 235}

 

4. 객체에 값 넣고 빼기

이미 만들어진 객체에 값을 넣기 위해서는

var student = {
   이름 : "박새로이",
   나이 : 45,
   키 : 235
}

student.주소 = "이태원";

// console.log(student);
// 출력값 : {이름 : "박새로이", 나이 : 45, 키 : 235, 주소 : "이태원"}

위와 같은 방법으로 객체명.속성 = 값 

입력해주면 원하는 값을 원하는 객체에 넣을 수 있다.

 

반대로 넣었던 값을 빼기 위해서는 delete 연산자를 사용해서 원하는 속성과 값을 제거할 수 있다.

var student = {
   이름 : "박새로이",
   나이 : 45,
   키 : 235
}

delete student.키;

// console.log(student);
// 출력값 : {이름 : "박새로이", 나이 : 45}

 

 

 

반응형
반응형

반복문을 사용하여 많이 연습하는 예제 중 하나인

별 찍기에 대해서 연습해보려 한다.

 

1. 별찍기 기본

*

**

***

****

*****

위 형태의 별 모양은 반복문을 돌려서 출력할 수 있다.

for (var i = 1; i <= 5; i++){  // 별 개수의 초기값 1; 최대 별 개수 5; 별개수는 1씩증가
   console.log("*".repeat(i)); // 문자열.repeat(n)이라는 함수로 문자열을 n번 만큼 반복할 수 있다.
}

 

또한 반대 모양인

*****

****

***

**

*

의 모양도 앞서 사용한 반복문을 응용해서 만들 수 있다.

for (var i = 5; i >= 1; i--){  // 별 개수의 초기값 5; 별 개수 최소값 1; 별개수는 1씩감소
   console.log("*".repeat(i));
}

 

2. 별찍기 응용

이제 별이 왼쪽에 붙는 형태가 아닌

오른쪽에 붙여서 별을 표현할 수 있다.

   

for(var i = 1; i <=5; i++){
   console.log(" ".repeat(5 - i) + "*".repeat(i)); 
}

// " "의 공백을 repeat()시켜줘서 별모양 앞에 여백을 준다.
// 이 때, 여백의 칸 수는 별의 수와는 다르게
// 4 -> 3 -> 2 -> 1 로 줄어들기 때문에 5 - i 를 적용시켜주었다.

반대의 경우

for(var i = 5; i >= 1; i--){
   console.log(" ".repeat(5 - i) + "*".repeat(i)); 
}

// 공백이 0 -> 1 -> 2 -> 3 -> 4 의 순서로 추가되기 때문에
// i 값이 5로 바뀐 상황에서 5 - i로 적용한다.

 

3. 별찍기 심화

이제 한 쪽으로 치우친 별이 아닌,

트리 형태, 거꾸로 된 트리 형태를 만들어 볼 것이다.

 

    *  

   ***

  *****

 *******

*********

for (var i = 1; i <= 9; i = i+2){  // 별의 최대 개수 9개; 별의 개수는 1-3-5-7-9로 2개씩 증가
   console.log(" ".repeat((9-i)/2) + "*".repeat(i))
}

// 공백의 수는 4 -> 3 -> 2 -> 1 로
// (9-i)/2 를 적용해준다.

 

거꾸로 된 트리 형태로는 아래의 소스를 적용할 수 있다.

for (var i = 9; i >= 1; i = i-+2){  // 별의 최대 개수 9개; 별의 개수는 1-3-5-7-9로 2개씩 증가
   console.log(" ".repeat((9-i)/2) + "*".repeat(i))
}

 

 

이 처럼 반복문을 사용해서 원하는 모양을 만들 수 있다.

 

 

 

반응형
반응형

자바스크립트 반복문을 사용하여 끝말잇기 게임을 만들 수 있다.

 

조건문과 반복문을 사용하고,

prompt() 라는 함수를 사용하여 사용자가 입력한 데이터를 받아서

끝말잇기 게임을 만들 수 있다.

for(var word = "첫단어"; true;){  // 처음에 입력한 단어를 만들고 true를 사용해 무한 루프를 돌린다.
   var answer = prompt(word);

   if (word[word.length-1] == answer[0]){  // word(첫단어)의 맨 마지막 글자와 대답한 데이터의 맨 첫 글자를 비교.
      word = answer;   // 위의 비교한 내용이 맞다면 내가 입력한 답이 다음 제시어(word)가 된다.
   }else {
      console.log("틀렸습니다.");
      break;   // 이 전 단어의 끝 글자와 내가 입력한 단어의 첫 글자가 다르다면 무한루프 반복문을 끝낸다.
   }
}

 

 

위와 같은 for문이 아닌 while 문을 사용해서도 끝말잇기를 만들 수 있다.

var word = "첫단어";

while (true){  // true로 하여 무한루프를 돌린다.
   var answer = prompt(word);
   if (word[word.length-1]){
      word = answer;
   }else{
      console.log("틀렸습니다.");
      break;
   }
}

 

 

 

 

반응형
반응형

자바스크립트 반복문을 연습하는 방법 중에 

가장 많이 하는 방법이 반복문을 이용해 구구단을 만드는 방법이 있다.

for (var i = 2; i <= 9; i++){
   for (var j = 2; j <= 9; j++){
      console.log(i + "*" + j + "=" + i*j);
   }
}

// 2*2=4
// 2*3=6
// 2*4=8
// ...
// 5*2=10
// 5*3=15
// 5*4=20
// ...
// 9*7=63
// 9*8=72
// 9*9=81

// 2단~9단까지의 내용이 각각 출력된다.

i는 각 단의 숫자를

j는 각 단별로 곱할 숫자를 나타낸다.

 

ex) i가 2일 때, j는 2~9까지 반복이 된다.

    2*2, 2*3 ~ 2*9로 반복된다.

    그리고 i가 2일 때의 반복이 끝나면, i는 3으로 증가하고

    j는 다시 2부터 9까지 반복이 된다.

 

 

위의 경우는 콘솔이 각각 출력이 되는데

구구단을 한 번에 출력을 하기 위해 변수를 사용하여

 

출력 될 값을 문자열에 담아서 한 번에 출력할 수도 있다.

var box = "";

for (var i = 2; i <= 9; i++){
    for (var j = 2; j <= 9; j++){
        box += i + "*" + j + "=" + i*j + "\t";   // \t 는 탭을 나타내는 인용부호
    }
    box += "\n";   // \n 은 줄바꿈을 나타내는 인용부호
}
console.log(box);


/*

2*2=4   2*3=6   2*4=8  ...  2*9=18
3*2=6   3*3=9   3*4=12 ...  3*9=27
...
...
9*2=18  9*3=27  9*4=36 ...  9*9=81

*/
// 위의 값이 한 번에 출력   

 

 

 

 

 

반응형
반응형

자바스크립트에서 조건문과 마찬가지로 중요한 개념이 반복문이다.

 

똑같은 내용을 여러번 반복해야 할 경우

console.log("반복이 필요해");
console.log("반복이 필요해");
console.log("반복이 필요해");
console.log("반복이 필요해");
console.log("반복이 필요해");
console.log("반복이 필요해");
console.log("반복이 필요해");
console.log("반복이 필요해");
console.log("반복이 필요해");
console.log("반복이 필요해");

// "반복이 필요해" 라는 문구가 10번 출력된다.

이런식으로 똑같은 내용을 여러번 복사, 붙여넣기를 해야한다.

 

하지만 자바스크립트에서는 반복문을 사용하면

복사, 붙여넣기의 반복이 아닌 단 몇 줄의 코드만으로 불필요한 복, 붙을 하지 않아도 된다.

 

1. for문

반복문 중에서도 가장 많이 사용되는 것이 for문이다.

for (초기화; 조건문; 증감){
   // 조건문 범위 내로 실행
}

for (var i = 0; i < 10; i++){
   console.log("반복이 필요해");
}

// "반복이 필요해" 10번 출력

1. 초기화 변수를 설정 (var 변수 = 초기값)

2. 반복할 조건 설정 (변수 <= 조건에 해당할 값)

3. 증가 or 감소값 설정 (변수++, 변수--, 변수*2...)

 

2. while문

var 변수 = 초기값;   // 초기값 설정
while (조건){
   // 조건이 참일 동안 계속해서 실행
   i++;  // 증,감
}


var i = 0;
while (i < 10){
   console.log("반복이 필요해");
   i++;
}

// "반복이 필요해" 10번 출력

1. 초기화 변수는 while문 이전에 설정 (var 변수 = 초기값)

2. 반복할 조건은 while(조건)에 입력

3. while문 안에 증가 or 감소값 설정

 

3. do while문

do while문은 do 영역 안에 있는 내용이 먼저 한 번 실행되고

while(조건)에 만족할 때 까지 do{}안에 있는 내용이 반복된다.

var 변수 = 초기값;  // 초기값 설정
do{
   // 우선 한 번 실행
   // while의 조건을 확인하고 참이면 계속 실행
   
} while(조건);


var i = 0;
do{
   console.log("반복이 필요해");
} while(i < 10);

// "반복이 필요해" 10번 출력

 

1. 초기화 변수는 do{} while() 문 이전에 설정 (var 변수 = 초기값)

2. 반복할 조건은 while(조건)에 입력

3. do{} 안에 증가 or 감소값 설정

 

 

 

반응형
반응형

if 조건문의 압축한 형태로 사용할 때 삼항 연산자를 사용한다.

 

var age = 20;
var LimitAge = (age >= 20) ? "가능한 나이 입니다." : "불가능한 나이 입니다.";

위와 같은 문법으로 사용할 수 있는데,

 

() 괄호 안에는 조건이 들어가고

조건 뒤에 ? 물음표 뒤엔 조건이 참일 경우에 실행될 값이,

: 콜론 뒤엔 조건이 거짓일 경우에 실행될 값이 들어간다.

 

위의 경우 age라는 변수가 20보다 크거나 같은 값이기 때문에 위의 조건은 참이 되고,

"가능한 나이 입니다." 라는 값이 적용된다.

 

위의 삼항연산자는 if문으로도 풀어서 사용이 가능하다.

var age = 20;

if (age >= 20){
   "가능한 나이 입니다."
}else{
   "불가능한 나이 입니다."
}

 

 

 

반응형
반응형

자바스크립트에서 중요하게 사용하는 문법 중에 하나인 조건문에 대하여 알아보려고 한다.

 

1. if (조건) {}

조건문(if문)의 사용법은

if (조건){
   실행
}

if 뒤에 괄호()에 조건을 입력하고

뒤에 나오는 중괄호{}에 입력한 조건이 참(true) 일 경우에 실행 될 내용을 적는다.

 

조건이 거짓일 경우 중괄호에 입력된 내용은 실행되지 않는다.

 

위의 코드 같은 경우 단순히 조건만 입력을 하면 그 조건은 참(true)이 되기에

"실행" 이라는 텍스트가 출력된다.

 

2. else if (조건) {}

단순히 한 가지의 조건이 아니라 추가로 여러개의 조건을 붙이고 싶을 때

else if(){} 문을 이용한다.

if (조건1){
   실행1
} else if(조건2){
   실행2
}

이렇게 조건문을 입력하게 되면 조건이 총 2가지가 적용 된 것이다.

 

조건1에 부합하면 실행1이 실행되고

조건2에 부합하면 실행2가 실행된다.

 

3. else{}

if와 else if에 적용한 조건 외에

그 어느 조건에도 해당하지 않는 경우에 특정 코드를 실행하기 위해서는

else{} 문을 사용한다.

if (조건1){
   실행1
} else if(조건2){
   실행2
} else{
   실행3
}

if와 else if에 걸어놓은 조건1, 조건2 그 어느것에도 부합하지 않을 경우

else{실행3}이 실행이 된다.

 

4. 조건문 예시

위에서 정리한 if, else if, else를 한 소스에서 정리해 예를 들어보자면

var color = "red";

if (color == "blue"){
   console.log("내가 원하는 색상은 blue!");
} else if(color == "red"){
   console.log("내가 원하는 색상은 red!");
} else if(color == "green"){
   console.log("내가 원하는 색상은 green!");
} else{
   console.log("내가 원하는 색상은 이 중에 없나보다...");
}

// "내가 원하는 색상은 red!" 출력

color라는 변수에 "red"라는 데이터와

두 번째 else if문의 "red" 와 일치하기 때문에 조건은 참이 되고

"내가 원하는 색상은 red!" 라는 텍스트가 출력이 된다.

 

 

반응형
반응형

자바스크립트에서 사용하는 데이터의 종류에는 크게 6가지가 있다.

 

1. 숫자 (Number)

2. 문자 (String)

3. 참, 거짓 (Boolean)

4. 객체 (Object)

5. undefinded

6. null

 

1. 각 데이터 입력 방법

- 숫자 (Number)

var number = 123;

 

- 문자 (String) : 문자형은 반드시 따옴표로 감싸줘야 한다.

var str = "String";

 

- 참, 거짓 (Boolean) : true(참)은 1, false(거짓)은 0이다.

var bool = true;  // 참
var bool = false;  // 거짓

 

- 객체 (Object)

var obj = {
   id : "abcdqbbq",
   phonenum : 01012345678
};

 

2. undefinded vs null

undefinded와 null은 둘 다 값이 없음을 나타낸다.

둘 다 아무런 값이 없는 상태인데 왜 다르게 사용이 된건지에 대한 의문이 많이 있을 것이다.

 

둘을 비교해보자면

 

undefinded는 정말로 아무런 값이 선언되지 않은 값이고

null은 명시적으로 값이 비었음을 나타내는 무의미한 '빈 값'이다.

var test;  // 변수에 값이 없으므로 undefinded 출력

var test2 = null;  // null을 값으로 넣었으므로 빈 값이지만 null 출력

그래서 null 값의 경우 특정 변수나 함수에서 일부러 임의의 빈 값을 넣을 때 사용된다.

 

3. 데이터 타입 비교

내가 사용한 데이터가 어떤 형식인지를 확인하기 위해서는

typeof 를 사용하면 된다.

그럼 해당 변수가 어떤 데이터 타입을 갖고 있는지 알 수 있다.

var num = 123;
var str = "String";
var bool = true;
var obj = {
   id : "abcdqbbq",
   phonenum : 01012345678
};
var test;
var test2 = null;

console.log(typeof num); // number 출력
console.log(typeof str); // string 출력
console.log(typeof bool); // boolean 출력
console.log(typeof obj); // object 출력
console.log(typeof test); // undefinded 출력
console.log(typeof test2); // null 출력

 

4. 데이터 타입 변환(암시적 변환)

문자면 문자 숫자면 숫자, 정해진 데이터 타입에서 특정 경우에는

데이터 타입이 변경이 된다. 

예를들면 문자 + 숫자, 숫자 + 참,거짓이 연산이 되면 

데이터 타입이 변경 된다.

var num = 123;
var str = "String";
var bool = true;

var numnum = num + num;  // 246, typeof : number
var numstr = num + str;  // "123String", typeof : string
var numbool = num + bool;  // 124, typeof : number
var strbool = bool + str;  // "trueString", typeof : string
var boolbool = bool + bool;  // 2, typeof : number

var numstrbool = num + str + bool;  // "123Stringtrue", typeof : string
var numboolstr = num + bool + str;  // "124String", typeof : string

var numboolMulti = num * bool;  // 123, typeof : number
var numstrMulti = num * str;  // NaN, typeof : number

위의 소스를 살펴보면 몇 가지 데이터 타입의 특징을 알 수 있다.

 

1. number + string = string이 된다.

2. number + boolean은 boolean의 1(true) 혹은 0(false) 에 의해 숫자와 만나면 연산이 된다.

3. boolean + string = string이 된다.

4. boolean + boolean =  number이 된다.

5. number + string + boolean = string이 되지만

   number + boolean + string은 number와 boolean의

   연산된 값과 string이 더해진 상태로 string이 된다.

6. number * boolean은 연산이 되고, number이 된다.

7. number * string은 연산이 되지 않고 NaN(Not a number)라는 값이 나타난다.

NaN (Not a number)은 숫자형(number)이다.

 

라는 몇 가지 특징이 나타난다.

여기서 유심히 살펴볼 것은 string이 더해지면 결국엔 다 string이 되고

string은 * 연산이 적용되지 않고 number 혹은 boolean은 * 연산이 적용된다는 사실을 알 수 있다.

 

5. 데이터 타입 변환(명시적 변환)

특정한 연산에 의해 자연스레 타입이 변경되는 것이 아니라

특정 함수를 사용하여 명시적으로 타입을 변환할 수 있다.

 

- String() : 숫자를 문자형으로 변환한다.

- toString() : 숫자를 문자형으로 변환한다.

- Number() : 문자형을 숫자형으로 변환한다.

- parseInt() : 문자형을 정수로 변환한다.

 

var num = 123;
var str = "123";
var str1 = "string";
var bool = true;

var numToStr = String(num);  // "123", typeof : string
var numToStr2 = num.toString();  // "123", typeof : string

var boolToNum = Number(bool);  // 123, typeof : number
var strToNum = Number(str);  // 123, typeof : number
var strToNum2 = Number(str1);  // NaN, typeof : number

var strToNum1 = parseInt(str);  // 123, typeof : number

여기서 주목할 점은 Number(str)은 숫자형으로 변경이 되었지만

Number(str1)은 NaN이 나오는 것을 볼 수 있다.

 

str의 값은 "123", str1의 값은 "string"이 담겨있었는데,

문자형이라 하여도 따옴표 안에 숫자가 담겨있었으면 Number() 함수를 이용해서

숫자형으로 변경할 수 있지만

문자가 하나라도 들어가 있으면 숫자형으로 변경할 수 없다는 사실을 알 수 있다.

 

 

 

반응형
반응형

자바스크립트를 사용하면서 가장 기본이 되고 중요한 내용 중에 하나가

바로 '변수' (variable) 이다.

 

변수는 언제든 변할 수 있는 수로

변할 수 있는 데이터를 담는 상자라고 생각하면 된다.

 

1. 변수의 선언

변수 선언 즉, 변수에 데이터를 담는 방법은

var 변수명 = 값;

의 방식으로 선언할 수 있다.

 

var이라는 문자 뒤에 선언 할 변수명을 입력하고

'=' 을 통해 데이터를 담을 수 있다.

 

ex) var test = "값";

 

또 다른 방법으로는 변수를 미리 선언한 뒤에

값을 따로 넣어주는 방법이 있다.

 

ex) var test;  // 변수선언

     test = "값"  // 값 대입

 

물론 test라는 변수는 언제 어디서든 필요할 때 마다

그 값을 바꿀 수 있다.

 

2. 변수명 규칙

변수를 선언할 때 필요한 변수명은 아무 내용이나 지정할 수는 없다.

나름대로의 변수명의 규칙이 존재한다.

 

- 변수는 대, 소문자 구분이 된다.

ex) var test 와 var Test는 다른 변수이다.

- 첫글자에 숫자 사용은 불가능 하다.

- 한글도 사용이 가능하지만 가능하면 영어로

- 숫자도 사용 가능

ex) var 123

- 특수문자는 $(달러), _(언더바) 만 사용할 수 있다. (그 외의 특수문자는 불가능)

 

 

 

반응형

+ Recent posts