
🔄 JQuery .toggle(): moderni vaihtoehto poistetulle metodille
Löysitkö valmiin jQuery-pätkän "Näytä/Piilota"-painikkeelle, joka ei toimi? .toggle()-metodia käyttävä koodi on kirjoitettu vuosikymmenen takaisen ohjeen mukaan ja hajosi hiljaisesti jo jQueryn versiossa 1.9. Aloittelijalle tämä tilanne näyttää mustalta magialta: konsoli on tyhjä, ei virheilmoituksia, painike ei yksinkertaisesti reagoi toiseen klikkaukseen.
Ongelma on siinä, että .toggle()-metodilla jQueryssä oli kaksi elämää. Ensimmäinen, elementtien animoitu näyttäminen/piilottaminen, on yhä elossa. Toinen, klikkauksella vuorottelevat toiminnot, poistettiin vuonna 2013, mutta hakukoneet nostavat yhä vanhoja artikkeleita kärkituloksiin. Tässä selitämme, miksi vanha koodi on kuollut, ja kirjoitamme kolme toimivaa vaihtoehtoa yksinkertaisesta lipusta data-attribuutteihin tusinalle painikkeita kerralla.
💡 Nopea yleiskatsaus:
- Miksi
.toggle(fn1, fn2)ei toimi ja mistä etsiä vanhentunutta koodia - Tapa 1: tilamuuttuja yhdelle painikkeelle minimaalisella koodilla
- Tapa 2:
.data(), kun painikkeita on monta ja jokainen elää omaa elämäänsä - Bonus: kolme tai useampi toimintoa klikkausketjussa laskuria käyttäen
- Moderni
.toggle()animaatioon, mitä on jäljellä ja miten sitä käytetään
Mikä on.toggle() jQueryssä ja miksi vanha koodi on kuollut
Ennen jQuery 1.8:aa .toggle()-metodi saattoi tehdä kahta eri asiaa annetuista argumenteista riippuen. Jos annoit sille kaksi funktioparametria, se toimi vuorottelijana: ensimmäinen klikkaus suoritti ensimmäisen funktion, toinen klikkaus toisen, kolmas klikkaus taas ensimmäisen ja niin edelleen syklissä.
Se näytti kompaktilta:
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 );
Juuri tämä koodi on kiertänyt venäjänkielisissä blogeissa tähän päivään asti. Ongelma on, että jQuery 1.9:n julkaisun myötä (tammikuu 2013) tämä .toggle()-muoto poistettiin kokonaan. Syy: metodin kaksinainen tarkoitus aiheutti sekaannusta, eivätkä aloittelijat ymmärtäneet, miksi .toggle() välillä animoi ja välillä vuorotteli toimintoja.
Nykyään .toggle() tekee vain yhden asian: näyttää tai piilottaa elementin animaation kanssa. Vuorottelevia toimintoja varten kehittäjän on hallittava tilaa eksplisiittisesti.
Tapa 1: tilamuuttuja
Suorin lähestymistapa on luoda totuusarvomuuttuja ja vaihtaa sen tilaa .click()-käsittelijässä. Sopii yhdelle painikkeelle tai elementeille, joilla on jaettu vuorottelulogiikka.
Lisää koodi teemasi skriptitiedostoon (wp_enqueue_script-funktiolla functions.php-tiedostossa) tai <script>-lohkoon ennen sulkevaa </body>-tagia:
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 });
Tässä isFirstClick säilyttää nykyisen tilan käsittelijän ulkopuolella. Ensimmäinen klikkaus näyttää lohkon ja asettaa lipun arvoon false, toinen piilottaa sen ja palauttaa lipun takaisin. Ei magiaa: tiedät tarkalleen, mikä toiminto tapahtuu nyt ja mikä seuraavaksi.
Tämän lähestymistavan etu on, että lipun voi nollata mistä tahansa kohtaa ohjelmaa. Jos esimerkiksi AJAX-pyynnön jälkeen haluat palauttaa painikkeen alkutilaan, käytä vain isFirstClick = true.
Haittapuolena on yksi muuttuja kaikille painikkeille. Jos sivulla on kaksi itsenäistä vuorottelijaa luokalla .toggleBtn, isFirstClick-muuttuja on molempien yhteinen. Tällaiseen skenaarioon käytä tapaa 2.
Tapa 2: jQueryn data-attribuutit
Kun sinulla on useita itsenäisiä painikkeita (esimerkiksi jokaisella tuotteella verkkokaupassa on oma tekniset tiedot -lohkonsa), sinun on tallennettava tila suoraan DOM-elementtiin. .data()-metodi liittää mielivaltaista dataa elementtiin saastuttamatta globaalia näkyvyysaluetta.
Lataa skripti samalla tavalla, wp_enqueue_script-funktiolla tai footerissa:
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 });
Kutsu $btn.data('clicked') lukee juuri tämän painikkeen tilan. Kymmenen painiketta sivulla tarkoittaa kymmentä eristettyä tilaa. Ei konflikteja.
Huomio: .data() toimii jQueryn muistissa, ei HTML data-*-attribuuttien kanssa. Jos tarvitset tilan säilyvän sivun uudelleenlatauksen yli, kirjoita lisäksi $btn.attr('data-clicked', 'true') ja lue .attr()-metodilla.
Bonus: kolme tai useampi toimintoa ketjussa
Entä jos klikkauksia ei pitäisikään olla kaksi vaan kolme? Esimerkiksi: ensimmäinen painallus näyttää lohkon, toinen vaihtaa sen sisällön, kolmas piilottaa sen. Tässä totuusarvolipun sijaan luot numeerisen laskurin:
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 });
Laskurin nollaaminen (count = -1) on järkevää, jos ketjun halutaan kiertävän. Jos toiminto on kertaluonteinen, poista nollaus, niin kolmannen klikkauksen jälkeen ei tapahdu mitään.
Moderni.toggle() animaatioon
Se .toggle()-muoto, joka säilyi, vastaa tiukasti elementin näkyvyydestä. Ilman argumentteja se on välitön tilanvaihto. Kestoargumentilla se animoi leveyttä, korkeutta ja läpinäkyvyyttä samanaikaisesti.
Perusskenaario: "Näytä/Piilota valikko" -painike:
1 $('#menuToggle').on('click', function() { 2 $('#mainMenu').toggle('slow', function() { 3 // callback after animation completes 4 console.log('Animation complete'); 5 }); 6 });
Merkkijonot 'fast' ja 'slow' antavat 200 ja 600 millisekuntia. Voit antaa tarkan luvun: .toggle(400) tarkoittaa 400 ms.
Hyödyllinen temppu: tilan pakottaminen totuusarvoparametrilla. .toggle(true) näyttää elementin aina, ja .toggle(false) piilottaa sen aina. Tämä on kätevää yhdistettynä ulkoiseen lippuun tavasta 1:
1 let visible = true; 2 $('#toggleBtn').on('click', function() { 3 visible = !visible; 4 $('#content').toggle(visible); 5 });
Koodi luetaan lineaarisesti: lippu käännetään, elementti ottaa vaaditun tilan. Ei ehdollista if/else-rakennetta näkyvyyden ympärillä.
⁉️🤔 Usein kysytyt kysymykset
Miksi vanha koodini, jossa on .toggle(fn1, fn2), ei näytä virheitä konsolissa?
Vanha
.toggle()-muoto poistettiin metoditasolla: jQuery ei yksinkertaisesti löydä tällaista allekirjoitusta ja jättää sen hiljaisesti tekemättä mitään. Konsoli on tyhjä, koska.toggle(fn1, fn2)-kutsu on modernille jQuerylle syntaktisesti oikea mutta merkityksetön kutsu (argumentit ohitetaan). Tarkista jQuery-versiosi: jos se on 1.9 tai uudempi, vanha koodi on kuollut.
Voinko ottaa jQuery Migraten käyttöön ja olla kirjoittamatta koodia uusiksi?
Teknisesti kyllä. jQuery Migrate -lisäosa palauttaa poistetut metodit, mukaan lukien vanhan
.toggle()-metodin. Mutta tämä on väliaikainen apukeino: Migrate lisää noin 10 kt minifioituna ja on suunniteltu siirtymäkaudelle, ei pysyvään käyttöön. Jos sivusto toimii WordPressillä ja jQuery latautuu ytimestä, Migrate on siellä jo taaksepäin yhteensopivuuden vuoksi. Mutta siihen tukeutuminen omassa koodissa ei ole suositeltavaa: teema- tai lisäosapäivitys voi poistaa sen käytöstä milloin tahansa.
Kumpi on parempi, muuttuja vai data-attribuutti?
Yhdelle painikkeelle käytä muuttujaa (vähemmän koodia). Useille itsenäisille painikkeille tai dynaamisesti lisätyille elementeille käytä
.data()-metodia (tilan eristys). Jos painikkeita lisätään AJAXilla sivun latauksen jälkeen, käytä delegointia:$(document).on('click', '.toggle-btn', function() { ... }).
Toimiiko.toggle() mobiililaitteilla?
Kyllä. Moderni
.toggle()(animaatio) ja kaikki tämän artikkelin klikkauskäsittelijät toimivat oikein kosketustapahtumilla. jQuery normalisoiclick-tapahtuman mobiiliselaimille varhaisimmista versioistaan lähtien. Ainoa vivahde: iOS:ssä ennen versiota 12 elementeillä, joilla ei ollutcursor: pointer-määritystä, oli viivästetty klikkaus, mutta tämä ongelma ratkeaa yhdellä CSS-rivillätouch-action: manipulationpainikkeelle.
Mihin minun pitäisi sijoittaa jQuery-koodi WordPressissä?
Kolme vaihtoehtoa. Nopea: Code Snippets -lisäosa: lisää JS-koodi pätkään tyypillä "JavaScript", ja se latautuu automaattisesti footeriin. Oikeaoppinen: luo tiedosto
js/toggle.jslapsiteemaasi, rekisteröi sefunctions.php-tiedostossa:wp_enqueue_script('my-toggle', get_stylesheet_directory_uri() . '/js/toggle.js', array('jquery'), '1.0', true). Lopussa olevatrue-parametri lähettää skriptin footeriin, mikä on standardi DOM:n kanssa toimivalle koodille. Älä laita<script>-tagia suoraan artikkelin runkoon; WordPress-editori poistaa tagin.
Mikä lähestymistapa valita projektiisi
Jos sinulla on yksi painike, jossa on tekstin vaihto ja lohkon näkyvyys, käytä tilamuuttujaa. Kolme riviä, läpinäkyvä toiminta, triviaali debuggaus.
Jos vuorottelijoita on useita (verkkokauppa, asetuspaneeli, laajennettavien kohteiden lista), käytä vain .data()-metodia. Globaali muuttuja usealle painikkeelle luo kilpailutilanteen, jonka debuggaamiseen menee kauemmin kuin koodin kirjoittamiseen tavalla 2.
Kolmen tai useamman askeleen ketju vaatii laskurin ja switch-rakenteen. Älä monimutkaista totuusarvolipuilla sitä, mikä luontevasti sopii numeroille.
Tärkeintä: jos löydät hakutuloksista artikkelin, jossa on .toggle(fn1, fn2), sulje välilehti. jQuery on elossa, mutta tuo tietty metodi haudattiin vuonna 2013.
Voit päivittää tietosi JavaScript-pätkien ajamisesta lennossa artikkelissamme työskentelystä pätkien kanssa Chrome DevToolsissa, mikä on hyödyllistä tämän artikkelin koodin nopeaan testaamiseen.



