jQuery / Reference / .slideToggle()

.slideToggle()는 요소의 세로 크기를 애니메이션으로 바꾸어 내용을 접기와 펼치기를 전환합니다. 보이는 요소는 숨기고 숨겨진 요소는 표시하므로 접이식 안내 영역에 사용할 수 있습니다.

문법과 적용 범위

$("#panel").slideToggle(400, "swing", function () {
  // 이 요소의 애니메이션이 완료된 뒤 실행합니다.
});
$("#panel").slideToggle({ duration: 400, easing: "linear" });

duration은 밀리초 단위의 시간이며 기본값은 400입니다. "fast"는 200, "slow"는 600밀리초에 해당합니다. 숫자가 클수록 천천히 끝납니다. easing은 진행 속도의 변화 방식으로 기본 swing은 속도가 변하고 linear는 일정한 속도로 진행합니다. complete 함수는 각 요소의 애니메이션이 완료된 뒤 호출되며 this는 해당 DOM 요소입니다. 메서드의 반환값은 jQuery 객체이므로 반환 즉시 애니메이션이 끝났다고 판단하면 안 됩니다. 처음 숨겨진 요소를 펼치는 예제에서는 display: none을 사용합니다. HTML hidden 속성이나 다른 강제 숨김 규칙을 함께 쓰면 표시를 방해할 수 있습니다.

jQuery 공식 문서의 .slideToggle() 정의와 인수에서 다른 호출 형태도 확인할 수 있습니다.

전체 실행 예제

아래 코드를 UTF-8 형식의 example.html 파일로 저장한 뒤 브라우저로 여세요. 예제는 jQuery 4.0.0 일반 빌드를 외부 주소에서 불러오므로 인터넷 연결이 필요합니다. 문서가 준비된 뒤 실행하도록 $(function () { ... }) 안에 코드를 작성했습니다.

<!doctype html>
<html lang="ko">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>jQuery slideToggle 예제</title>
  <style>
    body { margin: 24px; font-family: sans-serif; line-height: 1.6; }
    .marked { background: #fff0b3; border: 2px solid #835b00; }
    .active { color: #a00000; font-weight: bold; }
    button, input, select { font: inherit; }
    #output { white-space: pre-wrap; overflow-wrap: anywhere; }
  </style>
  <script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
</head>
<body>
<button id="run" type="button" aria-controls="panel" aria-expanded="false">전환</button>
<button id="reset" type="button">처음 상태로</button>
<div id="panel" class="marked" style="display: none;"><p>접이식 안내 내용입니다.</p></div>
  <p id="output" aria-live="polite"></p>
  <script>
    $(function () {
      $("#run").on("click", function () {
        const $button = $(this);
        const duration = window.matchMedia("(prefers-reduced-motion: reduce)").matches ? 0 : 400;
        $("#panel").stop(true, true).slideToggle(duration, "swing", function () {
          const visible = $(this).is(":visible");
          $button.attr("aria-expanded", String(visible));
          $("#output").text(visible ? "펼침 완료" : "접힘 완료");
        });
      });
      $("#reset").on("click", function () {
        $("#panel").stop(true, true).hide();
        $("#run").attr("aria-expanded", "false");
        $("#output").text("처음 상태");
      });
    });
  </script>
</body>
</html>

실행 결과 확인

처음에는 내용이 숨겨져 있습니다. 전환을 누르면 내용이 펼쳐지고 펼침 완료, 다시 누르면 접히고 접힘 완료가 표시됩니다. 처음 상태로 버튼은 진행 중인 효과를 정리하고 최초 표시 상태로 되돌립니다. 운영체제에서 동작 줄이기를 설정한 경우 이 예제는 duration을 0으로 정해 즉시 상태를 바꿉니다.

여러 요소의 완료를 한 번에 처리하기

$(".panel").slideToggle(400).promise().done(function () {
  console.log("모든 패널의 효과 완료");
});

class가 panel인 여러 요소가 있는 문서에서 사용할 수 있습니다. .promise()는 기본 fx 큐의 완료를 기다리며, 각 요소의 complete와 전체 완료 알림을 구분할 때 도움이 됩니다.

사용할 때 주의할 점

  • slim 빌드에는 효과 모듈이 없으므로 이 메서드를 사용할 수 없습니다. 예제처럼 일반 빌드를 사용하고 개발자 도구 Network에서 파일 로딩을 확인하세요.
  • 기본적으로 효과는 요소의 fx 큐에 쌓입니다. 빠른 연속 클릭을 처리하려고 .stop(true, true)를 사용하면 대기 효과를 비우고 진행 중 효과를 끝 상태로 보낸 뒤 새 효과를 시작합니다. 끝 상태로 보내는 과정에서 이전 완료 콜백도 호출될 수 있습니다.
  • 여러 요소를 선택하면 complete는 요소마다 실행됩니다. 전체 집합의 효과가 모두 끝난 뒤 한 번만 처리하려면 .promise().done()을 사용하세요.
  • 접을 영역 안에 키보드 포커스가 있다면 숨기기 전에 제어 버튼 등 보이는 곳으로 옮기는 처리를 검토하세요. 표시 효과만으로 접근성 상태나 포커스가 자동 관리되지는 않습니다.
  • 일정한 열림 상태로 맞춰야 하는 경우에는 무조건 반전하지 말고 .slideDown()이나 .slideUp()을 사용하세요. 서버 상태와 UI 상태가 다른 경우에 유용합니다.

효과의 큐 처리와 전체 완료 대기는 .stop() 공식 설명과 .promise() 공식 설명을 참고할 수 있습니다. 효과 모듈 포함 여부는 jQuery 일반·slim 빌드 안내에 구분되어 있습니다.

용도를 비교하려면 .slideUp()으로 접기, .slideDown()으로 펼치기을 참고하세요.