jQuery / Method / .fadeToggle() - 보이는 요소는 보이지 않게, 보이지 않는 요소는 보이게 하는 메서드
jQuery의 .fadeToggle()은 보이는 요소를 서서히 숨기고 숨긴 요소를 서서히 표시합니다. 여러 요소를 선택하면 집합 전체를 한 상태로 맞추는 것이 아니라 각 요소가 자기 표시 상태를 반대로 바꿉니다. 항상 표시하거나 항상 숨겨야 한다면 각각 .fadeIn(), .fadeOut()을 사용합니다.
요소별 토글과 실행 인수 이해하기
.fadeToggle() 공식 문서의 형식은 .fadeToggle(duration, easing, complete)이며 선택 인수는 생략할 수 있습니다. duration은 진행 시간으로, 생략하면 400밀리초, "fast"는 200, "slow"는 600입니다. 숫자가 크면 더 천천히 바뀌며 시작 전에 기다리는 시간이 아닙니다.
easing의 기본값은 swing이고 일정한 진행에는 .fadeToggle(800, "linear")처럼 시간 뒤에 linear를 지정합니다. linear만 시간 자리에 넣는 방식으로 easing을 지정하지 않습니다. complete는 표시와 숨김 어느 방향이든 해당 요소의 효과가 끝난 뒤 실행합니다.
| 메서드 | 목적 | one 표시·two 숨김에서 완료 후 |
|---|---|---|
| .fadeToggle() | 각 요소 상태 반전 | one 숨김, two 표시 |
| .fadeIn() | 표시하는 방향 | 둘 다 표시 |
| .fadeOut() | 숨기는 방향 | 둘 다 숨김 |
.fadeIn()·.fadeOut()과 달리 토글을 두 번 완료하면 원래 상태로 돌아갑니다. 숨김 완료 시에는 display: none이 되어 배치 공간도 없어지지만, 요소를 DOM에서 삭제하지는 않습니다.
반대 상태의 두 패널을 바꾸는 전체 예제
전체 코드를 UTF-8의 fadetoggle-demo.html로 저장하고 브라우저에서 엽니다. 공식 jQuery 전체 파일을 CDN(Content Delivery Network, 콘텐츠 전송 네트워크)에서 읽을 인터넷 연결이 필요하며 별도 설치는 없습니다. effects가 없는 slim 파일은 이 예제에 사용할 수 없습니다.
코드는 4.0.0을 사용합니다. 두 패널의 상태 반전, linear 진행, 완료 집계, 연속 입력 제한과 초기화 후 재실행을 3.7.1과 4.0.0에서 확인했습니다. one은 처음 보이고 two는 CSS로 숨깁니다. 실습 버튼은 패널 밖에 있어 패널이 숨겨져도 사용할 수 있습니다.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Toggle each tile's visibility</title>
<style>
body { font: 16px/1.6 sans-serif; margin: 24px; }
.tile { padding: 20px; margin: 12px 0; background: #e4f2ef; }
#two { display: none; }
button, select { padding: 8px; margin: 4px; }
</style>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
</head>
<body>
<h1>Toggle each tile's visibility</h1>
<label for="duration">Duration:</label>
<select id="duration"><option value="800">800 ms</option><option value="200">200 ms</option></select>
<label><input type="checkbox" id="instant"> Toggle instantly</label>
<button type="button" id="toggle" aria-controls="one two">Toggle both</button>
<button type="button" id="reset">Reset</button>
<div id="tiles">
<div class="tile" id="one">Tile one starts visible</div>
<div class="tile" id="two">Tile two starts hidden</div>
</div>
<p id="result" aria-live="polite"></p>
<script>
$(function () {
const $tiles = $("#tiles > .tile");
let busy = false;
let completed = 0;
function report() {
const ids = $tiles.filter(":visible").map((_, tile) => tile.id).get().join(", ");
$("#result").text(`visible=${ids || "none"} | completed=${completed}`);
}
$("#toggle").on("click", function () {
if (busy || !$tiles.length) return;
busy = true;
completed = 0;
const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
const duration = $("#instant").prop("checked") || reduce
? 0 : Number($("#duration").val());
$("#result").text("animating | completed=0");
$tiles.fadeToggle(duration, "linear", function () {
completed++;
if (completed === $tiles.length) {
busy = false;
report();
}
});
});
$("#reset").on("click", function () {
$tiles.stop(true, true).hide().css("opacity", "");
$("#one").show();
busy = false;
completed = 0;
report();
});
report();
});
</script>
</body>
</html>
처음에는 one만 보이며 결과는 다음과 같습니다.
visible=one | completed=0
- Toggle instantly를 끄고 800 ms에서 Toggle both를 누릅니다. one은 사라지고 two는 나타나며 진행 중에는 animating을 표시합니다.
- 둘 다 완료하면
visible=two | completed=2입니다. completed는 두 요소의 완료 횟수이며 클릭 횟수가 아닙니다. - 한 번 더 눌러 완료하면
visible=one | completed=2로 돌아옵니다. 각 실행 시작 때 완료 수를 0으로 초기화합니다. - 200 ms로 바꾸고 실행하면 같은 상태 반전이 더 빠르게 진행됩니다. 진행 중의 추가 클릭은 이 예제의 busy 검사로 무시합니다.
- 진행 도중 Reset을 누르면 one 표시·two 숨김과
completed=0으로 돌아갑니다. 다시 Toggle both를 눌렀을 때 two가 보이는지까지 확인합니다. - Toggle instantly 또는 동작 줄이기 설정이 적용되면 시간을 0으로 하여 효과 없이 반전합니다. 네이티브 button은 포커스 후 Enter로도 실행할 수 있습니다.
완료 집계와 연속 입력 방식을 구분하기
.fadeToggle() 호출은 완료될 때까지 다음 JavaScript를 막지 않습니다. 완료 콜백은 선택된 요소마다 한 번 실행되므로, 예제는 completed가 $tiles.length에 도달했을 때만 현재 보이는 ID를 표시합니다. 숨기는 효과도 정상적으로 끝나면 완료에 포함합니다.
busy는 jQuery가 제공하는 인수가 아니라 실습에서 만든 실행 중 표시입니다. 시작할 때 참, 모두 완료하면 거짓으로 바꿉니다. 진행 중 다시 눌러도 반대로 즉시 전환하지 않고 현재 효과를 먼저 끝내는 설계입니다. 여러 번 요청해 효과가 대기열에 쌓이는 방식과 구분합니다.
원하는 동작이 ‘열기 버튼을 누르면 항상 열림’이라면 토글보다 표시 방향을 명시하는 메서드가 적합합니다. 여러 패널의 초기 상태가 달라도 모두 같은 상태로 맞춰야 할 때도 .fadeIn() 또는 .fadeOut()을 선택합니다.
초기화 순서와 문제 해결
Reset의 .stop(true, true)에서 첫 true는 대기열 제거, 둘째 true는 현재 효과를 즉시 끝내는 뜻입니다. 완료 콜백도 이때 실행될 수 있으므로, 그 뒤에 두 패널을 숨기고 one만 표시한 다음 busy와 completed를 초기화하고 최종 결과를 출력합니다. 초기 상태 복원 뒤에 예전 완료가 값을 바꾸지 않도록 순서를 지킵니다.
토글은 진행 중 상태도 추적하므로, 단순히 중간에 멈춘 뒤 CSS만 초기처럼 바꾼 결과를 다음 실행까지 확인하지 않고 완료로 판단하면 안 됩니다. 이 예제는 현재 효과를 마무리한 후 알려진 보임 상태를 명시적으로 복원하며, 초기화 직후와 다음 반전 결과를 모두 확인했습니다.
예상과 반대로 보이면 one·two의 초기 CSS와 현재 display를 확인합니다. 효과가 없으면 즉시 전환 옵션과 동작 줄이기 설정을, 메서드 오류가 나면 전체 jQuery 파일 로딩과 Console을 확인합니다. 선택 결과가 비면 요소별 완료도 없으므로 예제는 .length를 검사한 뒤 시작합니다.




