웹 사이트를 사용하다보면 회원가입을 해야 서비스를 이용할 수 있는 경우들이 있습니다.

예를 들어 넷플릭스나 티빙 등의 *OTT(Over The Top)를 이용하는 경우 회원가입을 해야 영상 목록을 확인할 수 있고 또한 회원가입 후 멤버십 가입을 해야 영상 시청을 할 수 있는 경우가 대다수입니다.

* OTT(Over The Top)는 인터넷을 통해 볼 수 있는 TV 서비스를 일컫는다.

 

웹 사이트에 회원가입을 하는 경우 자신의 정보를 입력해야 회원가입을 진행할 수 있습니다.

예시 OTT 회원가입 창

회원가입 후 서비스를 이용할 수 있지만 사용자 입장에서 회원가입은 번거로운 작업일 수도 있습니다.

만약 이미 회원가입 된 사이트의 정보를 이용하여 따로 입력폼을 작성하지 않고 회원가입이 된다면 매우 편리하게 이용할 수 있을 것입니다. 

 

실제로 제가 사용하는 아래 예시 사이트에선 다양한 로그인 방법을 제공하고 있습니다.

다양한 로그인 방법

저는 이미 네이버에 회원가입이 되어 있고 "네이버로 시작하기" 버튼을 통해 네이버 정보 제공에 동의 시 따로 회원가입 폼을 작성하지 않더라도 서비스를 이용할 수 있습니다.

 

아래 내용부터는 다양한 개발환경 중 Vue.js에서 기본적인 방법으로 네이버 로그인 구현에 대해 작성하고자 합니다.

 


- 목차 -

가. NAVER Developers 세팅

나. Vue에서 로그인 코드 세팅

다. 참고자료


가. NAVER Developers 세팅

1. NAVER Developers 접속 후 우측 상단 로그인 버튼을 클릭, 로그인까지 진행합니다.

https://developers.naver.com/products/login/api/api.md

NAVER Developers 초기 접속 화면

 

2-1. 네이버 Application을 처음 이용하는 경우 약관동의, 계정 정보 등록, 애플리케이션 등록까지 진행해야 합니다.

① 상단 메뉴 중 Application을 클릭합니다.

② 이용약관을 확인 후 동의합니다.

③ 확인버튼을 누릅니다. 

2-2. 계정 정보 등록

① 휴대폰 인증을 진행합니다.

② 체크박스를 클릭합니다.

③ 위 진행 시 버튼이 활성화되고 확인을 클릭합니다.

계정 정보 등록

2-3. 애플리케이션 등록

① 자신의 애플리케이션 이름을 작성합니다. (저는 테스트로 진행하므로 임의로 작성했습니다)

② 사용 API, "선택하세요." 를 클릭하여 네이버 로그인을 클릭합니다.

애플리케이션 등록

③ 네이버 로그인을 클릭하면 제공 정보를 선택할 수 있습니다. 사용자에게 필수로 받을 정보라면 필수쪽 체크박스에 체크하고 선택적으로 받을 정보라면 추가쪽의 체크박스를 체크합니다.

 

네이버로그인 필수, 선택 정보

* 아래 이미지에서 필수에 체크된 항목은 필수 제공 항목으로 되며 추가에 체크된 항목은 추가 제공 항목에 추가됩니다.

네이버 필수 제공항목, 추가 제공 항목 예시

 

④ "환경 추가" 를 누른 뒤 "PC 웹"을 클릭합니다.

⑤ 서비스 URL을 입력합니다. (아래 이미지에서는 vue 로컬 주소를 입력했습니다)

⑥ Vue 라우터 path가 추가된 URL을 입력합니다.

⑦ "등록하기"를 클릭하면 NAVER Developers의 네이버 로그인 세팅이 완료됩니다.

환경 추가

2-4 멤버관리에 주소 추가

① 위 과정을 거치면 아래 화면이 나옵니다. 메뉴 중 멤버관리를 클릭합니다.

② 테스트할 아이디를 등록합니다. (관리자 ID 등록 시 테스트 ID에 따로 등록하지 않아도 관리자 ID로 테스트가 가능합니다)

나. Vue에서 로그인 코드 세팅

1. 터미널에서 vue 프로젝트를 생성합니다.

2. 네이버 로그인 화면 파일을 생성합니다.

3. /router/index.js, path에 /login/naver 로 라우터를 작성합니다.

// /router/index.js, 라우터 작성
{
    path: '/login/naver',
    name: 'naverLoginView',
    component: () =>
      import(
        /* webpackChunkName: "login", webpackPrefetch:true */ '../views/0_login/naverLoginView.vue'
      )
  }

4. /public/index.html, head태그 안에 script (sdk 주소가 추가된) 태그를 아래와 같이 추가합니다.

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <link rel="icon" href="<%= BASE_URL %>favicon.ico">
  <title>
    <%= htmlWebpackPlugin.options.title %>
  </title>
  <script src="https://static.nid.naver.com/js/naveridlogin_js_sdk_2.0.2.js"></script> // sdk 코드 추가
</head>

5. 아래 주소의 SDK 다운로드로 접속하면 javascript용 네이버 로그인 라이브러리의 샘플이 존재하지만 Vue를 이용하므로 아래 6번의 코드를 작성합니다.

https://developers.naver.com/docs/login/sdks/sdks.md

 

6. 네이버 로그인 View.vue 파일 template에 전체 코드를 아래와 같이 추가합니다.

- clientId 와 callbackUrl은 naver Developers의 application 메뉴에서 client Id 확인이 가능하며 콜백  URL은 설정 시 작성했던 주소를 입력합니다

(콜백 URL 예시 : http://localhost:8080/login/naver, 콜백 URL을 기억하지 못 한다면 NAVER Developers의 Application메뉴에서 확인이 가능합니다.)

// NaverLoginView.vue
<template>
  <div>
    <div id="naverIdLogin">
      <a id="naverIdLogin_loginButton" href="#" role="button"
        ><img src="https://static.nid.naver.com/oauth/big_g.PNG" width="320"
      /></a>
    </div>
    <button @click="naverLogout($event)">로그아웃</button>
  </div>
</template>
<script>
export default {
  /* eslint-disable */
  components: {},
  data() {
    return {
      nickName: '',
      naverLogin: null
    }
  },
  setup() {},
  created() {},

  mounted() {
    this.naverLogin = new window.naver.LoginWithNaverId({
      clientId: 'client Id', // client id 작성
      callbackUrl: 'http://localhost:8080/login/naver', // call back url 작성
      isPopup: true,
      loginButton: { color: 'green', type: 3, height: 60 }
    })
    /* 네아로 로그인 정보를 초기화하기 위하여 init을 호출 */
    this.naverLogin.init()

    /* 현재 로그인 상태를 확인 */
    this.naverLogin.getLoginStatus((status) => {
      if (status) {
        console.log(this.naverLogin.user.getNickName()) // 제공 정보 중 닉네임에 대한 정보 출력
        this.nickName = this.naverLogin.user.getNickName()
      }
    })
  },
  unmounted() {},
  methods: {
    naverLogout(event) {
      event.preventDefault()
      this.naverLogin.logout()
    }
  }
}
</script>

* [eslint] 오류 발생 시 mounted()안에 /* eslint-disable */을 작성하여 eslint규칙을 무시할 수 있습니다.

Eslint 오류

 

7. 정상적으로 작성되었다면 아래 네이버 로그인 버튼이 나오고 클릭 시 네이버 로그인 팝업이 등장합니다.

네이버 아이디로 로그인 버튼

8. 동의항목을 클릭하고 "동의하기"버튼을 누르면 콘솔창에 닉네임이 출력됩니다. (정상 로그인)

// mounted() 코드 일부분
console.log(this.naverLogin.user.getNickName()) // 닉네임 출력

 

9. 화면상의 로그아웃 버튼을 누르고 새로고침 시 콘솔창에 닉네임이 출력이 안 된다면 정상적으로 로그아웃된 상태가 됩니다.

 

 

10. NickName을 제외한 다른 값을 받고 싶다면 아래 주소로 접속합니다. (네이버 로그인 개발 가이드)

https://developers.naver.com/docs/login/devguide/devguide.md#3-4-5-%EC%A0%91%EA%B7%BC-%ED%86%A0%ED%81%B0%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%98%EC%97%AC-%ED%94%84%EB%A1%9C%ED%95%84-api-%ED%98%B8%EC%B6%9C%ED%95%98%EA%B8%B0

 

네이버 로그인 개발가이드 - LOGIN

네이버 로그인 개발가이드 1. 개요 4,200만 네이버 회원을 여러분의 사용자로! 네이버 회원이라면, 여러분의 사이트를 간편하게 이용할 수 있습니다. 전 국민 모두가 가지고 있는 네이버 아이디

developers.naver.com

* 출력결과 필드 항목에 response/nickname 이라면 user.getNickName() 의 형식으로 하여 값들을 받아올 수 있습니다.

console.log(this.naverLogin.user.getNickName()) // 닉네임
console.log(this.naverLogin.user.getId()) // Id
console.log(this.naverLogin.user.getName()) // 이름
console.log(this.naverLogin.user.getEmail()) // 이메일
console.log(this.naverLogin.user.getGender()) // 성별
console.log(this.naverLogin.user.getAge()) // 나이
console.log(this.naverLogin.user.getBirthday()) // 생일 (년도 제외)

 


위와 같이 서비스를 운영할 때 자체 회원가입도 필요하지만 네이버와 구글과 같은 이미 많은 사용자가 있는 플랫폼의 로그인 기능들을 포함한다면 사용자에게 더 좋은 선택지를 제공할 수 있으며 간편하게 회원가입을 진행할 수 있게 됩니다.

 

해당 글은 vue.js 환경에서 로그인 구현에 대해 알아보았습니다.

https://developers.naver.com/docs/login/devguide/devguide.md#%EB%84%A4%EC%9D%B4%EB%B2%84-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EA%B0%9C%EB%B0%9C%EA%B0%80%EC%9D%B4%EB%93%9C

 

네이버 로그인 개발가이드 - LOGIN

네이버 로그인 개발가이드 1. 개요 4,200만 네이버 회원을 여러분의 사용자로! 네이버 회원이라면, 여러분의 사이트를 간편하게 이용할 수 있습니다. 전 국민 모두가 가지고 있는 네이버 아이디

developers.naver.com

네이버 로그인에 더 필요한 정보가 있다면 위의 링크(네이버 로그인 개발가이드)를 확인하시면 됩니다.

 

저의 글을 읽어주셔서 감사합니다.


다. 참고자료

1. https://www.youtube.com/c/개발자의품격 - 부트캠프,  Vue.js 네이버 로그인

2. https://developers.naver.com/products/login/api/api.md - NAVER Developers, 네이버 로그인

3. https://developers.naver.com/docs/login/overview/overview.md - NAVER Developers, 네이버 로그인, 개요

4. https://terms.naver.com/entry.naver?docId=3579352&cid=59088&categoryId=59096 - NAVER 지식백과, OTT

먼저 vue.js란 자바스크립트 프레임워크로 SPA(Single Page Application)을 구현하는데 최적화되어 있습니다.

SPA의 장점으로 단일 페이지로 구성되어 있기 때문에 페이지 내에 메뉴를 클릭하여 이동하더라도 새로고침이 진행되지 않아 사용자에게 좋은 이용 경험을 제공해줄 수 있습니다.

즉, 하나의 페이지에서 메뉴 이동시 전체 페이지가 변경되는 것이 아니라 변경이 필요한 부분만 교체됩니다.

 

SPA의 장점도 존재하지만 처음 페이지를 접속할 때 다른 페이지들의 소스들도 한 번에 로드되기 때문에

처음 페이지 접속 시 느리다는 단점도 존재합니다.

 

vue의 라우터 방식을 통해 javaScript파일들을 미리 캐시에 담아 최적화된 웹 페이지를 제공한다면 위의 단점을 보완할 수 있게 됩니다.

 

SPA의 단점을 보완할 수 있는 vue 라우터 방식에 대해서 알아봅시다.


- 목차 -

가. 라우터 기본 구조

나. 라우터 방식 3가지

 1. app.js 파일에 포함되는 방식

 2. app.js가 아닌 별도의 js파일로 분리되는 방식

 3. webpackPrefetch:true가 포함된 방식

다. 참고자료

 


가. 라우터 기본 구조

vue를 vscode 터미널로 초기 설치 시 아래 이미지와 같은 폴더 구조로 되어있습니다.

이 중 src폴더 - router폴더 안 index.js를 클릭하셔서 확인하시면 됩니다.

vue 폴더 구조

 

index.js 파일의 routes 배열 코드는 아래와 같습니다.

// index.js 코드의 일부
import HomeView from '../views/HomeView.vue' // HomeView
const routes = [
  {
    path: '/', // URL 경로
    name: 'home', // 유일한 값
    component: HomeView // 실제 컴포넌트 경로
  }
]

1. path

App.vue의 <router-link to="경로">에서의 경로를 의미합니다. 실제로 url 경로를 입력하면 해당 페이지로 이동합니다.

만약 path : "/about" 이고 <router-link to="/about"></router-link>이라면

Home에서 주소창에 "/about" 경로를 입력하게 되면 about페이지로 이동하게 됩니다.

* router-link는 컴파일 시 a 태그로 변환됩니다. to 경로는 href 속성으로 변환됩니다.

about 페이지 주소

 

2. name

페이지가 작성되고 메뉴가 추가되는데, name은 브라우저의 독립적인 url로 접근 가능한 모든 페이지를 의미합니다. 계속 메뉴가 추가되더라도 동일한 이름이 있으면 안 되며 유일한 값만 가져야 합니다.

 

3. component

path로 이동했을 때 연결할 페이지 컴포넌트(확장자 : .vue)에 대한 정보를 입력합니다.

위의 코드에서 컴포넌트 경로가 '../views/HomeView.vue' 으로 되어 있으므로

Home 메뉴로 이동하면 해당 경로의 vue컴포넌트가 로드됩니다.


나. 라우터 방식 3가지

라우터 방식에는 3가지 방식이 있습니다.

라우터 방식에 따라 적절하게 사용된다면 전체 앱의 사용 속도를 최적화할 수 있게 됩니다.

 

1. app.js 파일에 포함되는 방식

// index.js 파일
import HomeView from '../views/HomeView.vue'
const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  }
]

1번 방식은 routes 배열 밖에 별도의 import 코드가 존재하며 routes 안 component에 import 명만 넣는 형태입니다.

 

웹 개발이 완료되고 vue 컴포넌트들이 컴파일되면 브라우저에서 이해할 수 있는 javaScript 코드들로 변환됩니다.

이때 라우터 1번 방식으로 작성된 파일들은 app.js 파일에 포함됩니다.

 

app.js는 첫 화면이 로드될 때 같이 실행되므로

사용자가 무조건 해당 페이지에 접속하는 경우 1번 방식을 사용하게 됩니다.

첫 화면 로드 시 app.js는 같이 로드

* chunk-vendors.js는 개발한 코드를 제외하고 참조하고 있는 외부 js라이브러리 스크립트 코드가 포함됩니다.

 

 

2. app.js가 아닌 별도의 js파일로 분리되는 방식

// index.js 파일
const routes = [
  {
    path: '/about',
    name: 'about',
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
  }
]

2번 방식은 routes의 component 함수 안에 import로 작성된 방식입니다.

 

/* webpackChunkName : "about" */

여기에 어떤 이름을 지정하는가에 따라 페이지에 접속했을 때 지정한 이름의 js파일로 로드됩니다. 위의 코드의 결과로는 아래와 같습니다.

about.js 로드

2번 방식은 about 페이지로 이동되는 순간에 서버로부터 about.js파일을 불러오게 됩니다.

app.js 파일과 분리되어 생성됩니다.

 

아래 3번 방식의 경우 방문할 페이지의 js소스를 미리 캐시에 담아 해당 페이지에 접속했을 때 캐시에 있는 js파일이 실행되면서 더 빠르게 화면이 로드됩니다.

 

반면 2번 방식은 이동할 페이지에 방문할 가능성이 낮거나 파일 용량이 가벼운 경우

첫 번째 페이지 접속 시 js파일을 캐시에 담아 첫 화면 로드 시간을 늘릴 이유가 없으므로 2번 방식을 사용할 수 있습니다.

 

 

3. webpackPrefetch:true가 포함된 방식

const routes = [
  {
    path: '/about',
    name: 'about',
    component: () =>
      import(
        /* webpackChunkName: "about", webpackPrefetch:true */ '../views/AboutView.vue'
      )
  }
]

3번 방식은 기존 2번 방식 webpackChunkName : "about" 오른쪽에 ,(콤마) webpackPrefetch:true가 추가된 방식입니다.

 

webpackPrefetch:true가 포함된 페이지에 접속 시 네트워크 탭에서 (prefetch cache)가 표시됩니다.

 

(prefetch cahce)

 

그리고 개발자 창 코드에서도 <head> 태그 안에 <link rel="prefetch" as="script" href="/js/about.js"> 코드를 확인할 수 있습니다.

 

link rel prefetch

link rel="prefetch"은 사용자가 요청할 가능성이 높은 페이지의 리소스를 미리 캐시에 담아 다음 요청이 빨리 이루어질 수 있도록 합니다.

 

따라서 3번 방식은 사용자가 방문할 가능성이 높거나 용량이 높은 페이지인 경우 소스들을 미리 캐시에 가져오고

해당 페이지 이동 시점에 캐시에 있는 소스를 가져와 빠르게 화면을 로드할 수 있도록 합니다.

 

* javascript는 파서 차단 리소스 입니다.

브라우저 렌더링이 진행될 때 javascript를 만나게 되면 html 페이지 파싱이 중단됩니다.

html 파싱이 중단되면 javascript 분석이 진행되는 동안 웹 화면이 빈 화면으로 유지됩니다.

이런 경우 사용자는 웹 사이트가 느리게 느껴질 수도 있습니다.

하지만 prefetch로 가져온 리소스는 캐시에 저장만 하고 스크립트를 해석하지 않기 때문에 브라우저 렌더링을 중단하지 않습니다.

따라서 서버에서 javascript 파일은 가져오지만 해석하지 않고 렌더링을 차단하지 않기 때문에 성능에 이점이 발생하게 됩니다.

 


 

라우터 방식 3가지를 정리하면

1. app.js 파일에 포함되는 방식은 사용자가 무조건 접속하게 되는 메뉴의 페이지인 경우 사용합니다.

2. app.js 파일이 아닌 별도의 js파일로 분리되는 2번 방식은 사용자가 방문할 가능성이 적거나 용량이 가벼운 경우 사용하게 됩니다.

3. webpackPrefetch:true로 미리 캐시에 담아두는 방식인 3번은 사용자가 방문할 가능성이 높거나 페이지 용량이 무거운 경우 미리 캐시에 담아 접속 시점에 페이지 로드를 빠르게 할 수 있도록 합니다.

 

위의 3가지 방식을 알맞게 사용하여 전체 페이지 설계를 진행하면 SPA 단점의 보완과 웹 페이지 로드 시간을 최적화할 수 있게 됩니다.

 


다. 참고자료

1. https://www.youtube.com/c/개발자의품격 - 부트캠프, Vue.js 라우터 이해하기

2. https://v3.router.vuejs.org/kr/guide/ - Vue Router, 시작하기

3. http://www.tcpschool.com/html-tag-attrs/link-rel - TCPSCHOOL, <link> 태그의 rel 속성

'언어 > Vue.js' 카테고리의 다른 글

[Vue.js] Vue.js에서 네이버 로그인 구현  (1) 2022.11.12

웹 스토리지는 클라이언트에서 서버로 데이터를 전송하여 실제 데이터베이스에 저장하는 것이 아닌 웹 브라우저의 저장공간에 데이터를 저장하게 됩니다.

(저장 공간 : 5mb)

 

웹 스토리지는 보안상 중요한 정보인 로그인 비밀번호 등엔 사용되지 않으며 비교적 덜 중요한 정보인 장바구니 목록이나 테마 정보 등에 사용됩니다.

 

웹 스토리지엔 localStorage와 sessionStorage가 있습니다.

각 스토리지는 키와 값으로 저장되며 사용법은 동일하지만 삭제 시점의 차이가 존재합니다.

 

웹 브라우저 저장소인 localStorage와 sessionStorage에 대해 알아보고자 합니다.

 


 

- 목차 - 

가. localStorage & sessionStorage

  1. localStorage

  2. sessionStorage

나. 사용법

  1. 기본 사용법

  2. 배열 저장법

다. 참고자료

 


 

가. localStorage & sessionStorage

1. localStorage

- 브라우저를 닫거나 종료하여도 별도로 삭제하기 전까지는 데이터가 남아있습니다.

- 로컬스토리지는 현재 사용하는 기기(PC, 스마트폰)에 저장하며 도메인별로 따로 저장됩니다.

(pc에서 로컬스토리지를 저장했다면 스마트폰에서는 해당 데이터를 확인할 수 없습니다)

(www.naver.com에 저장한 데이터는 www.daum.net에서 확인할 수 없습니다. 하지만 도메인이 같을 경우 새 창을 띄워도 동일한 데이터를 확인할 수 있습니다)

 

 

2. sessionStorage

- 브라우저를 닫거나 종료하면 데이터가 삭제됩니다.

- 세션스토리지는 탭별로 별도의 데이터를 저장하게 됩니다.

(같은 브라우저 탭 안에서만 데이터가 유지됩니다)

 

 

 

* localStorage & sessionStorage 차이점

- 아래 코드를 실행하여 로컬스토리지와 세션스토리지에 데이터를 각 하나씩 저장합니다.

// storage.html 파일
localStorage.setItem("local", "local_value")
sessionStorage.setItem("session", "session_value")

- 다른 html 파일을 생성하여 위의 데이터를 console에 출력합니다.

// storage02.html 파일
console.log(localStorage.getItem("local")) // local_value 출력
console.log(sessionStorage.getItem("session")) // session_value 출력

실제 콘솔창

위 이미지처럼 실제로 콘솔창에는 2개의 값이 출력됩니다.

 

- 새 탭을 열어 위와 동일한 주소로 접속합니다.

session 값은 null로 출력

- 그 결과 다른 탭에서 sessionStorage 값은 null(값 없음)이 출력되고 localStorage 값만 출력되고 있습니다.

- 브라우저를 완전히 종료하고 다시 실행해도 위와 같은 결과가 도출됩니다.

 

 


 

나. 사용법

1. 기본사용법

1. 먼저 localStorage와 sessionStorage는 html5부터 지원하기 때문에 아래 코드를 통해 지원여부를 확인할 수 있습니다.

if (typeof (Storage) !== "undefined") { // 스토리지 지원 여부 확인
      // typeof(Storage)가 undefined가 아니면 웹 스토리지를 지원합니다.
    } else {
      // 웹 스토리지를 지원하지 않습니다.
    }

 

 

 

2. localStorage(sessionStorage)에 데이터 추가하기

* localStorage와 sessionStorage는 사용법이 동일하기 때문에 코드 예제엔 localStorage가 사용되지만 sessionStorage를 사용시 이름만 바꿔서 사용하시면 됩니다.

// 첫 번째 파라미터 사용할 키 명, 두 번째 파라미터 값
localStorage.setItem("key", "value");

localStorage객체의 내장함수인 setItem()을 사용하여

첫 번째 파라미터로 키 명을 작성하고

두 번째 파라미터로 값을 작성합니다.

 

 

 

3. localStorage(sessionStorage)에 데이터 가져오기

console.log(localStorage.getItem("key")) // value가 콘솔에 출력됩니다.

localStorage객체의 내장함수인 getItem("키 명")을 사용합니다.

파라미터로 setItem()으로 추가한 데이터의 키 명을 입력합니다.

 

 

* setItem()으로 추가한 데이터를 console.log()로 확인하지 않아도 브라우저에서 확인이 가능한 방법

- 로컬스토리지를 저장한 브라우저를 실행합니다. (vscode의 라이브서버 확장기능에서도 확인할 수 있습니다)

- 키보드 상단에 F12키를 누르시거나 마우스 오른쪽 클릭 후 검사 항목을 클릭합니다.

 

마우스 오른쪽 클릭 후 검사 항목 클릭

 

- 검사를 클릭하면 개발자도구창이 실행됩니다.

개발자 도구창을 가로로 늘리시고 상단에 응용 프로그램을 클릭합니다.

그리고 좌측에 로컬 저장소와 세션저장소를 확인할 수 있습니다.

 

개발자 도구의 응용 프로그램 및 로컬, 세션 저장소 확인

 

- 로컬 저장소 좌측에 ▶ 을 클릭하면 아래 저장된 주소가 나오고 주소를 클릭하면

아래 이미지와 같이 setItem("key, "value")으로 저장한 데이터를 확인할 수 있습니다.

 

웹 브라우저에서 로컬 스토리지 키 값 확인 가능

 

 

 

 

 

4. localStorage(sessionStorage)에 데이터 삭제하기

// 키가 key인 데이터를 삭제합니다.
localStorage.removeItem("key");

localStorage객체의 내장함수인 removeItem("키 명")을 사용합니다.

파라미터로 setItem()으로 추가한 데이터의 키 명을 입력합니다.

실제로 실행한 결과 아래 이미지와 같이 추가한 key 데이터가 삭제된 모습을 볼 수 있습니다.

 

로컬 스토리지 키 값이 비어있는 모습

 

 

 

5. localStorage(sessionStorage)에 모든 데이터 삭제하기

// 로컬 스토리지 내의 모든 데이터를 삭제합니다.
localStorage.clear()

localStorage객체의 내장함수인 clear()를 사용합니다.

실제로 삭제되는지 확인하기 위해 아래 별도의 데이터를 추가하였습니다.

 

clear()를 테스트하기 위해 별도의 데이터 추가

 

그리고 clear() 실행 시 아래와 같이 모든 데이터가 한 번에 삭제되었습니다.

 

모든 데이터가 삭제된 모습

 

 

 

 

2. 배열 저장법

로컬스토리지와 세션스토리지는 키 값으로 문자열만 저장되기 때문에 바로 배열을 넣게되면 배열이 아닌 문자열로 저장됩니다.

// 두 번째 파리미터로 배열을 추가했으나 문자열로만 추가됩니다.
localStorage.setItem('key', ["apple", "banana", "pear"])

배열로 저장했으나 문자열로 저장된 모습

두 번째 파라미터를 배열로 지정했으나 값에는 위 이미지와 같이 배열이 아닌 문자열로 추가됩니다.

 

 

 

* JSON.stringify() & JSON.parse() 이용하기

let arr = ["apple", "banana", "pear"]
localStorage.setItem('key', JSON.stringify(arr)) // ["apple", "banana", "pear"]로 추가

값에 배열로 추가가 된 모습

setItem() 내장함수의 두 번째 파라미터로 JSON.stringify()를 이용해 문자열로 변환 후 전달 시 배열 형태로 저장됩니다.

 

하지만 getItem()으로 가져올 때 그냥 가져오게 되면 배열이 아닌 문자열 형태로 출력됩니다.

따라서 가져올 때 JSON.parse()를 이용해 가져오게 되면 배열로 사용할 수 있게 됩니다.

console.log(JSON.parse(localStorage.getItem("key"))) // 배열 형태로 출력

실제 콘솔창에 배열로 출력된 모습

위 코드를 실행 시 콘솔 창에 배열로 출력된 모습을 확인할 수 있습니다.

 


웹 브라우저 저장소인 localStorage와 sessionStorage를 알아보았습니다.

둘의 가장 큰 차이점은 삭제 시점에 있었는데요,

localStorage는 삭제하기 전까지 웹 브라우저를 종료하여도 데이터가 남아있으며 동일한 도메인 내에서는 데이터를 공유할 수 있음을 알 수 있었습니다.

하지만 sessionStorage는 동일한 도메인에서도 새 탭에선 데이터를 공유할 수 없으며 브라우저를 종료하면 데이터가 삭제됨을 알 수 있었습니다.

 

둘의 차이점을 확인하여 적절한 상황에 웹 브라우저 저장소를 사용하는 것이 중요하다고 생각되어 집니다.

여기까지 저의 글을 읽어주셔서 감사합니다.


 

3. 참고자료

1. https://www.youtube.com/watch?v=nmLwQyWzkXU - 개발자의 품격, 자바스크립트 기초-localStorage와 sessionStorage 이해하기

2. http://www.tcpschool.com/html/html5_api_webStorage - Web Storage

웹 개발에서 프론트엔드 개발자와 벡엔드개발자는 서로  협업하여 일을 진행합니다.

프론트엔드에서는 화면을 구성하기 위해 서버에서 데이터가 오면 그 데이터를 가지고 화면에 출력하게 됩니다.

 

하지만 프론트엔드와 벡엔드가 개발하는 과정에서 속도 차이가 발생할 수 있으며 벡엔드에서 API 주소가 올 때까지 프론트는 대기하게 되는 상황에 직면할 수도 있습니다.

 

이때 가상의 웹 서버를 구동할 수 있게하는 오픈 소스 모듈인 json-server를 이용하면 위 문제를 해소할 수 있게 됩니다.

json-server를 사용하게 되면 실제 서버가 없더라도 실제와 굉장히 유사한 서버를 사용할 수 있게되어 미리 코드를 구현할 수 있게 됩니다.

프론트엔드에서 중요하게 사용되는 json-server 사용하는 방법에 대해서 알아보고자 합니다.

 

- 목차 - 

가. json-server 설치 방법

나. json-server 사용 방법

 * fetch api

다. 참고자료

 


 

가. json-server설치 방법

* json-server를 설치하기 위해 아래 글은 visual studio code 에디터를 사용합니다. 아래 사이트에서 미리 다운로드 부탁드립니다.

https://code.visualstudio.com/

 

Visual Studio Code - Code Editing. Redefined

Visual Studio Code is a code editor redefined and optimized for building and debugging modern web and cloud applications.  Visual Studio Code is free and available on your favorite platform - Linux, macOS, and Windows.

code.visualstudio.com

 

1. 프로젝트 폴더를 만들고 폴더 안에 json-server 설치할 폴더까지 생성합니다.

프로젝트 폴더 생성
json-server 설치할 폴더 생성

 

 

 

2. visual studio code를 실행하고 Open Folder 버튼을 눌러 프로젝트 폴더를 불러옵니다.

 

visual studio code를 실행 후 Open Folder 버튼을 클릭

 

 

 

 

3. 상단 메뉴 Terminal에서 new Terminal을 클릭합니다.

 

상단 메뉴 Terminal - New Terminal

 

4. 클릭하면 에디터 아래에 Terminal창이 열립니다. 설치폴더로 이동하기 위해 cd json-server를 입력하고 엔터키를 누릅니다.

* cd는 change directory를 뜻하는 명령어로 현재 작업 폴더를 변경하는 명령어 입니다.

cd json-server 입력 후 엔터

 

 

5. 아래 json server 주소로 접속합니다.

https://www.npmjs.com/package/json-server

 

json-server

Get a full fake REST API with zero coding in less than 30 seconds. Latest version: 0.17.0, last published: a year ago. Start using json-server in your project by running `npm i json-server`. There are 291 other projects in the npm registry using json-serve

www.npmjs.com

 

 

 

6. 스크롤을 내리다보면 Getting started가 있으며 Install JSON Server의 코드를 복사합니다.

* 맥 사용자는 복사한 코드 앞에 sudo를 추가 입력하여 설치합니다.

# 윈도우 사용자
npm install -g json-server

# 맥 사용자
sudo npm install -g json-server

 

7. 에디터로 돌아와서 Terminal창에 복사한 코드를 붙여넣기하고 엔터키를 누릅니다.

 

 

 

8. 설치가 완료되면 json-server 사이트의 설명대로 db.json 파일을 생성합니다.

* 화살표로 가리키는 아이콘이 새파일을 생성하는 아이콘이므로 클릭 후 db.json을 입력하고 엔터를 누르면 파일이 생성됩니다.

db.json 파일 추가

.

 

 

 

9. 그리고 아래 예시 코드를 복사해서 db.json파일에 붙여넣고 저장합니다.

 

{
  "posts": [
    { "id": 1, "title": "json-server", "author": "typicode" }
  ],
  "comments": [
    { "id": 1, "body": "some comment", "postId": 1 }
  ],
  "profile": { "name": "typicode" }
}

 

 

10. 마지막으로 json-server를 구동시키기 위해 터미널에 json-server --watch db.json 명령어를 입력하고 엔터키를 누릅니다.

json 서버 구동 명령어

json-server --watch db.json

 

 

11. 엔터키를 누르고 잠시 뒤에 아래 코드가 나오면 구동까지 완료된 상태입니다.

* http://localhost:3000/posts 는 해당 db.json파일 안 데이터 posts에 접근할 수 있는 리소스 주소를 나타냅니다.

\{^_^}/ hi!

  Loading db.json
  Done

  Resources
  http://localhost:3000/posts // 접근가능한 리소스 주소
  http://localhost:3000/comments // 접근가능한 리소스 주소
  http://localhost:3000/profile // 접근가능한 리소스 주소

  Home
  http://localhost:3000

  Type s + enter at any time to create a snapshot of the database
  Watching...

http://localhost:3000/posts는 db.json에서 posts에 접근하는 리소스 주소 입니다.

 

* 위 주소를 javaScript로 활용하여 데이터 조회, 생성, 수정, 삭제가 가능합니다.

* 위의 db.json파일의 데이터들은 원하는대로 수정해서 테스트할 수 있습니다.

* json-server로 미리 구현 후 최종적으로 벡엔드 api가 완료되면 주소부분만 수정하여 대기시간 없이 구현할 수 있게 됩니다.

 

 


 

나. json-server 사용방법

위에서 json-server를 설치하여 구동까지 완료되었습니다.
아래부터는 json-server를 구동한 상태에서 데이터 조회, 생성, 수정, 삭제를 알아보고자 합니다.

 

fetch api

데이터를 조작하기 위해 다양한 방법 중 fetch api를 사용하고자 합니다.

 

fetch api를 이용하면 필요할 때 서버에 요청을 보내고 정보를 받아오는 일을 할 수 있습니다.
- 첫 번째 파라미터 : 접근할 URL
- 두 번째 파라미터 : 옵션

 

데이터 조회

fetch('http://localhost:3000/posts')
  .then((response) => response.json())
  .then((data) => console.log(data));

위 코드는 fetch api를 이용해 데이터를 조회하는 코드 입니다.

 

- fetch('http://localhost:3000/posts')
데이터를 정상적으로 받아오면 then()안의 함수가 실행됩니다.

- .then((response) => response.json())
fetch는 promise를 포함하고 있어 서버로 받은 응답을 response 파라미터로 받습니다.

response 안에는 응답코드, 응답메시지 등의 정보를 담고 있습니다.


- response.json()은 받아온 json 데이터를 사용할 수 있도록 객체 형태로 변환합니다.
(JSON.parse()와 동일한 기능입니다)

- .then((json) => console.log(json));
json 데이터를 마지막 then()에서 출력합니다.

 

fetch api로 db.json의 posts데이터를 조회한 결과 콘솔창

posts 리소스를 조회한 결과, 위 콘솔창의 0번 인덱스와, 아래 db.json파일의 posts와 동일한 것을 확인할 수 있습니다.

fetch api로 posts데이터를 조회한 결과 db.json의 posts의 데이터와 동일

 

 

데이터 생성

function postData() {
      const data = { title: "javaScript", author: "Mike" }; // 생성할 코드
      fetch("http://localhost:3000/posts", { // 첫 번째 파라미터 : 주소, 두 번째 파라미터 : 옵션
        method: "POST", // 데이터 생성 method : POST
        body: JSON.stringify(data), // body 보낼 데이터 입력 (문자열로 변환 후 전송)
        headers: headers = {
          "content-type": "application/json;charset=UTF-8"  // 데이터 타입 : json, 인코딩 방식 : UTF-8
        },
      }).then((response) => response.json()).then((json) => console.log(json))
    }

위 코드는 fetch api를 이용해 데이터를 생성하는 코드 입니다.

 

- 생성할 데이터를 미리 변수에 담아 놓습니다. (const data = { title: "javaScript", author: "Mike" };)
- 첫 번째 파라미터에 주소가 입력되고,
데이터를 생성하기 위해 두 번째 파라미터로 옵션을 입력해야 합니다.

- 데이터를 생성하기 위해서는 method에 POST를 입력합니다.
- body에는 보낼 데이터를 입력합니다.
- 데이터를 전송하려면 JSON.stringify(data)를 이용해 문자열로 변환 후 전송합니다.
- 생성할 데이터 타입이 json이므로 headers에는 content-type이 application/json이 되고 인코딩 방식은 전 세계 언어를 지원하는 charset=UTF-8을 사용합니다.

 

데이터 생성 결과 콘솔창 : 인덱스 번호 1번이 생성되었습니다.

실제로 코드 실행 시 1번 인덱스에 데이터가 생성된 것을 확인할 수 있습니다.

 

데이터 수정

function putData() {
      const data = { title: "fetch api", author: "john" }; // 수정할 데이터를 변수에 담아놓습니다.
      fetch("http://localhost:3000/posts/2", { // 주소 끝에 변경할 id 값을 입력합니다.
        method: "PUT", // 데이터 수정시 method에 PUT을 입력합니다.
        body: JSON.stringify(data), // 데이터 전달 시 문자열로 변경 후 전송합니다.
        headers: headers = {
          "content-type": "application/json;charset=UTF-8"
        }
      }).then(response => response.json()).then(json => console.log(json))
    }

위 코드는 fetch api를 이용해 데이터를 수정하는 코드 입니다.

 

 

- 수정할 데이터를 미리 변수에 담아 놓습니다. (const data = { title: "fetch api", author: "john" };)
- fetch("http://localhost:3000/posts/2" 수정할 id 값을 주소 마지막에 입력합니다.
- 데이터를 수정하기 위해서 method에 PUT를 입력합니다.

 

id 값이 2번인 데이터가 수정된 콘솔창

실제로 코드 실행 시 id값이 2인 title 값이 javaScript에서 fetch api로 변경되었고 author 값이 Mike에서 john으로 변경된 것을 확인할 수 있습니다.

 

 

데이터 삭제

function deleteData() {
      fetch("http://localhost:3000/posts/2", { // 삭제할 id 값을 입력합니다.
        method: "DELETE" // 삭제를 위해 method는 DELETE를 입력합니다.
      }).then(response => response.json()).then(json => console.log(json))
    }

위 코드는 fetch api를 이용해 데이터를 삭제하는 코드 입니다.

 

- fetch("http://localhost:3000/posts/2" 삭제할 id 값을 주소 마지막에 입력합니다.
- 데이터를 삭제하기 위해서 method에 DELETE를 입력합니다.

 

id값이 2인 데이터가 삭제된 콘솔창

실제로 코드 실행 시 id값이 2인 데이터가 삭제된 모습을 확인할 수 있습니다.

 

 


여기까지 json-server를 설치하고 fetch api를 이용해 간단한 데이터 조작까지 알아보았습니다.
실제 서버 api 주소가 없더라도 가상 서버인 json-server를 이용해 미리 코드를 구현하고 실제 api 주소를 전달받으면 주소만 교체하여 일을 효율적으로 처리할 수 있게 됩니다.

여기까지 저의 글을 읽어주셔서 감사합니다.

 


 

다. 참고자료

1. https://www.youtube.com/watch?v=NMJiqIadnMc - 개발자의 품격, 프론트엔드 개발자가 꼭 알아야하는 가짜 서버(json-server) 사용하기
2. https://ko.javascript.info/fetch - javascript.info, fetch

 

 

 

 

 

 

 

본 글은 Array(배열) 객체에서 사용할 수 있는 내장 함수의 종류와 사용법에 대해서 알아보고자 합니다.

서버에서 데이터를 클라이언트로 전송 받고 이 데이터를 통해 화면에 구현하는 경우가 많이 발생 합니다.

array 객체 내장 함수들을 알고 있다면 데이터를 적절하게 가공하여 화면에 나타낼 수 있습니다.

 

- 목차 - 

가. Array(배열)의 의미

나. Array(배열) 객체 내장 함수

 1. toString() 함수

 2. join() 함수

 3. pop() 함수

 4. push() 함수

 5. shift() 함수

 6. unshift() 함수

 7. splice() 함수

 8. concat() 함수

 9. slice() 함수

 10. sort() 함수

 11. filter() 함수

 12. map() 함수

 13. reduce() 함수

다. 참고자료

 

 

 

 

가. Array(배열)의 의미

배열 객체의 내장함수를 알아보기 전에 배열의 의미와 특징을 간단하게 알아봅시다.

 

배열은 하나 이상의 데이터를 담을 수 있으며 해당 데이터는 어떤 데이터 타입도 할당할 수 있습니다.

const array = [12, "abc", true, false, [], {}, undefined, null, Symbol]

 

어떤 데이터 타입도 담을 수 있는 배열

 

 

배열의 각 요소에는 순서가 있어서 데이터에 접근하고 수정할 수 있습니다.

배열의 순서는 0부터 시작합니다. 위의 사진에서도 0번 째 요소는 12를 명시하고 있습니다.

 

const array = [12, "abc", true, false, [], {}, undefined, null, Symbol]
console.log(array[2]) // true

 

위의 코드와 같이 배열에서 요소를 가져올 때는 배열 변수명에 대괄호를 사용합니다.

그리고 대괄호 안에 가져올 요소의 순번을 작성합니다.

배열 요소의 순서는 0부터 시작하므로 array[2]인 경우 true가 콘솔에 표시됩니다.

 


 

나. Array(배열) 객체 내장 함수

내장 함수는 자바스크립트에서 기본적으로 제공하는 함수를 의미합니다.

그렇기에 내장 함수를 잘 알고 있다면 이미 있는 기능을 활용하여 코딩할 수 있게 됩니다.

아래 글 부터 배열에서 사용할 수 있는 내장 함수에 대해서 알아봅시다.

 

1. toString() 함수

- 배열의 각 요소를 하나의 문자열로 반환하며 이때 각 요소는 ,(콤마)로 구분됩니다.

 

// toString() 함수
const fruits = ["apple", "banana", "pear", "orange", "melon"]
console.log(fruits.toString()) // apple,banana,pear,orange,melon

 

console에 표시된 toString() 함수 결과

 

 

 

2. join() 함수

- 첫 번째 파라미터로 전달된 문자가 각 요소 사이의 구분자로 사용됩니다.

- toString() 함수의 경우 ,(콤마)만 구분자로 사용되지만 join() 함수는 어떤 문자든 사용할 수 있습니다.

 

// join() 함수
const fruits = ["apple", "banana", "pear", "orange", "melon"]
console.log(fruits.join(" & ")) // apple & banana & pear & orange & melon
console.log(fruits.join("")) // applebananapearorangemelon

 

console에 표시된 join() 함수 결과

 

* join() 함수의 활용법

let drinkList = [ // 서버에서 전달받은 데이터로 가정
      {name: "콜라", price: 1400},
      {name: "칠성사이다", price: 1300},
      {name: "아메리카노", price: 1200},
      {name: "바나나우유", price: 1500},
      {name: "초코우유", price: 1000}
    ]

    const trElem = [] // 빈 배열 생성
    drinkList.forEach(function (drink) { // forEach 함수로 배열 순회
      trElem.push("<tr>") 
      trElem.push("<td>" + drink.name + "</td>")
      trElem.push("<td>" + drink.price + "</td>")
      trElem.push("</tr>") // push() 함수로 빈 배열에 요소 추가
    })

    document.getElementById('tbody_elem').innerHTML = trElem.join("")
    // 배열 join()함수를 통해 html 요소에 삽입

서버에서 전달 받은 데이터를 html 요소에 삽입할 경우

복합 할당 연산자인 +=로 태그들을 빈 문자열에 넣어 html에 넣는 방법이 있습니다.

 

하지만 위에 코드에서 push() 함수로 빈 배열을 채운 다음

마지막에 join()함수로 배열을 하나의 문자열로 만들어 html에 넣는 방법도 있습니다.

 

join() 함수 활용법 코드 출력화면

 

 

 

 

3. pop() 함수

- 배열의 마지막 요소를 제거하고, 해당 마지막 요소를 반환합니다.

// 3. pop() 함수
const fruits = ["apple", "banana", "pear", "orange", "melon"]
console.log(fruits.pop()) // melon
console.log(fruits) // ['apple', 'banana', 'pear', 'orange']

위 배열의 마지막 요소가 melon 이므로 fruits.pop()의 반환 값은 melon이 됩니다.

pop()함수로 인해 배열은 마지막 요소인 melon이 제거된 배열이 됩니다.

 

console에 표시된 pop() 함수 결과

 

 

 

4. push() 함수

- 배열 끝에 새로운 요소를 추가하고, 배열의 길이를 반환합니다.

// 4. push() 함수
const fruits = ["apple", "banana", "pear", "orange", "melon"]
fruits.push("grape") // grape 추가
console.log(fruits) // ['apple', 'banana', 'pear', 'orange', 'melon', 'grape']

위 배열에서 push() 함수로 grape를 추가하여 총 요소가 6개인 배열이 됩니다.

 

console에 표시된 push() 함수 결과

 

 

5. shift() 함수

- 배열의 첫 번째 요소를 제거하고 그 요소를 반환합니다.

 

// 5. shift() 함수
const fruits = ["apple", "banana", "pear", "orange", "melon"]
console.log(fruits.shift()) // apple 반환
console.log(fruits) // ['banana', 'pear', 'orange', 'melon']

 

shift() 함수를 통해 fruits 배열의 첫 번째 요소인 "apple"이 제거되었고 콘솔에는 apple이 반환되었습니다.

따라서 fruits 배열에는 "apple"요소를 제외한 나머지 요소들로 구성됩니다.

 

console에 표시된 shift() 함수 결과

 

 

6. unshift() 함수

- 배열 맨 앞에 요소를 추가하고, 배열의 길이를 반환합니다.

 

// 6. unshift() 함수
const fruits = ["apple", "banana", "pear", "orange", "melon"]
console.log(fruits.unshift("grape")) // 배열의 길이인 6 반환
console.log(fruits) // ['grape', 'apple', 'banana', 'pear', 'orange', 'melon']

 

unshift()로 fruits 배열 맨 앞에 "grape"가 추가되었고, 반환값은 배열의 길이인 6이 반환됩니다.

fruits 배열은 "grape"가 추가되어 총 길이가 6인 배열이 됩니다.

 

console에 표시된 unshift() 함수 결과

 

 

 

7. splice() 함수

- 배열 특정 위치에 새로운 요소를 추가하거나 요소를 제거하면서 추가할 수도 있습니다. 제거된 요소가 반환됩니다.

- 첫 번째 파라미터 : 새로운 요소를 추가할 인덱스 번호

- 두 번째 파라미터 : 요소를 추가하기전에 삭제할 요소 수 (없으면 첫 번째 파라미터 인덱스 번호부터 끝까지 삭제됩니다)

- 나머지 파라미터 : 추가할 요소 (없으면 요소를 추가하지 않습니다)

* 두번째 파라미터부터 필수값이 아닙니다.

 

// 7. splice() 함수
const fruits = ["apple", "banana", "pear", "orange", "melon"]
console.log(fruits.splice(2, 2, "grape")) // pear, orange 반환
console.log(fruits) // ['apple', 'banana', 'grape', 'melon']

 

splice() 함수로 첫 번째 파라미터 2는 인덱스 번호로 pear요소이며, 두 번째 파라미터 2는 2개를 삭제하므로 pear, orange 요소를 삭제하게 됩니다. 마지막 파라미터인 "grape"는 첫 번째 파라미터인 2번 인덱스 위치에 추가됩니다.

 

console에 표시된 splice() 함수 결과

 

 

 

 

8. concat()

- 2개 이상의 배열을 하나의 배열로 결합합니다.

- ,(콤마)를 통해 배열을 계속 결합이 가능합니다. (ex. arr01.concat(arr02, arr03, ...))

 

// 8. concat() 함수
const fruits01 = ["apple", "banana"]
const fruits02 = ["pear", "orange", "melon"]
console.log(fruits01.concat(fruits02)) // ['apple', 'banana', 'pear', 'orange', 'melon']

 

fruits01 배열과 fruits02 배열을 결합하여 총 5개 요소를 가진 배열이 반환됩니다.

 

console에 표시된 concat() 함수 결과

 

 

* Spread Operator로도 배열 결합이 가능합니다.

const fruits01 = ["apple", "banana"]
const fruits02 = ["pear", "orange", "melon"]
console.log([...fruits01, ...fruits02]) // ['apple', 'banana', 'pear', 'orange', 'melon']

배열 변수명 앞에 ... 을 붙이면 개별요소로 분해합니다. 이것을 배열로 만들면 concat() 함수와 동일한 값이 반환됩니다.

 

 

 

9. slice() 함수

- 배열의 요소를 잘라내서 새 배열을 반환합니다.

- 첫 번째 파라미터 : 시작 인덱스

- 두 번째 파라미터 : 종료 인덱스 (없으면 시작인덱스부터 끝까지 잘라냅니다)

 

// 9. slice() 함수
const fruits = ["apple", "banana", "pear", "orange", "melon"]
console.log(fruits.slice(2, 4)) // pear, orange 반환
console.log(fruits) // ['apple', 'banana', 'pear', 'orange', 'melon']

 

slice() 함수의 시작인덱스가 2이므로 pear부터, 종료인덱스 4의 경우 자신은 포함하지 않고 바로 앞까지 범위가 지정되어 orange요소까지 잘라냅니다. 따라서 pear, orange를 반환합니다.

원본배열은 수정되지 않습니다.

 

console에 표시된 slice() 함수 결과

 

 

 

10. sort() 함수

- 배열 요소를 정렬합니다.

- 원본 배열이 정렬되는 것을 인식하고 있어야 합니다.

 

// 10. sort() 함수
const fruits = ["apple", "banana", "pear", "orange", "melon"]
console.log(fruits.sort()) // ['apple', 'banana', 'melon', 'orange', 'pear']

 

배열에 sort() 함수를 사용하면 오름차순으로 정렬 됩니다.

 

 

 

 

* 숫자 정렬

const num = [9, 2, 100, 250, 50, 80, 31]
console.log(num.sort()) // [100, 2, 250, 31, 50, 80, 9]

위의 숫자 배열을 sort()함수로 정렬 시 문자열로 비교하게 되어 원하는 정렬을 얻지 못합니다.

 

 

 

 

* 정렬순서에 대한 함수를 sort()함수의 파라미터로 정의하면 원하는 정렬을 반환할 수 있습니다.

 

const num = [9, 2, 100, 250, 50, 80, 31]

    num.sort(function (a, b) {
      if (a > b) return 1;
      if (a < b) return -1;
      if (a === 0) return 0;
      
      // a = 9, b = 2 / a > b이므로 9와 2는 교체
      // [2, 9, 100, 250, 50, 80, 31]
      
      // a = 9, b = 100 / a < b이므로 그대로 유지
      // [2, 9, 100, 250, 50, 80, 31]
      
      // a = 100, b = 250 / a < b이므로 그대로 유지
      .
      .
      .
      // [2, 9, 31, 50, 80, 100, 250] 최종적으로 오름차순 배열 형태로 정렬
    })
    console.log(num) // [2, 9, 31, 50, 80, 100, 250]

 

파라미터 a와 b에 배열 요소가 순차적으로 들어가고 그 둘을 비교합니다.

a와 b를 비교해서 리턴값이 양수이면 a와 b의 자리를 교체합니다.

a와 b를 비교해서 리턴값이 음수이면 a와 b의 자리를 교체하지 않습니다.

더 이상 a와 b의 자리가 교체되지 않을 때까지 진행되면 원하는 정렬을 얻게 됩니다.

 

 

 

따라서 양수인지 음수인지를 확인하므로 숫자 정렬의 경우 아래와 같이 축약할 수 있습니다.

 

const num = [9, 2, 100, 250, 50, 80, 31]
num.sort(function (a, b) { return a - b })
console.log(num) // [2, 9, 31, 50, 80, 100, 250]

 

 

내림차순의 경우 아래와 같이 작성할 수 있습니다.

 

const num = [9, 2, 100, 250, 50, 80, 31]
num.sort(function (a, b) { return b - a })
console.log(num) // [250, 100, 80, 50, 31, 9, 2]

 

오름차순을 a - b로 비교했다면 내림차순은 b - a로 하여 정렬할 수 있습니다.

 

 

 

 

* 객체 정렬 & 문자 정렬

let drinkList = [
      {name: "콜라", price: 1400},
      {name: "칠성사이다", price: 1300},
      {name: "아메리카노", price: 1200},
      {name: "바나나우유", price: 1500},
      {name: "초코우유", price: 1000}
    ]

    drinkList.sort(function (a, b) {
      if (a.name > b.name) return 1; // 양수 : 자리교체
      if (a.name < b.name) return -1; // 음수 : 자레교체 안함
      if (a.name === b.name) return 0; // 0 : 다음 순서 진행
    })

    console.log(drinkList)

 

객체에 접근하여 문자를 정렬할 경우 숫자 정렬할 때의 a - b로 정렬되지 않고 if 문을 사용하여 정렬할 수 있습니다.

console에 표시된 sort() 함수 결과

 

 

 

11. filter() 함수

- 배열에서 특정 조건에 맞는 요소만 모아 새 배열로 반환됩니다.

- filter() 함수의 파라미터로 함수가 사용되며 그 함수의 파라미터에는 배열의 요소가 포함됩니다.

- 원본 배열은 변경되지 않습니다.

 

 const drinkList = [
      { name: "콜라", price: 1400 },
      { name: "칠성사이다", price: 1300 },
      { name: "아메리카노", price: 1200 },
      { name: "바나나우유", price: 1500 },
      { name: "초코우유", price: 1000 }
    ]

    const drinkListFilter = drinkList.filter(function (drink) {
      return drink.price > 1200; // 조건이 true 인 요소로 새로운 배열이 반환됩니다.
    })
    console.log(drinkListFilter)

 

filter() 함수는 for 반복문을 사용한 것처럼 배열을 순회하고 함수 안에 조건이 true인 요소만 새로운 배열로 반환됩니다.

위 코드에서는 price가 1200 이상인 요소들만 true가 되므로 name 값이 콜라, 칠성사이다, 바나나우유인 요소로 새로운 배열이 반환됩니다.

console에 표시된 filter() 함수 결과

 

 

 

 

12. map() 함수

- 배열이 가지고 있는 요소가 객체인 경우, 객체가 가지고 있는 key - value 쌍을 새로운 객체 형태로 변경하여 새 배열을 반환합니다.

- map() 함수의 파라미터로 함수가 사용되며 그 함수의 파라미터에는 배열의 요소가 포함됩니다.

- 배열 안의 객체들을 재정의 합니다.

- 서버에서 필요한 정보만 재정의하여 클라이언트로 데이터를 전달하는 경우도 있습니다.

- 원본 배열은 변경되지 않습니다.

 

const products = [
      {size: "big", name: "radio", price: 30000},
      {size: "small", name: "computer", price: 40000},
      {size: "medium", name: "phone", price: 50000}
    ]
    const productMap = products.map(function (prod) {
      return { // 배열 요소의 객체를 재정의 합니다.
        sizeProduct: prod.size + " " + prod.name,
        price: prod.price
      }
    })
    console.log(productMap)

 

위 코드에서 객체의 키 명인 size와 name이 있었으나 map() 함수를 통해 sizeProduct 라는 키로 합치게 되어 새 객체로 재정의 됩니다.

 

console에 표시된 map() 함수 결과

 

 

 

 

13. reduce() 함수

- reduce() 함수의 파라미터로 함수가 사용되며 그 함수의 파라미터는 아래와 같습니다.

- 첫 번째 파라미터 : accumulator - 누적값

- 두 번째 파라미터 : currentValue - 현재 배열 요소

- 세 번째 파라미터 : currentIndex - 현재 배열 인덱스 번호 (생략 가능)

- 네 번째 파라미터 : array - 전체 배열 (생략 가능)

- 원본배열은 변경되지 않습니다.

 

// 13 reduce()
const num = [9, 2, 100, 250, 50, 80, 31]
let sum = num.reduce(function (accumulator, currentValue, currentIndex, array) {
     return accumulator + currentValue;
}, 0) // 0은 초기화 값, accumulator(누적값) 초기값 : 0
console.log(sum) // 522

 

reduce함수는 배열의 개별 요소를 currentValue에 넣고 accumulator에 값이 누적됩니다.

 

 

 

 

아래는 reduce()함수 작동 순서를 알아보기 위한 코드 입니다.

 

// 13 reduce()
    const num = [9, 2, 100, 250, 50, 80, 31]
    let sum = num.reduce(function (accumulator, currentValue, currentIndex, array) {
      console.log(currentIndex + 1 + "번째 진행")
      console.log(accumulator + " - 누적 값")
      console.log(currentValue + " - 현재 값")
      console.log(accumulator + " + " + currentValue + " - 누적값 + 현재 값")
      console.log("")
      return accumulator + currentValue;
    }, 0) // 초기화 값 0
    console.log("총 누적 값 : " + sum) // 522

 

1번째 진행

reduce() 함수의 두 번째 파라미터를 0으로 할 시 처음 accumulator 초기값은 0입니다.

currentValue에는 num의 첫 번째 요소인 9가 들어가고 누적 값과 더해집니다.

 

2번째 진행

num의 9와 합하여 누적 값은 9입니다.

currentValue에는 num의 두 번째 요소인 2가 들어가고 누적 값인 9와 더해집니다.

 

이런 식으로 배열 요소의 갯수 만큼 반복되고 총 합계인 522가 반환됩니다.

 

console에 표시된 reduce() 함수 결과

 

 

* 조건식에서 사용되는 reduce() 함수

const drinkList = [
      { name: "콜라", price: 1400 },
      { name: "칠성사이다", price: 1300 },
      { name: "아메리카노", price: 1200 },
      { name: "바나나우유", price: 1500 },
      { name: "초코우유", price: 1000 }
    ]

    const price = drinkList.reduce(function (acc, cur) {
      if (cur.price > 1200) { // price가 1200 초과
        acc.push(cur) // 누적값의 초기값을 배열로 설정하여 누적값 배열에 push()함수로 현재 요소 넣기
      }
      return acc; // 누적값 반환
    }, []) // 초기값 배열로 설정
    
    console.log(price)

위 코드는 숫자 누적 합이 아닌 if 조건문을 이용하여 조건에 맞는 값만 반환하는 코드 입니다.

누적값의 초기값을 배열로 설정하고 현재 요소(cur)를 push()함수로 넣어 누적값을 반환합니다.

price값이 1200 초과인 배열요소, 즉 name 값이 콜라, 칠성사이다, 바나나우유인 요소가 반환됩니다.

 

console에 표시된 reduce() 함수 결과

 


 

여기까지 array(배열) 객체 내장 함수들을 알아보았습니다.

내장 함수들을 학습해 놓는다면 배열을 합치거나 요소를 정렬하는 등의 함수를 별도로 만들지 않더라도 구현할 수 있게 됩니다.

 

여기까지 저의 글을 읽어주셔서 감사합니다.

 

 


 

 

 

다. 참고자료

1. https://www.youtube.com/c/개발자의품격 / 부트캠프 中 - array 객체 내장 함수

2. https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/toString - MDN, toString()

3. https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/filter - MDN, filter()

4. https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce - MDN, reduce()

 

본 글은 자바스크립트 반복문의 종류와 그에 대한 사용법에 대해서 알아보고자 합니다.

 

- 목차 - 

가. 반복문 의미와 사용하는 이유

나. 반복문의 종류와 사용법

 1. for-loop 문

 2. for in 문

 3. for of 문

 4. forEach 문

 5. while 문

 6. do while 문

다. 참고자료

 


 

가. 반복문 의미와 사용하는 이유

특정 코드 블록을 정해진 횟수만큼 반복해서 실행되게 만드는 것을 반복문이라고 합니다.

즉, 특정 기능이나 명령을 반복해서 수행하기 위함입니다.

아래 예제에서 반복문을 사용하는 이유를 쉽게 알아보고자 합니다.

 

웹 화면에 1에서 100까지의 숫자를 출력하는 경우를 가정해봅시다.

반복문을 사용하지 않는다면 아래와 같이 표현할 수 있습니다.

 

document.write('1');
document.write('2');
document.write('3');
        .
        .
        .
document.write('98');
document.write('99');
document.write('100');

 

시간을 투자하여 1에서 100까지 숫자를 위와 같이 표현할 수도 있습니다.

하지만 나중에 1,000까지, 10,000까지 숫자로 표현해야 한다면 많이 힘들어질 수 있습니다.

이런 경우 중복되는 코드를 줄이고 반복해서 실행할 수 있도록 하는 것반복문입니다.

 

다음 글부터 자바스크립트 반복문의 종류와 사용법에 대해서 알아봅시다.

 


나. 반복문의 종류와 사용법

반복문의 종류에는 for-loop, for-in, for-of, forEach, while, do while이 있습니다.

왼쪽부터 차례대로 알아봅시다.

 

 

 

1. for-loop 문

for-loop 문은 초기식, 조건식, 증감식이 포함되어 있는 반복문 입니다.

for-loop 문은 객체에서 사용할 수 없으며 배열에서 사용 가능합니다.

아래 코드는 for loop문의 기본 형식입니다.

 

// for 문의 형식
for(statement1 ; statement2 ; statement3){
     실행될 코드
}

 

- statement1 : for-loop문 실행할 때 무조건 딱 한번 실행
- statement2 : 코드 블록을 실행시킬 조건절
- statement3 : 코드블록을 실행한 후 실행되는 코드

 

 

 

아래 for-loop문을 이용한 예제 코드를 보면서 이해하고자 합니다.

 

// 1에서 100까지 숫자를 출력
for (let i = 1; i <= 100; i++) {
      document.write(i);
}

 

1) statement1에 해당하는 "let i = 1" 은 한 번 실행됩니다. (변수 i에 숫자 1이 할당됩니다)

2) statement2에 해당하는 조건인 "i <= 100" 은 i 가 숫자 100보다 작거나 같으면 아래 코드가 실행됩니다.

3) statement3에는 i++가 있습니다. 이것은 for-loop문 안 코드가 실행된 후 i가 1씩 증가됨을 의미합니다.

 

 

아래는 위의 코드가 실행되는 순서를 표현한 코드입니다.

 

for (let i = 1; i <= 100; i++) {
       i = 1,  1이 100보다 작으므로 조건에 부합
       document.write(1) 실행
       i++되어 i는 2가 됨

       i = 2, 2는 100보다 작으므로 조건에 부합
       document.write(2) 실행
       i++되어 i는 3이 됨
      .
      .
      .
       i = 100, 100은 100과 같으므로 조건에 부합
       document.write(100) 실행
       i++되어 i는 101이 됨.

       i = 101, 101은 100보다 크므로 조건에 부합하지 않음
       for문이 종료되고 코드블록을 빠져나감
    }

 

위와 같이 조건에 부합하면 계속 반복실행되며 조건에 부합되지 않으면 for-loop문이 종료됩니다.

 

 

 

* for-loop 문 - break

break는 for-loop문을 사용하면서 원하는 특정 시점에 for 블록 전체를 실행하지 않고 빠져나올 수 있는 용도로 사용합니다.

 

for (let i = 0; i < 10; i++) {
      if (i === 3) {
        break; // break를 만나면 for문 종료
      }
      console.log(i); // 0, 1, 2 콘솔에 출력
    }

 

위의 for-loop문을 break 없이 실행한다면 0에서 9까지 콘솔에 출력되어야 하지만 

if 조건문을 사용, i 가 3일 때 break를 적용하므로 콘솔에는 0, 1, 2만 출력되고 for-loop문을 빠져나옵니다.

 

 

* for-loop 문 - continue

continue는 for-loop문을 사용하면서 continue를 만나면 아래 실행 코드를 실행하지 않고 statement3으로 이동됩니다.

 

for (let i = 0; i < 10; i++) {
      if (i === 3) {
        continue; // continue를 만나면 아래 코드를 실행하지 않고 i++로 이동 후 진행
      }
      console.log(i); // 0, 1, 2, 4, 5, 6, 7, 8, 9 콘솔에 출력 (3 생략)
    }

 

continue가 없다면 0~9까지 콘솔에 출력되지만 i가 3일 때 continue가 실행되므로

i가 3일 때의 continue 아래 코드가 실행되지 않고 statement3인 i++로 진행됩니다.

따라서 콘솔에는 0, 1, 2, 4, 5, 6, 7, 8, 9가 출력됩니다. (3이 생략됩니다)

 

 

 

 

2. for in 문

배열에서 요소만큼 반복하고 인덱스 번호를 출력합니다.

for-loop문은 객체에서 사용할 수 없지만 for in은 객체에서 사용할 수 있습니다.

 

 

아래는 for in 문의 기본 형태입니다.

 

// for in 기본 형태
for (선언자 변수명 in 객체) {
      실행 코드
    }

 

 

 

아래 for-loop문과 비교하면서 알아봅시다.

 

const fruit = ["orange", "apple", "banana", "grape"];

    // for 문
    for (let i = 0; i < fruit.length; i++) {
      console.log(fruit[i]);
    }

    // for in 문
    for (const i in fruit) {
      console.log(fruit[i]);
    }

 

위의 for와 for in 은 똑같은 결과를 가집니다.

for 같은 경우 statement를 설정해야 하지만 for in은 따로 statement를 설정하지 않더라도 모든 배열 요소를 순회합니다.

for in의 변수명에는 배열의 인덱스 번호가 출력됩니다. (위의 예제에서는 배열의 인덱스 번호가 0, 1, 2, 3이 됩니다)

 

 

* object에서 사용되는 for in

 

let person = {
      name: "김미영",
      age: 28,
      tel: "010-1234-5678",
      city: "daegu"
    };

    for (const key in person) { // key에는 person 객체의 키 명이 입력됩니다.
      console.log(key, person[key])
    }

 

객체에서 사용되는 for in 은 변수명에 객체의 키 명이 입력되어 위 예제 key에는 name, age, tel, city가 담겨있습니다.

객체의 키 값을 출력하기 위해서는 객체[키]를 이용하며 객체의 모든 키 값을 출력할 수 있습니다.

위의 예제에선 person[key]로 가져올 수 있습니다. (김미영, 28, 010-1234-5678, daegu가 출력됨)

 

 

- for in을 사용하는 경우

(1) 객체의 키, 값을 모두 출력해야 하는 상황

(2) 객체의 키 명을 알 수 없을 때 for in을 사용 가능

 

 

 

 

3. for of 문

배열의 요소만큼 반복하고 요소 값을 출력할 수 있습니다.

 

const fruit = ["orange", "apple", "banana", "grape"];
    for (const fruitsName of fruit) { // 배열을 순회하면서 fruitsName에 요소값을 넣어준다.
      console.log(fruitsName) // orange, apple, banana, grape
    }

 

for in은 변수명에 인덱스 번호가 담긴다면 for of는 배열 각각의 요소 값이 입력됩니다.

위의 예제 콘솔에 변수명 fruitsName을 출력하면 orange, apple, banana, grape가 출력됩니다.

 

 

* 문자열에 사용되는 for of 문

문자열을 문자 하나씩 출력할 수 있습니다.

 

const str = "js is the best language";
    for (const string of str) {
      console.log(string)
    }

 

위의 코드를 실행 시 아래와 같이 출력됩니다.

 

문자열을 for of로 출력한 모습

 

 

 

4. forEach 문

forEach문은 배열의 내장함수로 사용됩니다.

forEach의 파라미터는 함수를 전달 받습니다.

*파라미터(매개변수)란 함수를 호출할 때 전달받은 인수를 함수 내부로 전달하기 위한 변수를 의미합니다.

배열을 순회하면서 배열의 요소값, 인덱스번호를 출력할 수 있습니다.

 

const fruit = ["orange", "apple", "banana", "grape"]; // fruit - 배열 객체
  fruit.forEach(function (item, index) { // array 내장함수, 첫번째 파마리터 : 요소값, 두번째파라미터 : 인덱스번호
    console.log(item) // orange, apple, banana, grape 출력
    console.log(index) // 0, 1, 2, 3 출력
   })

 

위 예제의 첫번째 파라미터 item에는 배열의 요소 값인 orange, apple, banana, grape를 전달받고

두번째 파라미터 index에는 인덱스 번호인  0, 1, 2, 3을 전달 받습니다.

 

 

 

 

5. while 문

while문은 조건식을 만족하는 동안 코드 블록을 실행합니다.

조건식이 만족하는 동안 실행되므로 while문을 종료할 수 있는 코드가 반드시 존재해야 합니다.

 

let i = 1;
    while (i < 5) { // 변수 i가 5미만일 때만 while문 실행
      console.log(i)
      i++; // 반복할 때마다 변수 i를 1씩 증가, i가 5가되면 while문 종료
      
      // i = 1, i < 5 코드 블록 실행
      // i = 2, i < 5 코드 블록 실행
      // i = 3, i < 5 코드 블록 실행
      // i = 4, i < 5 코드 블록 실행
      // i = 5, i < 5 조건식에 부합하지 않으므로 while 문 종료
    }

 

조건식에 부합하는 동안 반복하다가 조건에 부합하지 않게 되면 while문은 종료됩니다.

위의 예제에서는 i 가 5 미만일 때까지 반복하다가 5가 되면 조건에 부합하지 않으므로 종료됩니다.

 

* while문이 사용되는 경우

얼마나 반복해야 될지 모를 때 사용합니다.

 

// 동전교환기
    let inputCoin = 6000; // 넣은 금액
    let coinUnit = 500; // 교환할 동전
    let coinCount = 0; // 교환 동전의 갯수, 초기값은 0

    while (inputCoin >= 0) { // 넣은 금액이 0보다 클 경우 반복 (조건식)
      inputCoin = inputCoin - coinUnit; // 넣은 금액 - 교환할 동전, 넣은 금액이 0보다 작을 때까지 반복
      coinCount++; // 교환 동전 갯수 1씩 증가
    }

 

위의 예제는 동전교환기 코드입니다.

동전 교환기의 경우 사용자가 돈을 얼마나 교환할지 정해져 있지 않습니다.

따라서 얼마나 반복해야 할지 알 수 없으므로 while문을 통해 반복 횟수를 명시하지 않더라도 반복문을 사용할 수 있게 됩니다.

 

 

 

6. do while 문

do while문은 무조건 1번 코드 블록이 실행되고, 그 다음 조건식을 체크합니다.

 

let i = 1;
    do {
      console.log(i) // 무조건 1번 실행되므로 console에 1이 출력된다.
      i++;
    } while (i > 5)

 

위의 예제에서 조건식인 i 가 5보다 커야 조건에 부합하지만 do while 문은 코드블록이 무조건 1번 실행되므로 콘솔에 1일 출력되고 do while문이 종료됩니다.

 


 

여기까지 자바스크립트 반복문에 대해서 알아보았습니다.

배열 및 객체에서 반복문을 통해  값 또는 인덱스 번호를 가져올 수 있으며 반복되는 코드를 줄일 수 있는 장점이 있습니다.

반복문에는 6가지가 있으며 각각의 쓰임새가 조금씩 다르므로 필요에 맞게 사용하시면 됩니다.

 

저의 글을 읽어주셔서 감사합니다.

 


 

 

다. 참고자료

 

1. https://www.youtube.com/c/개발자의품격 / 부트캠프 中 - 반복문

2. http://www.tcpschool.com/javascript/js_control_loop - TCH SCHOOL - 반복문

3. http://www.tcpschool.com/javascript/js_function_parameterArgument - TCP SCHOOL - 매개변수와 인수

본 글은 CSS 박스모델에 대하여 알아보고자 합니다.

 

- 목차 -

가. Css 박스모델을 알아야 하는 이유

나. Css 박스모델의 의미

다. Css 박스모델의 구성

 0. 개발자 창으로 Css 박스모델 확인 법

 1. 내용(content)

 2. 패딩(padding)

 3. 테두리(border)

 4. 마진(margin)

라. box-sizing 속성

마. 참고자료

 


 

가. Css 박스모델을 알아야 하는 이유

Css(cascading style sheets)는 웹의 뼈대인 html을 꾸미는 역할을 하고 있습니다. 그 중에 Css 박스모델은 컨텐츠의 크기, 간격, 여백 등을 조절하기 때문에 웹 사이트에 스타일을 적용하기 위해서는 당연히 알아야 하는 개념임이 틀림 없습니다. 다음 글 부터 Css 박스모델의 의미부터 속성들까지 알아보고자 합니다.

 

 

 

 


 

 

나. Css 박스모델의 의미

모든 Html 요소는 박스(box) 모양으로 구성되며, 이것을 Css 박스모델이라고 부릅니다. 아래 예시 사진을 살펴봅시다.

 

네이버 로고 이미지가 박스형태인 모습

 

위의 이미지를 통해 확인할 수 있듯이 네이버 로고만을 보면 박스 모양으로 되어있지는 않습니다. 하지만 글 아래에서 알려드릴 개발자창을 통해 html 요소를 확인해본 결과 네이버 로고도 html 요소이기 때문에 박스모양으로 되어있다는 것을 확인할 수 있습니다.

 

 

 


 

 

다. Css 박스모델의 구성

Css 박스모델은 내용(content), 패딩(padding), 테두리(border) 그리고 마진(margin)으로 이루어져 있습니다.

 

0. 개발자 창으로 Css 박스모델 확인 법

 

잠깐, 다음 내용으로 가기전에 개발자 창을 통해 Css 박스모델 확인하는 방법을 먼저 알려드리고자 합니다.

 

1) 웹 사이트에 접속합니다.

 

2) 키보드 상단의 "F12"키를 누르거나 또는 웹 사이트의 빈 공간에서 마우스 오른쪽 버튼을 클릭하고 "검사"라는 항목을 클릭합니다.

 

마우스 오른쪽 클릭 시 나온는 검사항목

 

3) 위의 항목을 수행 시 개발자 창이 등장하고 요소의 정보를 보기 위해서는 개발자창의 좌측 상단 마우스모양을 클릭합니다.

 

개발자 창 우측 상단의 마우스 모양 이미지

 

4) 확인하고자 하는 요소를 웹 사이트에서 클릭합니다.

(마우스를 위에 올리기만 해도 아래 이미지와 같이 정보를 확인할 수 있습니다.)

 

네이버의 로그인 버튼을 개발자 창으로 클릭한 모습

 

5) 요소를 클릭하면 개발자 창에서 html의 구조와 Css가 적용된 속성들을 확인할 수 있습니다.

 

개발자 창의 구조

 

6) Css 속성을 확인할 수 있는 창에서 맨 아래로 내리면 css 박스모델을 확인할 수 있는 이미지를 볼 수 있습니다.

 

css 박스모델을 확인할 수 있는 이미지

 

여기까지 개발자 창으로 Css 박스모델을 확인할 수 있는 방법이였으며 다음 내용부터 Css 박스모델 구성을 알아보고자 합니다.

 

 

 

1. 내용(content)

내용(content)은 텍스트, 이미지, input, div 요소 등 모든 실질적인 내용 부분입니다.

 

네이버 컨텐츠 영역 표시

 

개발자 창에서 요소를 클릭했을 때 스타일 탭(Css 속성들을 확인할 수 있는 탭의 명칭)의 가장 안쪽 영역이 content 입니다.

위의 이미지에서 content가 512x102라고 되었는데 이것의 의미는 content 너비가 512px, 세로가 102px이라는 의미 입니다.

 

내용에 너비와 높이를 적용하기 위해서는 css의 width 속성과 height 속성을 사용합니다.

 

/* Css 너비와 높이 예시 코드 */
div{
 width : 150px;
 height: 200px;
}

 

 

2. 패딩(padding)

패딩(padding)은 내용(content)와 테두리(border)사이의 간격입니다.

 

패딩 영역

 

위 이미지 스타일 탭의 박스모델에서 padding 이라고 적혀있으며 초록색 영역이 패딩(padding) 영역을 나타내고 있습니다. 양 옆으로 35라고 적혀있고 위 아래로는 "-" 표시가 되어있는데, 양 옆은 35px 적용되어 있으며 위 아래로는 패딩값이 없다는 것을 표현하고 있습니다.

실제 요소에도 양 옆으로 초록색 영역이 패딩을 표현하고 있습니다. 

 

아래는 Css 패딩(padding) 속성을 사용하는 방법 입니다.

 

div{
  /* 축약 코드 */
  padding : 10px; /* 위, 아래, 좌, 우 : 10xp */
  padding : 10px 5px; /* 위, 아래 : 10xp / 좌, 우 : 5px */
  padding : 10px 5px 7px; /* 위 : 10px / 좌, 우 : 5px / 아래 : 7px */
  padding : 10px 5px 7px 4px; /* 위 : 10px / 우 : 5px / 아래 : 7px / 좌 : 4px / 시계방향 */
  
  /* padding 4개 방향을 별도로 작성할 수 있습니다. */
  padding-top: 10px; /* 위 : 10px */
  padding-right: 10px; /* 오른쪽 : 10px */
  padding-bottom: 10px; /* 아래 : 10px */
  padding-left: 10px; /* 왼쪽 : 10px */
}

 

 

3. 테두리(border)

테두리(border)는 내용(content)과 패딩(padding)을 감싸는 테두리 선 입니다.

 

테두리 영역

 

위 이미지 스타일 탭의 박스모델에서 border 라고 적혀있으며 노란계열의 영역이 테두리(border)를 표시해주고 있습니다. 위, 아래, 좌, 우로 1씩 적혀있는 것은 양 사방으로 1px씩 테두리가 적용되어 있다는 것을 나타내고 있습니다.

 

아래는 Css 테두리(border) 속성을 사용하는 방법 입니다.

 

div{
  /* 축약 코드 */
  border : 1px solid black; /* 위, 아래, 좌, 우 : 1px 실선 검정색 */

/*
  border 속성을 아래와 같이 분해하여 작성할 수 있습니다.
  border-width : 테두리의 두께 (px단위, thin, medium, thick)
  border-style : 테두리 스타일 (solid, dashed, dotted 등)
  border-color : 테두리의 색상 (black, #000 등)
 */
  
  /* border 4개 방향을 별도로 작성할 수 있습니다. */
  border-top: 1px solid black; /* 위 : 1px 실선 검정색 */
  border-right: 1px solid black; /* 오른쪽 : 1px 실선 검정색 */
  border-bottom: 1px solid black; /* 아래 : 1px 실선 검정색 */
  border-left: 1px solid black; /* 왼쪽 : 1px 실선 검정색 */
}

 

 

4. 마진(margin)

마진(margin)은 테두리(border)를 감싸는 영역 입니다.

 

마진 영역

 

위 이미지 스타일 탭의 박스모델에서 margin 이라고 적혀있으며 갈색계열의 영역이 마진(margin)을 표시해주고 있습니다.

위 이미지에서는 위 4, 아래 5, 좌우는 "-"표시가 되어있는데 이것의 의미는 위로 4px, 아래로 5px, 좌우는 값이 없다는 것을 나타내고 있습니다.

 

아래는 Css 마진(margin) 속성을 사용하는 방법 입니다.

 

div{
  /* 축약 코드 */
  margin : 10px; /* 위, 아래, 좌, 우 : 10xp */
  margin : 10px 5px; /* 위, 아래 : 10xp / 좌, 우 : 5px */
  margin : 10px 5px 7px; /* 위 : 10px / 좌, 우 : 5px / 아래 : 7px */
  margin : 10px 5px 7px 4px; /* 위 : 10px / 우 : 5px / 아래 : 7px / 좌 : 4px / 시계방향 */
  
  /* margin 4개 방향을 별도로 작성할 수 있습니다. */
  margin-top: 10px; /* 위 : 10px */
  margin-right: 10px; /* 오른쪽 : 10px */
  margin-bottom: 10px; /* 아래 : 10px */
  margin-left: 10px; /* 왼쪽 : 10px */
}

 


 

 

라. box-sizing 속성

box-sizing 속성은 요소의 너비와 높이 계산하는 방법을 설정합니다.

 

1) box-sizing : content-box;

컨텐츠 영역을 기준으로 크기를 결정합니다.

content-box는 기본 값으로 content 영역과 padding, border 값을 다 더한 값이 요소의 너비와 높이가 됩니다.

 

box-sizing : content-box

 

위의 이미지를 보면 box-sizing : content-box;를 설정하지 않아도 기본 값으로 적용되어 있는 모습입니다. content 영역의 너비, 높이 값에 패딩 값과 테두리 값을 합산하여 요소의 너비와 높이가 결정 됩니다.

 

- 너비 계산 : 100px(너비 값) + 40px(padding 좌, 우 너비 합산) + 10px(border 좌, 우 너비 합산) = 150px;

- 높이 계산 : 50px(높이 값) + 40px(padding 위, 아래 높이 합산) + 10p(border 위, 아래 높이 합산) = 100px;

 

 

2) box-sizing : border-box;

테두리(border)를 기준으로 크기를 결정합니다.

border-box는 요소의 너비 값과 높이 값이 있다면 패딩 값과 테두리 값은 각각의 너비 값과 높이 값 안쪽에 영역이 추가됩니다.

 

box-sizing : border-box

 

box-sizing : border-box;는 패딩 값과 테두리 값이 추가되어도 요소의 너비 값과 높이 값을 넘어서지 않습니다.

- 너비 계산 : 100px(너비 값) = 100px; (패딩 값, 테두리 값이 포함되지 않음)

- 높이 계산 : 50px(높이 값) = 50px; (패딩 값, 테두리 값이 포함되지 않음)

 


여기까지 Css 박스모델의 의미와 구성에 대해서 알아보았습니다. 

Css의 박스모델을 이해하셨다면 컨텐츠의 크기, 여백, 영역 등을 지정할 수 있으므로 html 요소 레이아웃 배치에 대한 이해도가 높아졌을 것으로 예상됩니다.

 

저의 글을 읽어주셔서 감사합니다.

 


 

마. 참고자료

1. https://www.youtube.com/c/개발자의품격 / 부트캠프 中 - css 박스모델

2. https://developer.mozilla.org/ko/docs/Web/CSS/box-sizing / MDN - box-sizing

3. http://www.tcpschool.com/css/css_boxmodel_boxmodel / TCP SCHOOL - 박스 모델

4. https://www.naver.com/ / 예시 이미지 사용

본 글은 이미지 한 장에 여러 개의 링크를 걸 수 있는 HTML 태그인 <map> 태그에 대해서 알아보고자 합니다. 

 

- 목차 -

가. <map> 태그를 사용해야 하는 상황

나. <map> 태그에 대하여

 1. <map> 태그 사용법

 2. <map> 태그를 쉽게 사용할 수 있는 사이트 소개

다. 참고자료

 


가. <map>태그를 사용해야 하는 상황

html을 사용하시는 분들은 보통 <img> 태그에 <a> 태그를 감싸주어 이미지를 클릭하면 페이지가 이동되도록 할 것 입니다.

<div>
    <a href="링크">
      <img src="이미지 경로" alt="이미지에 대한 설명">
    </a>
</div>

위의 방법은 이미지를 클릭하면 다른 페이지로 이동되지만 링크를 단 하나만 설정할 수 있습니다.

 

다음과 같은 상황을 가정해봅시다. 

이 글을 읽고 있는 분은 아마 개발자이거나 개발자를 준비하고 계시는 분 일 것입니다.

어느 날 기획자 또는 디자이너가 요구사항을 가져옵니다.

"이미지 한 장에 제품이 여러 개가 있는데 각각 다른 링크로 이동되도록 부탁드려요~"

제품이 여러 개가 존재하는 이미지

위의 예시를 보면 제품별로 이미지를 잘라내어 링크를 걸기에 난감한 상황에 직면할 수 있습니다.

 

또한 웹 사이트를 이용하다 보면 분명 하나의 이미지인데 이미지 안의 특정 제품을 클릭하면, 클릭한 제품에 대한 상세 화면으로 이동이 되는 것을 경험한적이 있을 것입니다.

 

대표적인 웹 사이트가 바로 이케아 입니다. 

https://www.ikea.com/kr/ko/

 

IKEA KOREA | 이케아 코리아

행복을 만드는 우리집, IKEA 더 나은 생활을 위해 다양한 홈퍼니싱 제품 및 솔루션을 제공합니다. IKEA.kr을 방문하여 온라인으로 쇼핑하거나 가까운 매장을 직접 방문해보세요.

www.ikea.com

 

이케아는 판매하는 단일 제품에 대한 이미지가 아니라 해당 제품이 있는 공간을 꾸미고 그 공간 안에서 제품이 어떻게 보여지는지를 고객에게 보여줌으로써, 고객의 공간이 이 제품을 통해 어떻게 바뀔지 상상할 수 있도록 합니다. 

 

그리고 공간 속에 배치된 각 제품을 클릭하면 해당 제품을 구매할 수 있는 구매 페이지로 이동을 하게 됩니다. 이렇게 하나의 사진 이미지에 특정 영역 마다 링크를 삽입해서 사용자가 링크를 클릭하면 별도의 페이지로 이동하도록 개발 할 때 사용할 수 있는 태그가 바로 <map> 태그입니다.


나. <map> 태그에 대하여

  1. <map> 태그 사용법

<img usemap="#food" src="이미지 경로" alt="이미지 설명">
  <map name="food">
    <area shape="링크 영역 모양" coords="링크 영역 좌표1" href="이동할 페이지 링크1" alt="대체 텍스트1">
    <area shape="링크 영역 모양" coords="링크 영역 좌표2" href="이동할 페이지 링크2" alt="대체 텍스트2">
    <area shape="링크 영역 모양" coords="링크 영역 좌표3" href="이동할 페이지 링크3" alt="대체 텍스트3">
  </map>

1) <img> 태그를 생성하고 usemap 속성과 값을 입력합니다.

 

2) <map> 태그를 생성하고 name 속성값에 적절한 값을 입력합니다.

 

3) 이미지와 <map>태그를 연결하기 위해서 <img> 태그의 usemap 값과 <map>태그의 name 값을 동일하게 작성하고 usemap 값에는 맨 앞에 #을 붙여서 입력합니다.

 

4) <map> 태그 안으로 연결할 링크 갯수와 동일하게<area> 태그를 작성합니다.

 

5) <area> 태그의 shape 속성, coords 속성, href 속성에 알맞는 값을 입력합니다.

  - shape : 링크 영역의 모양을 설정합니다. (값 : circle, rect, poly) / circle = 원 영역, rect = 사각형 영역, poly = 다각형

  - coords : 링크 영역의 좌표를 설정합니다.

    (circle 일 경우 coords="x좌표, y좌표, 반지름" )

    (rect 일 경우 coords="좌측 상단 x좌표, 좌측 상단 y좌표, 우측 하단 x좌표, 우측 하단 y좌표")

    (poly 일 경우 coords="x1, y1, x2, y2, x3, y3"), 다각형의 모서리에 대한 좌표를 입력한다.

   - href : <area> 태그 영역마다 이동할 페이지 링크를 입력합니다.

   - target : _self : 현재 자기 자신의 창에서 이동, _blank : 새 창(새 탭)에서 열림

 

6) 위의 과정이 끝나면 테스트 진행 후 완료됩니다.

 

  2. <map> 태그를 쉽게 사용할 수 있는 사이트 소개

"1. <map> 태그 사용법"에서 <area> 태그 coords의 속성 값은 알기가 어려운데요 아래 사이트에서 쉽게 제작할 수 있습니다.

https://www.image-map.net/

 

image-map.net 처음 접속한 화면

1) 주소로 처음 접속하면 위와 같은 화면이 나옵니다. 왼쪽(자신의 PC에서 이미지 선택) 또는 오른쪽(웹 이미지 주소로 가져오기) 버튼을 클릭하여 이미지를 가져오시면 됩니다.

 

2) 이미지를 입력하면 위와 같은 화면이 나옵니다. 항목들을 작성합니다.

 ① Active : 입력할 항목을 클릭합니다.

 ② Shape : 링크 영역 모양을 선택합니다.

 ③ 이미지에 마우스를 왼쪽 클릭하여 링크 영역을 표시합니다.

 ④ Link : 영역을 클릭 시 이동할 페이지 링크를 입력합니다.

 ⑤ Title : 영역에 대한 설명을 입력합니다.

 ⑥ Target : 링크 클릭 시 창을 어떻게 띄울지 선택합니다. (_blank : 새창, _self : 현재 자신 창)

 ⑦ X버튼을 클릭 시 해당 항목이 초기화 됩니다.

 ⑧ 링크영역을 추가하고 싶다면 "Add New Area" 버튼을 클릭합니다.

 ⑨ 영역을 다 만들었다면 "Show Me The Code!" 버튼을 클릭합니다.

 

3) 코드를 복사합니다.

제작된 map 태그 코드

- "Show Me The Code!" 버튼을 클릭하면 팝업창으로 코드들을 보여줍니다. 그대로 코드 에디터에 복사 후 <img> 태그의 이미지 경로와 usemap, name 속성 등의 값들을 수정하면 완료됩니다!

 

4) 실제 결과물 입니다.

실제 코드를 복사 후 화면에 나타낸 모습

- 캡쳐로 인해 마우스 포인터는 보이지 않지만 실제 링크 영역을 마우스로 올리고 있으면 title 값이 나오고 좌측하단에 이동할 링크까지 보여주고 있습니다.

 


 

클릭 유도 표시

* 실제 클릭할 영역까지 보여주고 있지 않으니 이미지에 표시해주면 쉽게 클릭을 유도할 수 있습니다.

 

 

저의 글을 읽어주셔서 감사합니다.

 


 

다. 참고자료

1. https://www.youtube.com/watch?v=5zqxXKrnZtY / 개발자의 품격 - 사진 한장에 여러개의  하이퍼링크 걸기

2. http://www.tcpschool.com/html-tag-attrs/area-coords / TCPSCHOOL - <area> 태그의 coords 속성

3. https://developer.mozilla.org/ko/docs/Web/HTML/Element/area / MDN - <area>

 

* 사진출처

1. https://pixabay.com/ko/photos/%eb%8f%bc%ec%a7%80-%eb%8f%bc%ec%a7%80%ea%b3%a0%ea%b8%b0-%eb%8f%bc%ec%a7%80%ea%b3%a0%ea%b8%b0-%ec%95%88%ec%8b%ac-2103502/ / 사진출처 - 픽사베이

 

+ Recent posts