jQuery / Método / .fadeToggle() - Invertir la visibilidad de cada elemento
En jQuery, .fadeToggle() oculta gradualmente los elementos visibles y muestra los ocultos. Con varios elementos, cada uno invierte su estado; el conjunto no se vuelve uniformemente visible u oculto. Usa .fadeIn() para mostrar siempre y .fadeOut() para ocultar siempre.
Inversión por elemento y argumentos
La documentación de .fadeToggle() indica .fadeToggle(duration, easing, complete) con argumentos opcionales. duration es tiempo de ejecución: 400 ms por defecto, 200 para "fast" y 600 para "slow". Los números mayores ralentizan, sin esperar antes de comenzar.
easing usa swing por defecto. Para avanzar constantemente, indica linear tras la duración, como .fadeToggle(800, "linear"), no solo en su posición. complete se ejecuta cuando termina el efecto de cada elemento, en cualquiera de las direcciones.
| Método | Objetivo | Desde one visible y two oculto |
|---|---|---|
| .fadeToggle() | Invertir cada estado | one oculto, two visible |
| .fadeIn() | Mostrar | Ambos visibles |
| .fadeOut() | Ocultar | Ambos ocultos |
A diferencia de .fadeIn() y .fadeOut(), dos inversiones terminadas vuelven al estado inicial. Ocultar termina con display: none y quita espacio del diseño sin eliminar el elemento DOM.
Ejemplo completo con estados opuestos
Guarda todo el código en UTF-8 como fadetoggle-demo.html y ábrelo en el navegador. No requiere instalación, pero sí internet para cargar el archivo oficial completo de jQuery desde su red de distribución de contenidos, o CDN. Slim excluye efectos y no sirve para este ejemplo.
Usa 4.0.0. Inversión, avance lineal, recuento de finalizaciones, entradas repetidas y nueva ejecución tras Reset se comprobaron con 3.7.1 y 4.0.0. one empieza visible y CSS oculta two. Los controles quedan fuera.
<!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>
Al principio solo se ve one:
visible=one | completed=0
- Deja Toggle instantly desmarcado, elige 800 ms y pulsa Toggle both. one desaparece y two aparece; animating indica la transición.
- Al terminar ambos, aparece
visible=two | completed=2. completed cuenta elementos terminados, no clics. - Otra inversión terminada devuelve
visible=one | completed=2. Cada activación aceptada reinicia primero el contador en cero. - 200 ms hace la misma inversión más rápido. Los clics durante el efecto se ignoran mediante busy en este ejemplo.
- Reset durante la ejecución restaura one visible, two oculto y completed=0. Comprueba que el siguiente Toggle both muestra two.
- Toggle instantly o la preferencia de movimiento reducido usa cero. El botón nativo también responde a Intro al tener el foco.
Finalización y política de entradas repetidas
.fadeToggle() no bloquea el JavaScript siguiente hasta terminar. Su función de finalización se ejecuta por elemento; solo se muestran los ID visibles cuando completed alcanza $tiles.length. Terminar de ocultar también cuenta como finalización normal.
busy es una variable creada para el ejercicio, no un argumento jQuery. Pasa a verdadero al empezar y a falso al terminar ambos. Este diseño ignora entradas adicionales en lugar de invertir de inmediato a mitad del efecto. Difiere de acumular todas las peticiones en una cola.
Si un botón Abrir debe abrir siempre, elige explícitamente mostrar. Para igualar paneles con visibilidades distintas, usa .fadeIn() o .fadeOut() en lugar de invertirlos.
Orden de reinicio y resolución de problemas
En .stop(true, true) de Reset, el primer true vacía la cola y el segundo termina el efecto actual inmediatamente. Las funciones de finalización pueden ejecutarse entonces. Solo después se ocultan ambos, se muestra one, se reinician busy y completed y se informa del estado final. El orden evita que una finalización anterior sobrescriba lo restaurado.
Los efectos de alternancia siguen su estado en curso. Detener a mitad y cambiar CSS para parecer inicial no basta sin comprobar la siguiente ejecución. Aquí se termina el efecto actual, se restaura visibilidad conocida y se comprueban Reset y la siguiente inversión.
Ante expectativas invertidas, revisa CSS inicial y display actual. Sin movimiento, comprueba modo instantáneo y movimiento reducido; con errores de método, archivo completo y Console. Un conjunto vacío no tiene finalización por elemento, por lo que se comprueba .length al empezar.




