jQuery가 오래 사랑받은 이유 중 하나가 효과 메서드입니다. 한 줄로 요소를 부드럽게 나타내고 접을 수 있기 때문입니다. 이 글은 기본 메서드를 하나씩 쌓아 마지막에 동작하는 아코디언 메뉴를 완성합니다.
보이기와 감추기, 그리고 시간 주기
가장 기본은 세 개입니다. 인자를 주지 않으면 즉시 바뀌고, 밀리초 단위 숫자를 주면 그 시간 동안 서서히 바뀝니다. 1000이 1초입니다.
$('#noteBox').hide(); // 즉시 사라짐
$('#noteBox').show(400); // 0.4초에 걸쳐 나타남
$('#noteBox').toggle('slow');// 보이면 감추고, 감춰졌으면 보임
'slow'는 600, 'fast'는 200과 같습니다. hide()는 요소에 display: none을 직접 넣기 때문에 CSS 파일의 지정보다 우선합니다. 반대로 show()는 감추기 전 상태를 그대로 되돌려 줍니다.
fade와 slide — 어떤 상황에 무엇을 쓸까
둘 다 부드럽게 사라지지만 움직이는 방향이 다릅니다.
| 메서드 | 변하는 값 | 어울리는 자리 |
|---|---|---|
fadeIn / fadeOut |
투명도 | 알림 문구, 팝업 |
fadeToggle |
투명도 (왕복) | 껐다 켜는 안내문 |
slideDown / slideUp |
높이 | 접히는 상세 설명 |
slideToggle |
높이 (왕복) | 아코디언, 더보기 영역 |
$('#saveMsg').fadeIn(200).delay(1500).fadeOut(400);
$('#courseDetail').slideToggle(300);
첫 줄의 delay는 다음 효과 전에 잠깐 쉬라는 뜻입니다. 다만 delay는 효과에만 통하고 css나 text 같은 즉시 실행 메서드에는 적용되지 않습니다.
animate로 원하는 값을 직접 움직이기
준비된 효과로 부족하면 animate로 CSS 값을 직접 바꿀 수 있습니다. 마지막에 함수를 붙이면 애니메이션이 끝난 뒤 실행할 일을 지정하는데, 이것을 콜백이라고 부릅니다.
$('#noteBox').animate({
width: '480px',
opacity: 0.9,
marginTop: '+=20'
}, 500, function () {
$(this).addClass('expanded'); // 끝난 뒤 실행됩니다
});
규칙이 두 가지 있습니다. 첫째, 숫자로 된 속성만 움직입니다. 너비와 여백, 투명도는 되지만 배경색은 되지 않습니다. 색을 부드럽게 바꾸려면 CSS transition에 맡기고 jQuery는 클래스만 붙이는 편이 낫습니다. 둘째, 속성 이름의 하이픈이 사라지고 뒷글자가 대문자가 됩니다. margin-top은 marginTop이며, '+=20'은 현재 값에서 더하라는 뜻입니다.
효과가 밀리는 이유 — 큐와 stop
jQuery는 효과 명령을 받으면 곧바로 실행하지 않고 줄을 세워 하나씩 처리합니다. 이 줄을 큐라고 부릅니다.
// 마우스를 빠르게 여러 번 올렸다 내린 경우
$('#menuBtn').on('mouseenter', function () { $('#subMenu').slideDown(300); });
$('#menuBtn').on('mouseleave', function () { $('#subMenu').slideUp(300); });
마우스를 다섯 번 왕복시키면 명령 열 개가 줄을 섭니다. 그래서 손을 뗀 뒤에도 메뉴가 혼자 펄럭입니다. 새 효과 전에 대기 중인 명령을 지워야 합니다.
$('#subMenu').stop(true, true).slideDown(300);
첫 번째 true는 “밀린 명령을 모두 버려라”, 두 번째 true는 “지금 하던 것은 끝난 상태로 만들어라”라는 뜻입니다. 두 번째를 false로 두면 중간에 멈춘 높이 그대로 굳어 버립니다.
실전 — 아코디언 메뉴 완성하기
배운 것을 모아, 질문을 누르면 답이 펼쳐지고 다른 답은 접히는 메뉴를 만들겠습니다.
<div id="faqList">
<h4 class="faq-q">지금도 배울 가치가 있나요?</h4>
<div class="faq-a">기존 사이트 유지보수에 쓰입니다.</div>
<h4 class="faq-q">순수 자바스크립트가 먼저인가요?</h4>
<div class="faq-a">기본 문법은 먼저 익히는 편이 좋습니다.</div>
</div>
$(function () {
$('.faq-a').hide();
$('#faqList').on('click', '.faq-q', function () {
var $answer = $(this).next('.faq-a');
// 나를 뺀 나머지는 접기
$('.faq-a').not($answer).stop(true, true).slideUp(200);
$('.faq-q').not(this).removeClass('open');
// 나는 열고 닫기를 번갈아
$answer.stop(true, true).slideToggle(200);
$(this).toggleClass('open');
});
});
항목이 나중에 추가돼도 동작하도록 jQuery 이벤트에서 다룬 위임 방식으로 등록했습니다. $(this).next()로 누른 질문의 바로 다음 답만 집었으니 항목이 늘어나도 코드는 그대로입니다.
효과 메서드의 인자와 기본값은 jQuery 메서드 레퍼런스에서, next와 not 같은 탐색 방법은 jQuery 선택자에서 확인할 수 있습니다.
핵심 정리
- 세 갈래 — 즉시 처리는
show·hide, 투명도는fade, 높이는slide계열입니다. - animate — 숫자로 된 CSS 값만 움직이며, 속성 이름은
marginTop처럼 붙여 씁니다. - 콜백 — 효과가 끝난 뒤 실행할 코드는 마지막 인자에 함수로 넘깁니다.
- 큐 — 효과 명령은 줄을 서므로 반복 조작 시
stop(true, true)로 밀린 것을 비웁니다. - 색상 변화 —
animate로는 불가능하므로 CSStransition과 클래스 전환을 씁니다.