이벤트버블링을 알고계시면 이벤트리스너를 줄여가며 개발할 수도 있습니다.
필수나 그런건 아니고 알면 언젠가 도움되는 내용이기 때문에
전에 만들었던 탭기능을 다시 만들어봅시다. 원래 복습을 해야 실력이 느는 것임
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줄의 코드를 함수로 축약해볼 것입니다.
별 이유는 없고 깔끔해보일 것 같으니까요
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');
}
Q. 왜 구멍뚫음?
A. 함수로 코드를 싸맬 때 안에 변수가 들어있으면 변수를 전부 파라미터로 바꾸는게 좋습니다.
그래야 잘 동작합니다. 그래서 i 부분을 전부 파라미터로 바꿨습니다.
이제 함수 사용할 때
탭열기(0) 이러면 0번 탭이 열림
탭열기(1) 이러면 1번 탭이 열림
탭열기(2) 이러면 2번 탭이 열림
지금 탭을 만들 때 이벤트리스너를 3개나 부착했습니다. (버튼이 3개니까요)
근데 잘 생각해보면 이벤트리스너 1개만 써도 충분히 기능구현이 가능합니다.
버튼 3개의 부모인 <ul class="list">
여기에 이벤트리스너 1개만 있어도 탭기능만들 수 있을듯요
버튼 뭘 누르든 간에 <ul class="list">
에 붙은 이벤트리스너도 동작하니까요.
왜냐면 이벤트버블링이 항상 일어나기 때문입니다.
$('.list').click(function(){
지금 누른게 버튼 0이면 탭열기(0) 실행
지금 누른게 버튼 1이면 탭열기(1) 실행
지금 누른게 버튼 2이면 탭열기(2) 실행
})
그래서 이렇게 탭기능 만들어도 잘 동작한다는 소리입니다.
(jQuery 셀렉터엔 .click()
이라고 써도 간단하게 click 이벤트리스너 부착가능)
버튼이 몇십개 있다면 이렇게 짜는게 덜 복잡하고
이벤트리스너를 줄이면 램용량을 절약할 수 있습니다. 성능개선의 일환입니다.
그래서 위처럼 코드짜서 탭기능 완성해보도록 합시다.
$('.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 탭열기(){
생략
}
이러면 탭기능 잘됩니다
근데 이러나 저러나 코드 양은 똑같군요
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>
▲ 우선 탭의 버튼들에 이렇게 데이터를 숨겨봅시다. 따라하셈
그리고 아까 코드를 다시 살펴보면 if문이 3개였습니다.
버튼0 누르면 탭열기(0) 실행해주세요~
버튼1 누르면 탭열기(1) 실행해주세요~
버튼2 누르면 탭열기(2) 실행해주세요~
$('.list').click(function(){
탭열기(지금누른버튼에 숨어있던 data-id)
});
▲ 근데 이렇게 코드짜면 굳이 if문이 필요없이 한 줄로 해결아닙니까
맞습니다.
지금누른버튼에 숨어있던 data-id를 알려주는 코드같은게 있습니까
있습니다. 방금 배운듯
$('.list').click(function(e){
탭열기(e.target.dataset.id)
});
▲ 지금누른 버튼을 찾고 싶으면 e.target
이고
거기 숨어있는 data-id
꺼내고 싶으면 .dataset.id
붙이면 됩니다.
그래서 위처럼 코드짜도 탭기능 완성인 것입니다.
이전 코드가 좋으면 그거 쓰면 되고 취향것 쓰시길 바랍니다.
dataset 문법이 인터넷익스플로러 11+ 에서 동작하는데 그게 마음에 안들면
옛 브라우저까지 호환 잘되는 jQuery 함수 이용하는 방법도 있습니다.
$(셀렉터).data('데이터이름', '값')
이렇게 저장하고
$(셀렉터).data('데이터이름')
이렇게 출력합니다.
아마도, dataset을 사용했을 때, 가장 좋은 점은 e.target을 사용할 수 있다는 점이다.
e.target.dataset.id
그럼 해당 id 값이 0
이면, 0
을 출력해준다.
그런데, 그냥 id=0
이라면, 0
을 출력할 수는 없다.
이 점을 유의하고, 응용해보도록 하자!!
함수로 축약할 때 변수같은게 있으면 파라미터로 바꾸는게 좋음
이벤트리스너 줄이면 이점이 있음
dataset 잡기술 알면 이벤트리스너 적게 사용할 때 내가 뭐 눌렀는지 쉽게 파악할 수도 있음