
🔄 JQuery .toggle(): alternância moderna e substituição do método removido
Encontrou um snippet de jQuery pronto para um botão «Mostrar/Ocultar» que não funciona? O código que usa .toggle() foi escrito com base num manual com uma década e deixou de funcionar silenciosamente no jQuery 1.9. Para um principiante, esta situação parece magia negra: a consola está vazia, sem erros, o botão simplesmente não responde a um segundo clique.
O problema é que o método .toggle() no jQuery teve duas vidas. A primeira, animar a exibição/ocultação de elementos, ainda está viva. A segunda, alternar ações ao clicar, foi removida em 2013, mas os motores de busca ainda mostram artigos antigos como resultados principais. Aqui vamos explicar porque é que o código antigo está morto e escrever três alternativas funcionais, desde uma simples flag a atributos de dados para uma dúzia de botões de uma só vez.
💡 Visão geral rápida:
- Porque é que o seu
.toggle(fn1, fn2)não funciona e onde procurar código obsoleto - Método 1: uma variável de estado para um único botão com código mínimo
- Método 2:
.data()quando tem muitos botões e cada um vive a sua própria vida - Bónus: três ou mais ações numa cadeia de cliques usando um contador
.toggle()moderno para animação, o que resta e como usá-lo
O que é o.toggle() no jQuery e porque é que o código antigo está morto
Antes do jQuery 1.8, o método .toggle() podia fazer duas coisas diferentes dependendo dos argumentos passados. Se passasse dois parâmetros de função, funcionava como um alternador: o primeiro clique executava a primeira função, o segundo clique executava a segunda, o terceiro clique executava a primeira novamente, e assim por diante num ciclo.
Parecia compacto:
1 // Worked in jQuery before 1.8, removed in 1.9 2 $('#myButton').toggle( 3 function() { 4 $(this).text('Show categories').css('background', 'green'); 5 }, 6 function() { 7 $(this).text('Hide categories').css('background', 'red'); 8 } 9 );
Exatamente este código tem circulado em blogues de língua russa até hoje. O problema é que, com o lançamento do jQuery 1.9 (janeiro de 2013), esta forma de .toggle() foi completamente removida. A razão: o duplo propósito do método criava confusão, e os principiantes não conseguiam perceber porque é que .toggle() por vezes animava e outras vezes alternava ações.
Hoje o .toggle() faz apenas uma coisa: mostra ou oculta um elemento com animação. Para ações alternadas, o programador precisa de gerir o estado explicitamente.
Método 1: variável de estado
A abordagem mais direta é criar uma variável booleana e alterná-la no manipulador .click(). Adequado para um único botão ou elementos com lógica de alternância partilhada.
Adicione o código ao seu ficheiro de scripts do tema (via wp_enqueue_script no functions.php) ou num bloco <script> antes do fecho </body>:
1 let isFirstClick = true; 2 3 $('#toggleBtn').on('click', function() { 4 const $btn = $(this); 5 6 if (isFirstClick) { 7 $btn.text('Hide categories'); 8 $('#contentBlock').show(700); 9 isFirstClick = false; 10 } else { 11 $btn.text('Show categories'); 12 $('#contentBlock').fadeOut('slow'); 13 isFirstClick = true; 14 } 15 });
Aqui isFirstClick guarda o estado atual fora do manipulador. O primeiro clique mostra o bloco e define a flag como false, o segundo oculta-o e devolve a flag ao estado anterior. Sem magia: sabe exatamente qual a ação que vai acontecer agora e qual a que acontecerá a seguir.
A vantagem desta abordagem é que a flag pode ser reposta a partir de qualquer parte do programa. Por exemplo, após um pedido AJAX, se quiser devolver o botão ao seu estado inicial, basta usar isFirstClick = true.
A desvantagem é uma variável para todos os botões. Se a página tiver dois alternadores independentes com a classe .toggleBtn, a variável isFirstClick será partilhada por ambos. Para esse cenário, use o método 2.
Método 2: atributos de dados do jQuery
Quando tem vários botões independentes (por exemplo, cada produto num catálogo tem o seu próprio bloco de especificações), precisa de guardar o estado diretamente no elemento DOM. O método .data() anexa dados arbitrários a um elemento sem poluir o âmbito global.
Carregue o script da mesma forma, via wp_enqueue_script ou no rodapé:
1 $('.toggle-btn').on('click', function() { 2 const $btn = $(this); 3 const hasClicked = $btn.data('clicked') || false; 4 5 if (!hasClicked) { 6 $btn.text('Hide specifications').css('background', '#f0f0f0'); 7 $btn.next('.specs-block').show(400); 8 $btn.data('clicked', true); 9 } else { 10 $btn.text('Show specifications').css('background', '#fff'); 11 $btn.next('.specs-block').fadeOut(300); 12 $btn.data('clicked', false); 13 } 14 });
Chamar $btn.data('clicked') lê o estado deste botão específico. Dez botões na página significam dez estados isolados. Sem conflitos.
Nota: .data() funciona com a memória do jQuery, não com atributos HTML data-*. Se precisar que o estado sobreviva a um recarregamento da página, escreva adicionalmente $btn.attr('data-clicked', 'true') e leia via .attr().
Bónus: três ou mais ações numa cadeia
E se não forem dois, mas três cliques? Por exemplo: o primeiro toque mostra o bloco, o segundo altera o seu conteúdo, o terceiro oculta-o. Aqui, em vez de uma flag booleana, cria um contador numérico:
1 $('#multiBtn').on('click', function() { 2 const $btn = $(this); 3 let count = $btn.data('clickCount') || 0; 4 5 switch (count) { 6 case 0: 7 $btn.text('Step 1: show block'); 8 $('#targetBlock').show(500); 9 break; 10 case 1: 11 $btn.text('Step 2: load data'); 12 $('#targetBlock').load('/ajax-content'); 13 break; 14 case 2: 15 $btn.text('Step 3: hide'); 16 $('#targetBlock').fadeOut(400); 17 count = -1; // next click will become case 0 again 18 break; 19 } 20 21 $btn.data('clickCount', count + 1); 22 });
Repor o contador (count = -1) faz sentido se a cadeia for cíclica. Se a ação for única, simplesmente remova a reposição e nada acontecerá após o terceiro clique.
.Toggle() moderno para animação
A forma de .toggle() que sobreviveu é estritamente responsável pela visibilidade do elemento. Sem argumentos, é uma alternância instantânea. Com duração, anima a largura, altura e opacidade simultaneamente.
Cenário básico: um botão «Mostrar/Ocultar menu»:
1 $('#menuToggle').on('click', function() { 2 $('#mainMenu').toggle('slow', function() { 3 // callback after animation completes 4 console.log('Animation complete'); 5 }); 6 });
As strings 'fast' e 'slow' dão 200 e 600 milissegundos, respetivamente. Pode passar um número exato: .toggle(400) significa 400 ms.
Um truque útil: forçar o estado através de um parâmetro booleano. .toggle(true) mostra sempre o elemento, e .toggle(false) oculta-o sempre. Isto é conveniente em combinação com uma flag externa do método 1:
1 let visible = true; 2 $('#toggleBtn').on('click', function() { 3 visible = !visible; 4 $('#content').toggle(visible); 5 });
O código lê-se linearmente: a flag é invertida, o elemento assume o estado requerido. Sem if/else condicional em torno da visibilidade.
⁉️🤔 Perguntas frequentes
Porque é que o meu código antigo com .toggle(fn1, fn2) não mostra erros na consola?
A forma antiga de
.toggle()foi removida ao nível do método: o jQuery simplesmente não encontra essa assinatura e não faz nada silenciosamente. A consola está vazia porque chamar.toggle(fn1, fn2)para o jQuery moderno é uma chamada sintaticamente correta, mas sem sentido (os argumentos são ignorados). Verifique a sua versão do jQuery: se for 1.9 ou superior, o código antigo está morto.
Posso incluir o jQuery Migrate e não reescrever o código?
Tecnicamente, sim. O plugin jQuery Migrate restaura métodos removidos, incluindo o antigo
.toggle(). Mas isto é uma muleta temporária: o Migrate adiciona ~10 KB minificado e foi concebido para um período de transição, não para uso permanente. Se o site corre em WordPress e o jQuery carrega do núcleo, o Migrate já está lá para compatibilidade retroativa. Mas confiar nele no seu próprio código não é recomendado: pode ser desativado a qualquer momento por uma atualização de tema ou plugin.
O que é melhor, uma variável ou um atributo de dados?
Para um único botão, use uma variável (menos código). Para vários botões independentes ou elementos adicionados dinamicamente, use
.data()(isolamento de estado). Se os botões forem adicionados via AJAX após o carregamento da página, use delegação:$(document).on('click', '.toggle-btn', function() { ... }).
O.toggle() funciona em dispositivos móveis?
Sim. O
.toggle()moderno (animação) e todos os manipuladores de clique deste artigo funcionam corretamente em eventos de toque. O jQuery normaliza oclickpara navegadores móveis desde as suas primeiras versões. A única nuance: no iOS antes da versão 12, elementos semcursor: pointertinham um clique atrasado, mas este problema resolve-se com uma linha de CSStouch-action: manipulationpara o botão.
Onde devo colocar o código jQuery no WordPress?
Três opções. Rápida: o plugin Code Snippets: insira o código JS num snippet com o tipo «JavaScript» e ele carrega automaticamente no rodapé. Correta: crie um ficheiro
js/toggle.jsno seu tema filho, registe-o viawp_enqueue_script('my-toggle', get_stylesheet_directory_uri() . '/js/toggle.js', array('jquery'), '1.0', true)nofunctions.php. O parâmetrotrueno final envia o script para o rodapé, o que é padrão para código que trabalha com o DOM. Não coloque<script>diretamente no corpo do artigo; o editor do WordPress irá remover a tag.
Que abordagem escolher para o seu projeto
Se tem um botão com alternância de texto e visibilidade de bloco, use uma variável de estado. Três linhas, comportamento transparente, depuração trivial.
Se houver vários alternadores (catálogo, painel de configurações, lista de itens expansíveis), use apenas .data(). Uma variável global para vários botões criará uma condição de corrida de estado que demorará mais a depurar do que o tempo que leva a escrever o código usando o método 2.
Uma cadeia de três ou mais passos requer um contador com switch. Não complique com flags booleanas o que se encaixa naturalmente com números.
Mais importante ainda, se encontrar um artigo nos resultados de pesquisa com .toggle(fn1, fn2), feche o separador. O jQuery está vivo, mas esse método específico foi enterrado em 2013.
Pode refrescar os seus conhecimentos sobre como executar snippets de JavaScript rapidamente no nosso artigo sobre como trabalhar com snippets no Chrome DevTools, que será útil para testar rapidamente o código deste artigo.



