> For the complete documentation index, see [llms.txt](https://leeans-dev-book.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://leeans-dev-book.gitbook.io/docs/lecture/javascript/tab-ui.md).

# Tab UI

js010.html 복사해서 js011.html 파일 생성 후&#x20;

body 태그 안의 내용을 전부 삭제

(bootstrap, jquery cdn은 남겨두자)

<figure><img src="/files/Z3wvsecvRkmZ4UZtEbDi" alt=""><figcaption><p>Tab UI 예시 </p></figcaption></figure>

{% embed url="<https://carbondesignsystem.com/components/tabs/usage>" %}

Tab UI를 만들어 보자

&#x20;

{% code title="js011.html" %}

```html
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Bootstrap demo</title>

  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-4bw+/aepP/YC94hEpVNVgiZdgIC5+VKNBQNGCHeKRQN+PtmoHDEXuppvnDJzQIu9" crossorigin="anonymous">

  <link rel="stylesheet" href="main.css">
  <script src="https://code.jquery.com/jquery-3.7.0.min.js" integrity="sha256-2Pmvv0kuTBOenSvLm6bvfBSSHrUJ+3A7x6P5Ebd07/g=" crossorigin="anonymous"></script>
  <style>
    ul.list {
      list-style-type: none;
      margin: 0;
      padding: 0;
      border-bottom: 1px solid #ccc;
    }
    ul.list::after {
      content: '';
      display: block;
      clear: both;
    }
    .tab-button {
      display: block;
      padding: 10px 20px 10px 20px;
      float: left;
      margin-right: -1px;
      margin-bottom: -1px;
      color: grey;
      text-decoration: none;
      cursor: pointer;
    }
    .orange {
      border-top: 2px solid orange;
      border-right: 1px solid #ccc;
      border-bottom: 1px solid white;
      border-left: 1px solid #ccc;
      color: black;
      margin-top: -2px;
    }
    .tab-content {
      display: none;
      padding: 10px;
    }
    .show {
      display: block;
    }
  </style>
</head>
<body>



  <div class="container mt-5">
    <ul class="list">
      <li class="tab-button">Products</li>
      <li class="tab-button orange">Information</li>
      <li class="tab-button">Shipping</li>
    </ul>
    <div class="tab-content">
      <p>상품설명 탭  Product</p>
    </div>
    <div class="tab-content show">
      <p>스펙설명 탭 Spec</p>
    </div>
    <div class="tab-content">
      <p>배송정보 탭 Shipping</p>
    </div>
  </div>

  <script>
   
  </script>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-HwwvtgBNo3bZJJLYd8oVXjrBZt8cqVSpeBNS5n7C8IVInixGAoxmnlMuBnhbgrkm" crossorigin="anonymous"></script>
</body>
</html>
```

{% endcode %}

&#x20;products 버튼을 누르면 상품 설명 탭이 보이고, information버튼을 누르면 스펙설명 탭이 보이게 만들면 된다.&#x20;

💎 javascript 모듈화&#x20;

&#x20;css 파일을 main.css로 따로 뺀 것 처럼 js도 모듈화 할 수 있다.&#x20;

{% embed url="<https://github.com/kdelemme/blogjs>" %}
모듈화 예시&#x20;
{% endembed %}

{% code title="index.html" %}

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="Blog about personal projects written mostly in JavaScript with AngularJS and Node.js. MongoDB is a guest too.">
    <meta name="author" content="Kevin Delemme">
    <meta name="fragment" content="!">

    <title>Kevin Delemme - JavaScript Addict - Personal projects written mostly with AngularJS, Node.js and MongoDB</title>
    <link href="dist/css/bootstrap.min.css" rel="stylesheet">
    <link href="dist/css/style.css" rel="stylesheet">
    <link href="dist/css/font-awesome.min.css" rel="stylesheet">
    <link href="lib/wysiwyg/css/bootstrap3-wysiwyg5.css" rel="stylesheet">
  </head>
  
    <body ng-app="app">

        <div class="container col-sm-12">

            <header class="header">
                <h1 class="header-title">
                    <a href="#">
                        <i class="fa fa-code"></i> Kevin Delemme
                    </a>
                </h1>
            </header>

            <div ng-view></div>
            
        </div>

        <script src="lib/angular/angular.min.js"></script>
        <script src="lib/angular/angular-route.min.js"></script>
        <script src="lib/jquery/jquery-2.0.3.min.js"></script>
        <script src="lib/bootstrap/bootstrap.min.js"></script>
        <script src="dist/js/blog.js"></script>
        <script src="lib/wysiwyg/js/wysihtml5-0.3.0.min.js"></script>
        <script src="lib/wysiwyg/js/bootstrap3-wysihtml5.js"></script>
        <script>
            (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

            ga('create', 'UA-46674011-1', 'kdelemme.com');
            ga('send', 'pageview');
        </script>
    </body>
</html>
```

{% endcode %}

js 폴더를 생성하고 app.js 파일 생성 후&#x20;

```
<script src="js/app.js"></script>
```

html에 \<body>태그 제일 아래에 이부분 삽입 하면 app.js의 스크립트 사용 가능&#x20;

왜 이렇게 할까?&#x20;

&#x20;이번에 개발하는 탭 UI를 모든 페이지마다 사용한다고 가정하면&#x20;

모든 html 파일에 똑같은 js를 복붙해야한다.&#x20;

이런 귀찮음을 방지하고자 모듈화해서 사용한다.&#x20;

모듈화를 잘하는 개발자가 진짜 실력있는 개발자다.&#x20;

다시 돌아와서&#x20;

products 버튼을 누르면 상품 설명 탭이 보이게 해보자

products 버튼을 누르면 버튼에 orange 클래스 추가

product div 에 show 클래스 추가&#x20;

이렇게 하면 버그 생김🔥

모든 버튼에  orange 클래스와 div show  클래스 제거&#x20;

jQuery로 class 셀렉트 하면 document.querySellectAll과 같이 동작 함&#x20;

$('.클래스명').eq(0)  하면 document.querySellectAll('.클래스명')\[0] 과 같은 동작

✨ 과제. 버튼 3개의 탭 기능 구현 해보기&#x20;

{% code title="app.js" %}

```javascript
$('.tab-button').eq(0).on('click', function (){
    $('.tab-button').removeClass('orange');
    $('.tab-content').removeClass('show');
    $('.tab-button').eq(0).addClass('orange');
    $('.tab-content').eq(0).addClass('show');

})

$('.tab-button').eq(1).on('click', function (){
    $('.tab-button').removeClass('orange');
    $('.tab-content').removeClass('show');
    $('.tab-button').eq(1).addClass('orange');
    $('.tab-content').eq(1).addClass('show');

})

$('.tab-button').eq(2).on('click', function (){
    $('.tab-button').removeClass('orange');
    $('.tab-content').removeClass('show');
    $('.tab-button').eq(2).addClass('orange');
    $('.tab-content').eq(2).addClass('show');

})

```

{% endcode %}

그런데 이렇게 작성하고 보니&#x20;

$('.tab-button') 이 계속해서 반복 된다.&#x20;

이럴땐 변수에 담아서 작성하면 성능 상 이점이 있다.&#x20;

&#x20;

🎈  Ctrl + R 하면 파일 내에서 바꾸기 가능

🎈 Ctrl + Shift + R 하면 프로젝트 내에서 바꾸기 가능

🎈  Ctrl + F 하면 파일 내에서 검색 가능

🎈 Ctrl + Shift + F 하면 프로젝트 내에서 검색 가능

{% code title="app.js" %}

```javascript
var tabBtn = $(".tab-button");
var tabContent = $(".tab-content");

tabBtn.eq(0).on('click', function (){
    tabBtn.removeClass('orange');
    tabContent.removeClass('show');
    tabBtn.eq(0).addClass('orange');
    tabContent.eq(0).addClass('show');

})

tabBtn.eq(1).on('click', function (){
    tabBtn.removeClass('orange');
    tabContent.removeClass('show');
    tabBtn.eq(1).addClass('orange');
    tabContent.eq(1).addClass('show');

})

tabBtn.eq(2).on('click', function (){
    tabBtn.removeClass('orange');
    tabContent.removeClass('show');
    tabBtn.eq(2).addClass('orange');
    tabContent.eq(2).addClass('show');

})
```

{% endcode %}

이렇게 바꿔 줄 수 있다.

## for 반복문&#x20;

```javascript
for(var i = 0; i < 10; i++){
    console.log(i);
}
```

for 반복문의 기본 형식은 위와 같다

0번째 부터 시작해서 i가 10보다 작으면 아래 코드를 실행하고 i를 +1해준다.

그럼 아까 작성한 js 중 3번이나 똑같은 코드가 반복되는데&#x20;

이걸 반복문을 쓰면 또 줄일 수 있을 것 같다.&#x20;

{% code title="app.js" %}

```javascript
for (let i = 0; i<3; i++){
    tabBtn.eq(i).on('click', function (){
        tabBtn.removeClass('orange');
        tabContent.removeClass('show');
        tabBtn.eq(i).addClass('orange');
        tabContent.eq(i).addClass('show');

    })
}
```

{% endcode %}

위에 반복문에서 let을 쓰는 이유 ?&#x20;

지난번 변수 선언 때의 var let const를 잘생각해보면 알 수 있다.&#x20;

## for 반복문에서 var는 안되고 let은 가능한 이유?

위의 반복문에서 var로 하면 제대로 동작을 하지않고 let으로 하면 동작한다&#x20;

왜그럴까????

컴퓨터가 코드를 읽는 순서를 한번 따라가보면 이해가 쉽다.

1. 컴퓨터는 코드를 위에서 부터 읽는다.
2. for 반복문을 발견하고 반복실행한다.
3. 이벤트 리스너를 만나고 이벤트 리스너는 바로 실행하는 게 아니라 해당 버튼을 클릭할때 실행된다.
4. 그래서 이벤트리스너 내의 코드는 실행하지 않고 지나간다.
5. 그렇게되면 반복문은 끝나서 var i = 3이된다.
6. 반복문이 다 종료되고 이후에 사용자가 버튼을 클릭하면 이제서야 이벤트리스너 안의 코드를 실행한다.
7. 반복문을 실행하려고 보니 현재 var i = 3이네??&#x20;

<pre class="language-javascript"><code class="lang-javascript">tabBtn.eq(3).on('click', function (){
<strong>    tabBtn.removeClass('orange');
</strong><strong>    tabContent.removeClass('show');
</strong>    tabBtn.eq(3).addClass('orange');
    tabContent.eq(3).addClass('show');
})
</code></pre>

이렇게 코드가 되는데 3번째 버튼은 없다.&#x20;

그래서 var는 오류나고  let은 다시 반복문돌때 0부터 시작하기때문에 정상동작한다.

지금까지 문법을 나열하고 뒤에가서 뭉뚱그려서 한번에 이것저것 다 해보는 방식이 아니라

하나씩 무언갈 만들어보면서 거기에 문법을 녹여내는 방식이다.

다른 문법과 마찬가지로 이런 문법이 이렇게 할 때 쓰이네&#x20;

또 다른데는 어떻게 쓰일까를 고민해보면 좋다.
