
🔄 JQuery .toggle(): modern växling och ersättning för den borttagna metoden
Hittade du ett färdigt jQuery-snippet för en "Visa/Dölj"-knapp som inte fungerar? Kod som använder .toggle() skrevs enligt en tio år gammal manual och slutade fungera i tysthet i och med jQuery 1.9. För en nybörjare ser situationen ut som svart magi: konsolen är tom, inga felmeddelanden, knappen svarar helt enkelt inte på ett andra klick.
Problemet är att metoden .toggle() i jQuery hade två liv. Det första, att animera visning/döljning av element, lever fortfarande. Det andra, att växla mellan olika funktioner vid klick, togs bort 2013, men sökmotorer lyfter fortfarande fram gamla artiklar som toppresultat. Här förklarar vi varför den gamla koden är död och skriver tre fungerande alternativ, från en enkel flagga till data-attribut för ett dussin knappar samtidigt.
💡 Snabb översikt:
- Varför din
.toggle(fn1, fn2)inte fungerar och var du ska leta efter föråldrad kod - Metod 1: en tillståndsvariabel för en enskild knapp med minimal kod
- Metod 2:
.data()när du har många knappar och var och en lever sitt eget liv - Bonus: tre eller fler åtgärder i en klickkedja med hjälp av en räknare
- Modern
.toggle()för animering, vad som finns kvar och hur du använder det
Vad är.toggle() i jQuery och varför gammal kod är död
Före jQuery 1.8 kunde metoden .toggle() göra två olika saker beroende på vilka argument som skickades. Om du skickade två funktionsparametrar fungerade den som en växel: första klicket körde den första funktionen, andra klicket körde den andra, tredje klicket körde den första igen, och så vidare i en cykel.
Det såg kompakt ut:
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 );
Exakt den här koden har cirkulerat i ryskspråkiga bloggar fram till idag. Problemet är att i och med lanseringen av jQuery 1.9 (januari 2013) togs denna form av .toggle() bort helt. Anledningen: metodens dubbla syfte skapade förvirring, och nybörjare kunde inte förstå varför .toggle() ibland animerade och ibland växlade mellan funktioner.
Idag gör .toggle() bara en sak: visar eller döljer ett element med animering. För att växla mellan olika funktioner måste utvecklaren uttryckligen hantera tillståndet.
Metod 1: tillståndsvariabel
Den mest direkta metoden är att skapa en boolesk variabel och växla den i .click()-hanteraren. Passar för en enskild knapp eller element med delad växlingslogik.
Lägg till koden i din tema-skriptfil (via wp_enqueue_script i functions.php) eller i ett <script>-block före avslutande </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 });
Här lagrar isFirstClick det aktuella tillståndet utanför hanteraren. Första klicket visar blocket och sätter flaggan till false, andra klicket döljer det och återställer flaggan. Ingen magi: du vet exakt vilken åtgärd som ska ske nu och vilken som ska ske härnäst.
Fördelen med detta tillvägagångssätt är att flaggan kan återställas var som helst i programmet. Om du till exempel efter en AJAX-förfrågan vill återställa knappen till sitt ursprungliga tillstånd, använd bara isFirstClick = true.
Nackdelen är en variabel för alla knappar. Om sidan har två oberoende växlare med klassen .toggleBtn kommer variabeln isFirstClick att delas av båda. För ett sådant scenario, använd metod 2.
Metod 2: jQuery data-attribut
När du har flera oberoende knappar (till exempel varje produkt i en katalog har sitt eget specifikationsblock) behöver du lagra tillståndet direkt på DOM-elementet. Metoden .data() kopplar godtycklig data till ett element utan att förorena det globala scopet.
Ladda skriptet på samma sätt, via wp_enqueue_script eller i sidfoten:
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 });
Anropet $btn.data('clicked') läser tillståndet för just denna specifika knapp. Tio knappar på sidan innebär tio isolerade tillstånd. Inga konflikter.
Notera: .data() arbetar med jQuerys minne, inte med HTML:s data-*-attribut. Om du behöver att tillståndet överlever en sidomladdning, skriv dessutom $btn.attr('data-clicked', 'true') och läs via .attr().
Bonus: tre eller fler åtgärder i en kedja
Vad händer om det inte ska vara två utan tre klick? Till exempel: första trycket visar blocket, andra ändrar dess innehåll, tredje döljer det. Här skapar du en numerisk räknare istället för en boolesk flagga:
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 });
Att återställa räknaren (count = -1) är meningsfullt om kedjan ska loopa. Om åtgärden är engångs, ta helt enkelt bort återställningen, så händer ingenting efter det tredje klicket.
Modern.toggle() för animering
Den form av .toggle() som överlevde är strikt ansvarig för elements synlighet. Utan argument sker en omedelbar växling. Med varaktighet animerar den bredd, höjd och opacitet samtidigt.
Grundscenario: en "Visa/Dölj meny"-knapp:
1 $('#menuToggle').on('click', function() { 2 $('#mainMenu').toggle('slow', function() { 3 // callback after animation completes 4 console.log('Animation complete'); 5 }); 6 });
Strängarna 'fast' och 'slow' ger 200 respektive 600 millisekunder. Du kan skicka ett exakt tal: .toggle(400) innebär 400 ms.
Ett användbart trick: tvinga tillstånd via en boolesk parameter. .toggle(true) visar alltid elementet, och .toggle(false) döljer det alltid. Detta är praktiskt i kombination med en extern flagga från metod 1:
1 let visible = true; 2 $('#toggleBtn').on('click', function() { 3 visible = !visible; 4 $('#content').toggle(visible); 5 });
Koden läses linjärt: flaggan vänds, elementet antar det önskade tillståndet. Ingen villkorlig if/else kring synlighet.
⁉️🤔 Vanliga frågor
Varför visar min gamla kod med .toggle(fn1, fn2) inga fel i konsolen?
Den gamla formen av
.toggle()togs bort på metodnivå: jQuery hittar helt enkelt inte en sådan signatur och gör tyst ingenting. Konsolen är tom eftersom ett anrop av.toggle(fn1, fn2)för modern jQuery är ett syntaktiskt korrekt men meningslöst anrop (argument ignoreras). Kontrollera din jQuery-version: om den är 1.9 eller högre är den gamla koden död.
Kan jag inkludera jQuery Migrate och slippa skriva om koden?
Tekniskt sett, ja. Plugin-programmet jQuery Migrate återställer borttagna metoder, inklusive den gamla
.toggle(). Men detta är en tillfällig krycka: Migrate lägger till ~10 KB minifierat och är utformat för en övergångsperiod, inte permanent användning. Om webbplatsen körs på WordPress och jQuery laddas från core, finns Migrate redan där för bakåtkompatibilitet. Men att förlita sig på det i din egen kod rekommenderas inte: det kan inaktiveras när som helst av en tema- eller plugin-uppdatering.
Vilket är bäst, en variabel eller ett data-attribut?
För en enskild knapp, använd en variabel (mindre kod). För flera oberoende knappar eller dynamiskt tillagda element, använd
.data()(tillståndsisolering). Om knappar läggs till via AJAX efter sidladdning, använd delegering:$(document).on('click', '.toggle-btn', function() { ... }).
Fungerar.toggle() på mobila enheter?
Ja. Modern
.toggle()(animering) och alla klickhanterare från denna artikel fungerar korrekt med touch-händelser. jQuery normaliserarclickför mobila webbläsare sedan sina tidigaste versioner. Den enda nyansen: på iOS före version 12 hade element utancursor: pointerett fördröjt klick, men detta problem löses med en CSS-radtouch-action: manipulationför knappen.
Var ska jag placera jQuery-kod i WordPress?
Tre alternativ. Snabbt: plugin-programmet Code Snippets: infoga JS-kod i ett snippet med typen "JavaScript", så laddas det automatiskt i sidfoten. Korrekt: skapa en fil
js/toggle.jsi ditt child theme, registrera den viawp_enqueue_script('my-toggle', get_stylesheet_directory_uri() . '/js/toggle.js', array('jquery'), '1.0', true)ifunctions.php. Parameterntruepå slutet skickar skriptet till sidfoten, vilket är standard för kod som arbetar med DOM:en. Lägg inte<script>direkt i inläggets brödtext; WordPress-redigeraren kommer att ta bort taggen.
Vilket tillvägagångssätt du ska välja för ditt projekt
Om du har en knapp med textväxling och blockets synlighet, använd en tillståndsvariabel. Tre rader, transparent beteende, trivial felsökning.
Om det finns flera växlare (katalog, inställningspanel, lista med expanderbara objekt), använd endast .data(). En global variabel för flera knappar skapar ett tillståndsrace som du kommer att felsöka längre än det tar att skriva koden med metod 2.
En kedja med tre eller fler steg kräver en räknare med switch. Komplicera inte med booleska flaggor det som naturligt passar med siffror.
Viktigast av allt, om du hittar en artikel i sökresultaten med .toggle(fn1, fn2), stäng fliken. jQuery lever, men just den metoden begravdes 2013.
Du kan fräscha upp dina kunskaper om att köra JavaScript-snippets i farten i vår artikel om att arbeta med snippets i Chrome DevTools, vilket kommer att vara användbart för att snabbt testa kod från denna artikel.



