자바스크립트

자바스크립트>탭기능 만들며 for반복문

연습노트 2024. 7. 8. 23:43
 

 

이렇게 생긴 UI를 탭이라고 합니다.

어떻게 만드냐면 그냥 UI 만드는 step 그대로 따라가면 완성입니다. 

버튼3개, div 박스 3개 만들어두고

버튼누르면 거기 맞는 div박스를 보여주면 끝입니다. 

 

 

 

시간아까우니 디자인은 미리 해옴

 

설명하다
 
<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>

<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>스펙설명입니다. Information</p>
  </div>
  <div class="tab-content">
    <p>배송정보입니다. Shipping</p>
  </div>
</div> 

 

아무데나 복사붙여넣기하면 탭나옴 

어떻게 만들었는지 설명하자면 

1. <li> 태그로 버튼 3개 만들었습니다.

2. <div> 태그로 박스 3개 만들었습니다.

3. 제가 만든 orange 클래스명을 추가하면 버튼누른듯한 효과를 줄 수 있습니다 (매우편리) 

4. 제가 만든 show 클래스명을 추가하면 박스를 보여줄 수 있습니다 (역시편리)

 

 

[collapse]

 

 

 

 

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

 

그니까 자바스크립트 코드가 너무 길고 복잡하면 다른 파일로 뺄 수 있습니다.

작업폴더에다가 어쩌구.js  파일 만들고 거기다가 열심히 코드짠 다음에 

그 코드가 필요한 html 파일에서

<script src="어쩌구.js"></script>

이렇게 쓰면 끝입니다. 

그럼 js 파일에 있던 코드가 저 위치로 복붙됩니다. 

 

js 파일이 폴더 안에 숨어있으면 src="폴더명/어쩌구.js" 하면 되겠죠 

 

 

 

 

 

 

첫 버튼부터 기능개발해보기

 

버튼이 3개나 있으니까 "버튼3개를 어떻게 한 번에 개발하지?" 부터 생각하는 분들이 있는데 

그러면 금방 망하기 때문에 가장 간단하고 쉬운거 하나부터 만드는게 좋은 습관입니다. 

우선 첫 버튼만 기능개발해봅시다. 

탭의 0번 버튼 누르면 무슨 일이 일어나야합니까?

 

- 버튼0 누르면 

- 버튼0에 orange 클래스명 부착

- 박스0에 show 클래스명 부착

이러면 끝인 것 같은데 

근데 그것만 짜면... 

 

 

 

 

 

▲ 버튼0 눌렀을 때 이렇게 보일 것 같군요 

그래서 기존에 붙어있던 orange, show 라는 클래스는 제거해야합니다. 

 

- 버튼0 누르면

- 버튼0,1,2에 붙어있던 orange 클래스명 전부 제거하라고 코드 3줄 짜기

- 버튼0에 orange 클래스명 부착

- 박스0,1,2에 붙어있던 show 클래스명 전부 제거하라고 코드 3줄 짜기

- 박스0에 show 클래스명 부착

 

이렇게 코드짜면 버튼0 기능 완성일 것 같습니다.

 

 

 

Q. 왜 버튼0,1,2에 붙어있던 orange 클래스명 전부 제거하라고 코드 3줄이나 짬?

A. 무슨 버튼에 orange가 들어있을지 모르니까

그냥 귀찮아서 3개 버튼에 있는거 전부 제거하라고 코드짜면 간단하니까요 

 

 

 

 

 

 

 

 

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

 

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

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

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

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

 

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

이렇게 쓰면 됩니다.

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

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

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

 

 

그래서 가이드는 다 드렸으니 다음시간까지 버튼0 기능 완성해옵시다. 

쉬우니까 버튼1, 버튼2 기능도 만들어서 탭 완성해오면 됩니다. .

 

 

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

한글로 써놓고 번역만 잘 했을 뿐입니다

여기까지 하면 버튼0 기능이 완성됩니다.

querySelectorAll() 쓰는 분들은 뒤에 [0] 이런거 붙이는거 잊지마십시오 

 

 

Q. 어 왜 버튼1, 버튼2는 눌러도 아무 반응이 없죠?

A. 컴퓨터는 죄가 없습니다 여러분이 코드를 그렇게 짠것일 뿐

버튼0 기능만 개발했으니 버튼1 버튼2 기능도 알아서 개발하면 됩니다.

 

 

 

 

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


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

이거도 밑에 추가하니 잘되는군요 탭기능 완성 

 

 

[collapse]

 

 

 

 

 

좋은 관습 : 반복적인 셀렉터는 변수에 넣어서 쓰기

 

위 숙제에서 보면 비슷한 셀렉터가 매우 많이 등장합니다.

셀렉터 문법은 기본적으로 작동시간이 오래걸립니다.

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

html이 길고 복잡할 수록 더 오래걸립니다. 

그래서 저게 반복적으로 등장하면 그냥 변수에 넣어서 쓰십시오. 

querySelector 도 마찬가지입니다. 

 

 

설명하다
 
var 버튼 = $('.tab-button');

버튼.eq(0).on('click', function(){
  버튼.removeClass('orange');
  버튼.eq(0).addClass('orange');
  $('.tab-content').removeClass('show');
  $('.tab-content').eq(0).addClass('show');
})

이런 식으로 바꿔버리면 셀렉터 3번 쓰던걸 1번으로 줄일 수 있어서 성능적 이점이 있겠군요. 

하지만 굳이 성능 이런거 따지는 사람 별로 없음

 

 

 

 

 

 

코드 복붙하고 싶으면 for 반복문

 

지금 탭기능만든거 잘 보면 비슷한 코드덩어리 6줄이 3번이나 반복되고 있습니다. 

비슷한 코드를 발견하면 굳이 손수 복사붙여넣기할 필요없이 for 반복문 쓰면 쉽게 복붙해줍니다. 

 

for (횟수){
  복붙할 코드
}

이렇게 쓰면 안의 코드를 복붙해줍니다.

실은 복붙이라기보다 반복실행이 맞는데 결과는 똑같으니 복붙이라고 합시다.

횟수넣는 부분은 이렇게 써야합니다. 

 

 

for (var i = 0; i < 3; i++) {
  console.log('안녕')
}

이러면 console.log('안녕') 이게 3번 복사 붙여넣기 됩니다.

왜 3번이냐면 

i를 0부터 시작해서 / i에 1씩 더해가면서 복붙해라 / 근데 i < 3 까지

라는 뜻이라 3번입니다. 

이해하기 싫으면 외워써도 되긴 합니다. 

 

 

 

 

▲ 표로 그리면 이렇게 되겠군요. 

 

 

 

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

진짜 i가 그렇게 변하는지 궁금하면 출력해보면 됩니다. 

출력해보면 진짜로 0, 1, 2로 변하는군요. 

그리고 i가 3이 될 때 복사붙여넣기를 중지해줍니다. 

 

 

 

 

for (var i = 0; i < 5; i++) {
  console.log('안녕')
}

그럼 이건 안녕이 몇번 출력될까요?

답은

 

 

for (var i = 3; i < 6; i++) {
  console.log('안녕')
}

그럼 이건 안녕이 몇번 출력될까요?

답은

 

 

 

 

 

for 반복문으로 탭기능 코드 줄여보기

 

그래서 코드가 너무 길거나 그러면 for 쓰면 됩니다. 

for 문법은 언제나 옵션일 뿐이라 쓰기싫으면 안써도 됩니다 안써도 모든기능 구현가능 

하지만 배운 기념으로 아까 길게 짰던 탭기능을 for 이용해서 간단하게 만들어봅시다.

 

 

 

설명하다
 
$('.tab-button').eq(0).on('click', function(){
  $('.tab-button').removeClass('orange');
  $('.tab-button').eq(0).addClass('orange');
  $('.tab-content').removeClass('show');
  $('.tab-content').eq(0).addClass('show');
})

(밑에 비슷한거 2개 더 있음)

▲ 지금만든 탭기능은 이 덩어리가 3번이나 반복됩니다.

반복될 때 마다 0 부분이 1과 2로 바뀌긴 하지만 아무튼 비슷하니까

반복문안에 넣어서 코드를 쉽게 복사 붙여넣기해봅시다. 

 

 

 

설명하다
 
for (var i = 0; i < 3; i++){

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

});

▲ 이러면 성공이군요 안에 있던 코드가 3번 복사붙여넣기 됩니다. 

하지만 복붙할 때마다 0부분을 1로 바꾸고 2로 바꾸고 그래야합니다. (그래야 아까 코드랑 똑같이 생김)

그래서 반복문 안에 0이라고 하드코딩해놓는게 아니라 

0 대신 반복문이 진행되며 0, 1, 2로 차례로 바뀌는 변수 를 넣는게 어떨까요

그런게 있긴 합니까 

i 라고 배운거 같은데요 i 출력해보니까 복붙할 때 마다 0, 1, 2로 차례로 바뀝니다. 

 

 

 

 

설명하다
 
for (var i = 0; i < 3; i++){

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

});

▲ 이러면 완성 

아까랑 똑같이 탭기능이 동작하겠군요

 

Q. 전 안되는데요

A. 실은 for 반복문 사용할 때 변수를 var i 말고 let i로 바꿔야 잘됩니다.

let으로 바꾸면 탭 완성입니다.

 

 

 

var 쓰면 안되고 let 쓰면 잘되는 이유는

 

원리가 궁금하면 잘 들어보면 됩니다.

원리를 알면 코드 알아서 잘짤 수 있습니다. 

 

 

설명하다
 
for (var i = 0; i < 3; i++){

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

});

위 코드는 제대로 작동하지 않는데 

컴퓨터의 입장이 되어서 위 코드를 읽으면 이해가 쉽습니다.

 

0. 컴퓨터는 위에서부터 한줄한줄 코드를 해석합니다.

1. for 반복문을 발견해서 안에 있는 코드를 반복실행하려고 합니다.  

2. 이벤트리스너를 만납니다. 이벤트리스너 안의 코드는 바로 실행안됩니다. 사용자가 버튼을 클릭시 실행되는 코드입니다.   

그래서 이벤트리스너 내의 4줄 코드는 아직 실행하지 않고 지나갑니다.  

그런 식으로 반복문 안의 코드를 3번 실행합니다.

 

3. 그리고 반복문 끝나서 var i 변수는 3이 되어있습니다. 

4. 반복문이 다 돌고난 후 한참 후에, 사용자가 버튼0을 클릭합니다. 그럼 컴퓨터는 이벤트리스너 안의 코드 4줄을 실행시켜야겠군요

 

5. 근데 i 라는 변수를 발견합니다. 

$('.tab-button').eq(i).addClass('orange');
$('.tab-content').eq(i).addClass('show');

▲ 컴퓨터는 변수를 발견하면 근처에서 변수를 찾아서 채우려는 습성이 있습니다.

그래서 주변을 살펴보니 반복문을 다 돌고난 var i라는 변수가 3이 되어있는걸 찾아냅니다. 그거 씁니다.

(반복문이 다 돌고난 후라서 var i라는 변수는 3이 되어 남아있습니다.)

 

6. 하지만 $('.tab-button').eq(3) 이런건 없습니다. (4번 버튼은 없잖습니까)

7. 그래서 에러를 냅니다. 

 

근데 let 변수를 사용하면 변수포스트잇이 for 바깥이 아니라 안쪽에 생성됩니다.

더 쉽게 그림으로 비교해보자면 

 

 

 

 

 

for 안에서 var i = 0 쓰면

- var 변수는 범위가 function입니다.

- var i 들어있는 포스트잇은 for 바깥에 생성됩니다. 

 

for 안에서 let i = 0 쓰면

-let 변수는 범위가 { } 입니다.

- let i 들어있는 포스트잇은 for 안쪽에 3개 생성됩니다.

그리고 컴퓨터는 변수가져다쓸 때 가까운거 가져다 쓰려고합니다.

 

 

그냥 그렇게 동작해서 그렇습니다.

알 필요는 없는데 이런 원리같은거 알면 나중에 혼자 코드짤 때 많은 도움이 됩니다. 

 

 

 

[collapse]

 

 

 

 

 

 

확장성있는 코드로 바꾸기

 

"제 코드가 좋은 코드인지 모르겠어요" 라고 묻는 분들이 많은데

1. 원하는 기능이 잘 구현되었는가

2. 확장성좋은가

3. 나중에 관리가 쉬울 것인가

4. 성능문제 없는가

이런거 체크해보면 됩니다. 그럼 자연스럽게 좋은 코드임  

 

그래서 위에서 짠 탭기능도 확장성을 한번 잡아봅시다.

 

Q. 지금 탭이 3개면 잘 동작하지만 4개 5개가 되면 잘 동작하지 않습니다.

탭이 4개나 5개로 바뀌어도 알아서 잘 동작하는 코드가 되려면 현재 코드를 어떻게 수정하면 될까요? 

1시간 고민해도 모르겠으면 펼쳐봅니다

 

지금은 반복문에 3이라고 하드코딩해놔서 

무조건 3번 코드가 복붙이 되어서 

탭이 몇개든 간에 앞의 3개만 잘 동작합니다. 

3이라는 숫자 대신 "지금 html에 있는 탭 버튼의 갯수"를 넣으면 잘 되지않을까요 

html 갯수 세는 법은 안배웠으니 구글찾아보면 나올듯요 

 

[collapse]
이건 답

 

 

설명하다
 
for (let i = 0; i < $('.tab-button').length; i++){

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

});

여러개 찾아주는 셀렉터로 html 요소 찾은 다음에 .length 붙이면 갯수를 세어줍니다.

저러면 이제 버튼이 5개면 반복문도 5번 돌겠고 그럼 버튼마다 잘 기능이 실행되겠네요

 

 

[collapse]

 

 

 

 

오늘의 결론 : 

for 문법의 용도를 잘 기억해둡시다.  

비슷한 코드들을 직접 복붙하는게 귀찮으면 for 반복문을 쓰는 것일 뿐이지 

for 부터 써놓고 무슨 코드를 채울지 고민하는 짓을 하면 안됩니다. 그건 고수되면 하십쇼