
🔄 JQuery .toggle(): nowoczesny przełącznik i zamiana usuniętej metody
Znalazł Pan gotowy snippet jQuery do przycisku „Pokaż/Ukryj", a on nie działa? Kod z .toggle() pisany według manuala sprzed dziesięciu lat po cichu przestał działać już w jQuery 1.9. Dla początkującego taka sytuacja wygląda na czarną magię: konsola jest pusta, błędów brak, przycisk po prostu nie reaguje na ponowne kliknięcie.
Problem polega na tym, że metoda .toggle() w jQuery miała dwa życia. Pierwsze, animacja pokazywania/ukrywania elementów: żyje do dziś. Drugie, przełączanie akcji po kliknięciu: usunięto je w 2013 roku, ale wyszukiwarki wciąż podają stare artykuły jako główne. Tutaj rozbierzemy, dlaczego stary kod jest martwy, i napiszemy trzy działające alternatywy, od prostej flagi po data-atrybuty dla tuzina przycisków naraz.
💡 Szybki przegląd:
- Dlaczego Pana
.toggle(fn1, fn2)nie działa i gdzie szukać przestarzałego kodu - Sposób 1: zmienna stanu, dla pojedynczego przycisku, minimum kodu
- Sposób 2:
.data(), gdy przycisków jest wiele i każdy żyje własnym życiem - Bonus: trzy i więcej akcji w łańcuchu kliknięć przez licznik
- Współczesne
.toggle()do animacji, co zostało i jak używać
Czym jest.toggle() w jQuery i dlaczego stary kod jest martwy
Do jQuery 1.8 metoda .toggle() potrafiła dwie różne rzeczy w zależności od przekazanych argumentów. Jeśli przekazać dwa parametry-funkcje, działała jako przełącznik: pierwsze kliknięcie uruchamiało pierwszą funkcję, drugie kliknięcie, drugą, trzecie, znów pierwszą, i tak w kółko.
Wyglądało to kompaktowo:
1 // Работало в jQuery до 1.8, удалено в 1.9 2 $('#myButton').toggle( 3 function() { 4 $(this).text('Показать категории').css('background', 'green'); 5 }, 6 function() { 7 $(this).text('Скрыть категории').css('background', 'red'); 8 } 9 );
Właśnie taki kod wędruje po rosyjskojęzycznych blogach do dziś. Problem w tym, że wraz z wydaniem jQuery 1.9 (styczeń 2013 roku) tę formę .toggle() usunięto całkowicie. Powód: podwójne przeznaczenie metody stwarzało zamieszanie: początkujący nie rozumieli, dlaczego .toggle() raz animuje, a raz przełącza akcje.
Dziś .toggle() robi tylko jedno, pokazuje lub ukrywa element z animacją. A do przełączania akcji programista musi jawnie zarządzać stanem.
Sposób 1: zmienna stanu
Najprostsza droga: założyć zmienną logiczną i przełączać ją w handlerze .click(). Pasuje do pojedynczego przycisku lub elementów, w których logika przełączania jest wspólna.
Proszę dodać kod do pliku skryptów motywu (przez wp_enqueue_script w functions.php) lub w blok <script> przed zamykającym </body>:
1 let isFirstClick = true; 2 3 $('#toggleBtn').on('click', function() { 4 const $btn = $(this); 5 6 if (isFirstClick) { 7 $btn.text('Скрыть категории'); 8 $('#contentBlock').show(700); 9 isFirstClick = false; 10 } else { 11 $btn.text('Показать категории'); 12 $('#contentBlock').fadeOut('slow'); 13 isFirstClick = true; 14 } 15 });
Tutaj isFirstClick przechowuje bieżący stan na zewnątrz handlera. Pierwsze kliknięcie pokazuje blok i zmienia flagę na false, drugie, ukrywa i zwraca flagę z powrotem. Żadnej magii: dokładnie Pan wie, która akcja wydarzy się teraz, a która następna.
Zaletą podejścia jest to, że flagę można zresetować z dowolnego miejsca programu. Powiedzmy, po zapytaniu AJAX chce Pan przywrócić przycisk do pozycji wyjściowej, po prostu isFirstClick = true.
Wadą: jedna zmienna na wszystkie przyciski. Jeśli na stronie są dwa niezależne przełączniki z klasą .toggleBtn, zmienna isFirstClick będzie wspólna dla obu. Do takiego scenariusza, sposób 2.
Sposób 2: data-atrybuty jQuery
Gdy ma Pan kilka niezależnych przycisków (na przykład przy każdym produkcie w katalogu jest własny blok z charakterystyką), stan trzeba przechowywać bezpośrednio na elemencie DOM. Metoda .data() wiąże dowolne dane z elementem i nie zaśmieca globalnego zakresu widoczności.
Proszę załadować skrypt w ten sam sposób, przez wp_enqueue_script lub w stopce:
1 $('.toggle-btn').on('click', function() { 2 const $btn = $(this); 3 const hasClicked = $btn.data('clicked') || false; 4 5 if (!hasClicked) { 6 $btn.text('Скрыть характеристики').css('background', '#f0f0f0'); 7 $btn.next('.specs-block').show(400); 8 $btn.data('clicked', true); 9 } else { 10 $btn.text('Показать характеристики').css('background', '#fff'); 11 $btn.next('.specs-block').fadeOut(300); 12 $btn.data('clicked', false); 13 } 14 });
Wywołanie $btn.data('clicked') odczytuje stan konkretnie tego przycisku. Dziesięć przycisków na stronie, dziesięć izolowanych stanów. Żadnych konfliktów.
Proszę zwrócić uwagę: .data() pracuje z pamięcią jQuery, a nie z HTML-atrybutami data-*. Jeśli potrzebuje Pan, aby stan przetrwał przeładowanie strony, dodatkowo proszę zapisać $btn.attr('data-clicked', 'true') i odczytywać przez .attr().
Bonus: trzy i więcej akcji w łańcuchu
A co, jeśli kliknięć ma być nie dwa, a trzy? Powiedzmy: pierwsze naciśnięcie, pokaż blok, drugie, zmień jego zawartość, trzecie, ukryj. Tutaj zamiast flagi logicznej zakłada się licznik numeryczny:
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('Шаг 1: показать блок'); 8 $('#targetBlock').show(500); 9 break; 10 case 1: 11 $btn.text('Шаг 2: загрузить данные'); 12 $('#targetBlock').load('/ajax-content'); 13 break; 14 case 2: 15 $btn.text('Шаг 3: скрыть'); 16 $('#targetBlock').fadeOut(400); 17 count = -1; // следующий клик снова станет case 0 18 break; 19 } 20 21 $btn.data('clickCount', count + 1); 22 });
Resetowanie licznika (count = -1) ma sens, jeśli łańcuch ma się zapętlać. Jeśli akcja jest jednorazowa, proszę po prostu usunąć resetowanie, a po trzecim kliknięciu nic się nie będzie działo.
Współczesne.toggle() do animacji
Ta forma .toggle(), która przetrwała, odpowiada wyłącznie za widoczność elementów. Bez argumentów, natychmiastowe przełączenie. Z duration, animacja szerokości, wysokości i przezroczystości jednocześnie.
Podstawowy scenariusz: przycisk „Pokaż/Ukryj menu":
1 $('#menuToggle').on('click', function() { 2 $('#mainMenu').toggle('slow', function() { 3 // колбэк после завершения анимации 4 console.log('Анимация завершена'); 5 }); 6 });
Łańcuchy 'fast' i 'slow' dają odpowiednio 200 i 600 milisekund. Można przekazać dokładną liczbę: .toggle(400), 400 ms.
Przydatny chwyt: wymuszenie stanu przez parametr logiczny. .toggle(true) zawsze pokazuje element, a .toggle(false) zawsze ukrywa. To wygodne w połączeniu z zewnętrzną flagą ze sposobu 1:
1 let visible = true; 2 $('#toggleBtn').on('click', function() { 3 visible = !visible; 4 $('#content').toggle(visible); 5 });
Kod czyta się liniowo: flaga została odwrócona, element przyjął żądany stan. Żadnych warunkowych if/else wokół widoczności.
⁉️🤔 Częste pytania
Dlaczego mój stary kod z .toggle(fn1, fn2) nie generuje błędów w konsoli?
Starą formę
.toggle()usunięto na poziomie metody: jQuery po prostu nie znajduje takiej sygnatury i po cichu nic nie robi. Konsola jest pusta, ponieważ wywołanie.toggle(fn1, fn2)dla współczesnego jQuery to składniowo poprawny, ale bezsensowny wywołanie (argumenty są ignorowane). Proszę sprawdzić wersję jQuery: jeśli 1.9 lub wyższa, stary kod jest martwy.
Czy można podłączyć jQuery Migrate i nie przepisywać kodu?
Formalnie, tak. Wtyczka jQuery Migrate przywraca usunięte metody, w tym stare
.toggle(). Ale to tymczasowa proteza: Migrate dodaje ~10 KB w wersji skompresowanej i jest przeznaczony na okres przejściowy, a nie do stałej pracy. Jeśli strona jest na WordPressie i jQuery ładuje się z rdzenia, Migrate już tam jest dla wstecznej kompatybilności. Ale poleganie na nim we własnym kodzie nie jest wskazane: w każdej chwili może go wyłączyć aktualizacja motywu lub innej wtyczki.
Co lepsze, zmienna czy data-atrybut?
Dla jednego przycisku, zmienna (mniej kodu). Dla kilku niezależnych przycisków lub dynamicznie dodawanych elementów,
.data()(izolacja stanów). Jeśli przyciski są dodawane przez AJAX po załadowaniu strony, proszę użyć delegowania:$(document).on('click', '.toggle-btn', function() { ... }).
Czy.toggle() działa na urządzeniach mobilnych?
Tak. Współczesne
.toggle()(animacja) i wszystkie handlery kliknięcia z tego artykułu poprawnie obsługują zdarzenia dotykowe. jQuery normalizujeclickdla przeglądarek mobilnych począwszy od pierwszych wersji. Jedyny niuans: na iOS do wersji 12. w elementach bezcursor: pointerwystępowało opóźnione kliknięcie, ale ten problem rozwiązuje jeden wiersz CSStouch-action: manipulationdla przycisku.
Gdzie umieszczać kod jQuery w WordPressie?
Trzy warianty. Szybki, wtyczka Code Snippets: wstawia Pan kod JS do snippetu z typem „JavaScript", automatycznie ładuje się on w stopce. Prawidłowy, utworzyć w motywie potomnym plik
js/toggle.js, zarejestrować go przezwp_enqueue_script('my-toggle', get_stylesheet_directory_uri() . '/js/toggle.js', array('jquery'), '1.0', true)wfunctions.php. Parametrtruena końcu wysyła skrypt do stopki, to standard dla kodu pracującego z DOM. Proszę nie wstawiać<script>bezpośrednio w treść posta, edytor WordPressa utnie tag.
Jakie podejście wybrać dla Pana projektu
Jeśli ma Pan jeden przycisk z przełączaniem tekstu i widoczności bloku, proszę wziąć zmienną stanu. Trzy linijki, zachowanie przejrzyste, debugowanie trywialne.
Jeśli przełączników jest kilka (katalog, panel ustawień, lista elementów z rozwijaniem), tylko .data(). Globalna zmienna na kilka przycisków zrodzi gonitwę stanów, którą będzie Pan debugował dłużej, niż napisze kod sposobem 2.
Łańcuch z trzech i więcej kroków, licznik ze switch. Proszę nie komplikować flagami logicznymi tego, co naturalnie układa się na liczbach.
A co najważniejsze, jeśli natknął się Pan w wyszukiwarce na artykuł z .toggle(fn1, fn2), proszę zamknąć kartę. jQuery żyje, ale ta konkretna metoda została pogrzebana w 2013 roku.
Odświeżyć wiedzę z uruchamiania fragmentów JavaScript na bieżąco można w naszym materiale o pracy ze snippetami w Chrome DevTools, przyda się do szybkiego obiegania kodu z tego artykułu.



