jQuery / Método / .toggle() - Mostrar ou ocultar elementos

No jQuery, .toggle() oculta cada elemento visível e mostra cada oculto. .toggle(true) determina mostrar, .toggle(false) ocultar e .toggle(800) anima a mudança. Diferencie inverter o estado atual de estabelecer um estado conhecido.

Inversão imediata, estado e animação

A API de .toggle() muda display imediatamente sem argumentos. Se Alpha estiver visível e Beta oculto, um uso oculta Alpha e mostra Beta. Não sincroniza toda a coleção no mesmo estado.

Chamada Comportamento Quando usar
.toggle() Inverter cada estado Mudar para o contrário
.toggle(true), .toggle(false) Mostrar ou ocultar explicitamente Estado desejado conhecido
.toggle(800) Animar por 800ms Mudar tamanho e opacidade
.toggle({ duration: 0, complete: fn }) Efeito de duração zero Final imediato com callback

Efeitos temporizados alteram largura, altura e opacidade. Ao terminar de ocultar, display:none remove o espaço no layout. 800ms são 0,8 segundo e valores maiores são mais lentos. false booleano e zero numérico são formas diferentes. Ocultar não exclui valores nem outros estados do modelo de objetos do documento (DOM).

Exemplo completo com dois painéis

Salve todo o código em UTF-8 como toggle-demo.html e abra no navegador. A Internet carrega o arquivo oficial completo do jQuery 4.0.0 pela rede de distribuição de conteúdo (CDN). Efeitos temporizados precisam de effects: não troque por slim. Interações e trecho do Console foram executados com 3.7.1 e 4.0.0.

Alpha usa flex e Beta começa oculto. Os controles ficam fora. Escolha imediato, 800ms, 200ms ou 0ms. busy ignora pedidos extras durante o efeito. A preferência do sistema por movimento reduzido aplica duração zero.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Toggle each panel visibility</title>
  <script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
  <style>
    body { font: 16px/1.6 sans-serif; max-width: 760px; margin: 24px auto; padding: 16px; }
    button, select, input { font: inherit; margin: 4px; max-width: 100%; box-sizing: border-box; }
    .panel { padding: 12px; margin: 10px 0; border: 1px solid teal; background: #edf9f6; }
    #alpha { display: flex; flex-wrap: wrap; align-items: center; }
    #beta { display: none; }
    pre { white-space: pre-wrap; overflow-wrap: anywhere; }
  </style>
</head>
<body>
  <h1>Toggle independently or set a known state</h1>
  <label for="mode">Mode:</label>
  <select id="mode"><option value="instant">No arguments</option><option value="800">800ms</option><option value="200">200ms</option><option value="0">0ms</option></select>
  <button type="button" id="toggle">Toggle each</button>
  <button type="button" id="show">Show both</button>
  <button type="button" id="hide">Hide both</button>
  <button type="button" id="reset">Reset</button>
  <div id="panels">
    <div class="panel" id="alpha">Alpha <input aria-label="Alpha note" value="Keep this note"></div>
    <div class="panel" id="beta">Beta panel</div>
  </div>
  <pre id="result" aria-live="polite"></pre>
  <script>
    $(function () {
      const $panels = $("#panels > .panel");
      let busy = false, completed = 0;
      function report() {
        const visible = $panels.filter(":visible").map(function () { return this.id; }).get();
        $("#result").text(`visible=${visible.join(",") || "(none)"}\ncompleted=${completed}\nbusy=${busy}\nDOM panels=${$panels.length}`);
      }
      function settle() { $panels.stop(true, true); busy = false; completed = 0; }
      $("#toggle").on("click", function () {
        if (busy) return;
        completed = 0;
        const mode = $("#mode").val();
        if (mode === "instant") { $panels.toggle(); report(); return; }
        if (!$panels.length) { report(); return; }
        busy = true; report();
        const reduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
        $panels.toggle({ duration: reduced ? 0 : Number(mode), complete: function () {
          completed++;
          if (completed === $panels.length) busy = false;
          report();
        } });
      });
      $("#show").on("click", function () { settle(); $panels.toggle(true); report(); });
      $("#hide").on("click", function () { settle(); $panels.toggle(false); report(); });
      $("#reset").on("click", function () {
        settle(); $("#alpha").toggle(true); $("#beta").toggle(false);
        $("#alpha input").val("Keep this note"); $("#mode").val("instant"); report();
      });
      report();
    });
  </script>
</body>
</html>

Inicialmente só Alpha aparece; os dois painéis continuam no documento.

visible=alpha
completed=0
busy=false
DOM panels=2
  1. Com No arguments, pressione Toggle each: só Beta aparece e completed continua zero. Outra vez retorna a Alpha.
  2. Edite o campo Alpha, oculte e mostre novamente: valor e exibição flex são preservados.
  3. Com 800ms, no final visible=beta, completed=2 e busy=false. O callback executa por painel, não uma vez por coleção.
  4. Cliques durante o efeito são ignorados, sem acumular fila. Restaure antes de comparar 200ms nas mesmas condições.
  5. Show both mostra ambos e Hide both oculta ambos. Repetir mantém o estado especificado.
  6. Reset termina efeitos e restaura Alpha visível, Beta oculto, campo e modo iniciais. O valor muda pelo .val() explícito, não por ocultar.

0ms se parece com a chamada sem argumentos, mas executa complete por painel, resultando em completed=2. Movimento reduzido usa esse caminho sem alterar efeitos globais do site. :visible durante a animação não garante o estado final; confira após concluir.

Booleanos e restauração durante o efeito

Passe um booleano real para decidir exibição por condição. Dois true não ocultam novamente. Execute isto no Console da mesma página; dois elementos temporários são criados e depois removidos.

const $holder = $('<div><p>A</p><p>B</p></div>').appendTo("body");
const $items = $holder.find("p");
$items.toggle(false);
$items.toggle(false);
console.log(`hide twice visible=${$items.filter(":visible").length}`);
$items.toggle(true);
$items.toggle(true);
console.log(`show twice visible=${$items.filter(":visible").length}`);
console.log(`DOM count=${$items.length}`);
$holder.remove();
hide twice visible=0
show twice visible=2
DOM count=2

Impor um estado durante a animação exige gerenciar fila e estado interno. settle() usa .stop(true, true) para limpar a fila e terminar o efeito, depois define busy como false e zera completed. O segundo true pode executar callbacks imediatamente: zere contadores depois de stop.

Reset aplica então os estados conhecidos. Parar em um tamanho intermediário difere de terminar no destino. Foi verificado Reset durante a animação seguido de inversão sem argumentos: Alpha mudou corretamente para Beta. Para outra política de cliques, decida antes entre ignorar, esperar ou terminar o efeito atual.

Investigar visibilidade e efeitos diferentes

Confira seletor, .length e carregamento do jQuery. Um ancestral com display:none pode impedir ver o filho mesmo com .toggle(true). Diferencie visibility:hidden e opacity:0. toggle não remove todas as causas de invisibilidade.

Se terminar imediatamente, confira duração, movimento reduzido e arquivo carregado. Escolha entre só opacidade, só altura ou mudanças combinadas conforme a necessidade. Evite gravar repetidamente tamanhos intermediários como estilos permanentes sem motivo concreto.

Ao ocultar uma área com foco, planeje reabertura e movimento do foco. O exemplo mantém controles externos, mas não implementa toda a restauração de foco ou anúncios de expansão. Exibir e ocultar sozinho não completa todas as interações.