탭기능

셀라문·2022년 3월 29일
0

JS UI

목록 보기
7/15

탭의 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 기능 완성.

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을 쭉 읽고 찾아야해서 오래걸리는 것
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 (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');
  })

};

전에 만들었던 탭기능 함수로 축약해보기

함수쓰면 긴 코드를 짧은 단어하나로 축약할 수 있다고 했습니다.
그래서 탭만들 때 썼던 4줄의 코드를 함수로 축약해볼 것입니다.
별 이유는 없고 깔끔해보일 것 같으니까요

함수로 넣으면
1. 재사용이 편리하고
2. 나중에 남이 읽었을 때도 뭔가 이해가 쉬울 수 있습니다.

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

  $('.tab-button').eq(i).on('click', function(){
    탭열기(i)
  })

});


function 탭열기(구멍){
  $('.tab-button').removeClass('orange');
  $('.tab-button').eq(구멍).addClass('orange');
  $('.tab-content').removeClass('show');
  $('.tab-content').eq(구멍).addClass('show');
}

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

지금 탭을 만들 때 이벤트리스너를 3개나 부착했습니다. (버튼이 3개니까)
잘 생각해보면 이벤트리스너 1개만 써도 충분히 기능구현이 가능합니다.

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

버튼 뭘 누르든 간에 <ul class="list">에 붙은 이벤트리스너도 동작하니까요.

왜냐면 이벤트버블링이 항상 일어나기 때문입니다.

$('.list').click(function(){
  지금 누른게 버튼 0이면 탭열기(0) 실행
  지금 누른게 버튼 1이면 탭열기(1) 실행
  지금 누른게 버튼 2이면 탭열기(2) 실행
})

그래서 이렇게 탭기능 만들어도 잘 동작한다는 소리입니다.
(jQuery 셀렉터엔 .click() 이라고 써도 간단하게 click 이벤트리스너 부착가능)

Q. 왜 굳이 이벤트리스너 줄여서 코드 짜냐고요?

  • 버튼이 몇십개 있다면 이렇게 짜는게 덜 복잡하고

  • 이벤트리스너를 줄이면 램용량을 절약할 수 있습니다. 성능개선의 일환입니다.

완성

$('.list').click(function(e){
  if (e.target == document.querySelectorAll('.tab-button')[0] ){
    탭열기(0)
  }
  if (e.target == document.querySelectorAll('.tab-button')[1] ){
    탭열기(1)
  }
  if (e.target == document.querySelectorAll('.tab-button')[2] ){
    탭열기(2)
  }
})

function 탭열기(){
 $('.tab-button').removeClass('orange');
  $('.tab-button').eq(e).addClass('orange');
  $('.tab-content').removeClass('show');
  $('.tab-content').eq(e).addClass('show');
}

dataset 문법으로 한 줄로 해결하기

<div data-데이터이름="값"></div>
html 안에 유저 몰래 정보를 숨겨놓을 수 있습니다.

데이터이름 아무렇게나 작명하고 값도 넣으면 됩니다.
일반 유저들은 모름

document.querySelector().dataset.데이터이름;
이러면 html 요소에 숨겨놨던 데이터가 이 자리에 남습니다.
출력해보면 진짜로 아까 숨겨놓은 값이 남습니다.

이런 잡기술을 알고있으면 위에서 만들었던 코드를 조금 더 짧게 축약가능합니다.

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

▲ 우선 탭의 버튼들에 이렇게 데이터를 숨겨봅시다.

$('.list').click(function(){
  탭열기(지금누른버튼에 숨어있던 data-id)
});

▲ 이렇게 코드짜면 굳이 if문이 필요없이 한 줄로 해결

$('.list').click(function(e){
  탭열기(e.target.dataset.id)
});

▲ 지금누른 버튼을 찾고 싶으면 e.target이고
거기 숨어있는 data-id 꺼내고 싶으면 .dataset.id 붙이면 됩니다.

그래서 위처럼 코드짜도 탭기능 완성인 것입니다.

profile
취미로 하는 공부기록장

0개의 댓글