jQuery / Método / .fadeIn() - Mostrar elementos gradualmente

En jQuery, .fadeIn() muestra elementos ocultos aumentando gradualmente su opacidad. En .fadeIn(800), 800 es la duración del efecto en milisegundos, no una espera previa. Coloca las tareas que dependen de la finalización en su función de retorno, no inmediatamente después de la llamada.

Duración, easing y finalización

La documentación de .fadeIn() incluye .fadeIn(duration, easing, complete) con argumentos opcionales. Una duración numérica mayor hace más lento el efecto. complete es la función que se llama al terminar el efecto de un elemento.

Duración indicada Tiempo Expresión
Omitida 400 ms por defecto .fadeIn()
Número Milisegundos especificados .fadeIn(800)
"fast" 200 ms .fadeIn("fast")
"slow" 600 ms .fadeIn("slow")
0 Estado final sin transición gradual .fadeIn(0)

easing controla la progresión. El valor predeterminado es swing; linear avanza de forma constante. Se indica después de la duración, como .fadeIn(800, "linear"), no solo en su posición. El ejemplo completo usa el comportamiento predeterminado.

Ejemplo completo con dos avisos

Guarda todo el código en UTF-8 como fadein-demo.html y ábrelo en un navegador. No requiere instalación, pero sí internet para cargar la distribución oficial completa de jQuery desde su red de distribución de contenidos, o CDN. La versión slim excluye los efectos y no tiene .fadeIn(): usa el archivo completo.

El código usa 4.0.0. Se ejecutaron opacidad intermedia, 800/200 ms, finalización por elemento, reinicio durante el efecto y visualización instantánea con 3.7.1 y 4.0.0. Se omite la transición cuando el sistema solicita movimiento reducido.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Fade in two notice panels</title>
  <style>
    body { font: 16px/1.6 sans-serif; margin: 24px; }
    .panel { display: none; padding: 16px; margin: 12px 0; background: #e4f3f1; }
    button, select { padding: 8px; margin: 4px; }
  </style>
  <script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
</head>
<body>
  <h1>Fade in two notice panels</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"> Show instantly</label>
  <button type="button" id="show">Show notices</button>
  <button type="button" id="reset">Reset</button>
  <div id="notices">
    <div class="panel" id="one">Notice one</div>
    <div class="panel" id="two">Notice two</div>
  </div>
  <p id="result" aria-live="polite"></p>
  <script>
    $(function () {
      const $panels = $("#notices > .panel");
      let completed = 0;
      function report(state) {
        $("#result").text(`state=${state} | completed=${completed}`);
      }
      function clearPanels() {
        $panels.stop(true, false).hide().css("opacity", "");
        completed = 0;
      }
      $("#show").on("click", function () {
        clearPanels();
        const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
        const duration = $("#instant").prop("checked") || reduce
          ? 0 : Number($("#duration").val());
        $("#show").prop("disabled", true);
        report("showing");
        $panels.fadeIn(duration, function () {
          completed++;
          if (completed === $panels.length) {
            report("visible");
            $("#show").prop("disabled", false);
          } else {
            report("showing");
          }
        });
      });
      $("#reset").on("click", function () {
        clearPanels();
        $("#show").prop("disabled", false);
        report("hidden");
      });
      report("hidden");
    });
  </script>
</body>
</html>

Ambos paneles comienzan con display: none y el resultado muestra:

state=hidden | completed=0
  1. Deja Show instantly desmarcado, elige 800 ms y pulsa Show notices. Los paneles aparecen juntos y el botón queda desactivado durante la animación.
  2. Al terminar, ambos son visibles y aparece state=visible | completed=2. Dos cuenta elementos terminados, no clics.
  3. Tras Reset, elige 200 ms y repite para llegar antes al mismo resultado. Cambiar la lista no altera un efecto que ya está en ejecución.
  4. Pulsa Reset durante los 800 ms: se ocultan inmediatamente y vuelve state=hidden | completed=0. La antigua finalización no reaparece al pasar su duración original.
  5. Show instantly usa cero y muestra sin transición. Detectar movimiento reducido del sistema produce lo mismo.

Si no ves el fundido, revisa primero la casilla y prefers-reduced-motion. El ejemplo prioriza esa preferencia, de modo que incluso 800 puede producir visualización inmediata.

La finalización se ejecuta por elemento

.fadeIn() no bloquea el JavaScript posterior hasta terminar. Informar de finalización en la línea siguiente puede hacerlo mientras el efecto sigue activo. El ejemplo incrementa completed dentro de la función de retorno para contar finales reales.

Cada panel llama una vez a esa función; no es una sola llamada para todo el conjunto. Solo cuando completed alcanza $panels.length se informa visible y se reactiva el botón. El conjunto permanece fijo durante el ejercicio. En una función normal de retorno, this es el elemento DOM que acaba de terminar.

Interrumpir, restablecer y resolver problemas

En .stop(true, false), true vacía los efectos pendientes y false detiene el actual sin completarlo. No ejecuta su función de finalización, evitando interferencias tras Reset. .hide() oculta después, elimina opacidad en línea que pudiera quedar a mitad y pone el contador en cero.

Volver a iniciar hace la misma limpieza y empieza oculto. Desactivar el botón evita acumular clics y efectos en cola. La limpieza solo afecta a estos paneles y al contador; no cambia ajustes globales.

Si falla, revisa el archivo completo en Network y errores como .fadeIn is not a function en Console. Una selección vacía no ejecuta funciones por elemento. Revisa también visibility: hidden, antepasados ocultos y reglas display más fuertes: cambiar opacidad no elimina toda causa de ocultación.