Skip to content

Wszystko o WordPressie, tworzeniu stron — i nie tylko

👉 Jak naprawić «$ is not a function» w WordPress: 4 sposoby

👉 Jak naprawić «$ is not a function» w WordPress: 4 sposoby

Edytuje Pan functions.php, dodaje parę linijek jQuery, a strona pada z białym ekranem. W konsoli świeci się: Uncaught TypeError: $ is not a function. Znajomy obrazek?

Z tym błędem spotyka się każdy deweloper WordPressa przynajmniej raz. Kopiuje Pan działający kod jQuery z CodePen lub snippetu, wstawia na stronę, a WordPress go nie rozumie. Przyczyną nie jest krzywy kod ani konflikt wtyczek. Przyczyną jest to, jak WordPress obchodzi się z jQuery.

Rozbierzemy cztery sprawdzone sposoby naprawienia błędu „$ is not a function", od bezpiecznej obudowy IIFE po całkowite wyłączenie noConflict. Każdy sposób z gotowym kodem, który można skopiować i wkleić.

💡 Szybki przegląd:

  • Proszę obudować kod jQuery w anonimową funkcję IIFE, to najbezpieczniejszy i najbardziej uniwersalny sposób
  • Proszę użyć jQuery document ready z parametrem dolara dla skryptów w head
  • Proszę przypisać własny alias przez noConflict, wygodne, gdy dolar jest zajęty przez inną bibliotekę
  • Proszę globalnie wyłączyć noConflict, tylko gdy na stronie nie ma innych bibliotek

Dlaczego pojawia się błąd „$ is not a function" w WordPressie

WordPress ładuje jQuery w trybie noConflict. Oznacza to, że zmienna $, krótki alias jQuery, nie jest dostępna globalnie. Deweloperzy rdzenia WordPressa zrobili to celowo, aby uniknąć konfliktów: wiele bibliotek JavaScript (Prototype, MooTools, stare wersje Bootstrapa) również używa $ jako swojego głównego skrótu.

Kiedy pisze Pan w swoim skrypcie:

1$("#element").hide();

WordPress nie wie, że $ to jQuery. Widzi wywołanie nieznanej funkcji i wyrzuca TypeError: $ is not a function. Poza WordPressem, na „gołej" stronie HTML, ten sam kod zadziałałby bez problemu, tam jQuery rejestruje $ globalnie.

Technicznie WordPress rozumie tylko pełną nazwę: jQuery("#element").hide(). Ale pisanie jQuery zamiast $ w każdej linijce wieloliniowego skryptu jest niewygodne, kod puchnie i traci czytelność. Na szczęście są cztery sposoby, aby obejść to ograniczenie.

Błąd $ is not a function w konsoli WordPress

Przed jakimikolwiek zmianami w plikach motywu proszę zrobić kopię zapasową strony. Jeden pominięty średnik w functions.php i strona pada. Z backupem cofnie Pan zmiany w minutę.

Sposób 1: Obudowa IIFE, bezpieczna i uniwersalna

Najpewniejszy sposób przywrócenia $ w skryptach WordPressa to natychmiastowo wywołana funkcja (IIFE, Immediately Invoked Function Expression). Przekazuje Pan jQuery jako argument, a wewnątrz funkcji odwołuje się Pan do niego przez zwykły $.

Kod dla footer.php lub niskopoziomowego wstawienia (stopka strony):

1(function($) {
2 // Ваш jQuery-код здесь
3 $("#element").hide();
4})(jQuery);

Co tu się dzieje: anonimowa funkcja przyjmuje parametr $ i natychmiast jest wywoływana z argumentem jQuery. Wewnątrz tej funkcji $ === jQuery, a na zewnątrz $ tak samo jest niezdefiniowany. Konflikt z innymi bibliotekami jest wykluczony.

Ten sposób działa dla skryptów w stopce. Jeśli skrypt ma zadziałać w <head>, proszę użyć sposobu 2.

Sposób 2: jQuery(document).ready z parametrem $

Kiedy skrypt ma się wykonać w nagłówku strony (przed załadowaniem DOM), proszę obudować go w jQuery(document).ready. Proszę zwrócić uwagę: do parametru callbacku przekazywany jest $, to nie błąd, a kluczowy moment.

Kod dla header.php lub functions.php przez wp_enqueue_script:

1jQuery(document).ready(function($) {
2 // Ваш jQuery-код здесь
3 console.log($);
4});

Metoda .ready() czeka na pełne załadowanie DOM, a jQuery przekazuje siebie do callbacku jako $. Wewnątrz tego callbacku $ znowu działa jak w zwykłym środowisku JavaScript. I, w przeciwieństwie do sposobu 1, skrypt startuje z <head>, co jest przydatne dla krytycznych operacji inicjalizacji.

Większość deweloperów motywów i wtyczek wie o tej właściwości WordPressa, dlatego w produktach wysokiej jakości prawie zawsze zobaczy Pan jQuery zamiast $ lub jedną z powyższych obudów.

Sposób 3: Stworzyć własny alias przez noConflict

jQuery pozwala nie tylko przywrócić $, ale też przypisać dowolny inny krótki alias, na przykład zmienne $j lub jq, czy dowolną zmienną według uznania. Jest to wygodne, gdy na stronie jest już używana inna biblioteka, która zajęła $.

1var jq = jQuery.noConflict();
2jq("div p").hide();
3
4// Другая библиотека продолжает использовать свой $
5$("content").style.display = "none";

Metoda jQuery.noConflict() zwalnia $ dla innych bibliotek i zwraca jQuery do Pana zmiennej (jq w przykładzie). Po tym wywołania są realizowane przez jq(...), a $ działa jak u sąsiedniej biblioteki, konflikt znika całkowicie.

To podejście jest szczególnie przydatne na stronach, gdzie motyw WordPressa sąsiaduje z zewnętrznym frameworkiem JavaScript, który używa $ do swoich celów.

Sposób 4: Całkowicie wyłączyć noConflict (z ostrożnością)

Jeśli ma Pan pewność, że na stronie nie ma innych bibliotek, które roszczą sobie prawo do $, można wyłączyć tryb noConflict globalnie:

1$ = jQuery.noConflict(true);

Po tej linijce $ znowu działa jako globalny alias jQuery wszędzie, w dowolnym skrypcie, w dowolnym miejscu strony. Jednak ten sposób jest najbardziej ryzykowny. Jeśli później zainstaluje Pan wtyczkę, która również używa $, strona się zepsuje z trudnym do odtworzenia bugiem.

Rekomendujemy sposoby 1 i 2 jako podstawowe, są bezpieczne, izolowane i pokrywają przeważającą większość rzeczywistych scenariuszy. Sposób 4 jest dla sytuacji, gdy utrzymuje Pan duży legacy-script i nie może obudować każdej funkcji osobno.

Na filmie powyżej jest poglądowa demonstracja wszystkich czterech sposobów w działaniu. Proszę obejrzeć, jeśli woli Pan wyjaśnienie wizualne od tekstowego.

⁉️🤔 Częste pytania

Dlaczego w WordPressie w ogóle wyłączono $ dla jQuery?

Deweloperzy rdzenia WordPressa włączyli jQuery.noConflict() domyślnie, aby zabezpieczyć strony przed konfliktami z innymi bibliotekami JavaScript. Prototype.js, MooTools i niektóre stare frameworki również rejestrują globalną zmienną $. Gdyby WordPress oddawał $ dla jQuery, dowolny motyw czy wtyczka z taką biblioteką psułyby panel administracyjny lub frontend. WordPress uruchamia jQuery w trybie noConflict od wersji 3.6, to nie bug, a decyzja architektoniczna. Zmienna $ w globalnym zakresie widoczności pozostaje wolna dla zewnętrznych bibliotek. Właśnie dlatego $("#id") poza obudową zawsze będzie wyrzucać TypeError.

Czy można po prostu wstawić jQuery drugi raz, poza WordPressem?

Formalnie tak, może Pan podłączyć jQuery przez link CDN drugi raz, a ona zarejestruje $ globalnie. Ale to zła praktyka: dwie wersje jQuery na jednej stronie konfliktują, rozmiar strony rośnie, a wtyczki WordPressa oczekują właśnie tej wersji jQuery, która jest zarejestrowana przez wp_enqueue_script. Proszę zawsze pracować z tą wersją jQuery, którą dostarcza WordPress, jest ona przetestowana pod kątem kompatybilności z rdzeniem i panelem administracyjnym. Podłączanie jQuery ponownie oznacza tworzenie nowych problemów zamiast rozwiązania pierwotnego.

Co robić, jeśli błąd pojawia się tylko na poszczególnych stronach?

Proszę sprawdzić, czy konkretna strona nie podłącza zewnętrznego skryptu przez wtyczkę lub widget. Niektóre wtyczki cache'owania i minifikacji agresywnie zmieniają kolejność skryptów i jQuery może załadować się później niż Pana kod. Proszę wyłączać wtyczki optymalizacji po jednej, aby znaleźć winowajcę. W większości przypadków problem „$ is not a function na jednej stronie" jest spowodowany kolejnością ładowania skryptów. Wtyczka minifikacji lub cache'owania umieszcza Pana skrypt przed jQuery i $ jeszcze nie istnieje w momencie wywołania. Rozwiązanie: albo wykluczyć skrypt z minifikacji, albo obudować go w IIFE ze sposobu 1, który nie zależy od globalnego $.

Czy jest gotowa wtyczka, która naprawia ten błąd?

Specjalnej wtyczki „do naprawiania $ is not a function" nie ma i nie jest potrzebna. Problem rozwiązuje się jedną linijką-obudową, a instalowanie osobnej wtyczki dla tego jest nadmiarowe. Są jednak wtyczki takie jak Code Snippets, które pozwalają dodawać kod JavaScript i PHP bez edycji plików motywu, jest to bezpieczniejsze dla początkujących. Code Snippets przechowuje Pana kod w bazie danych, a nie w functions.php. Jeśli popełni Pan błąd składniowy, wtyczka automatycznie cofnie zmiany i strona nie padnie. Rekomendujemy początkującym dodawanie dowolnego kodu JS właśnie przez nią, a nie przez edycję plików motywu.

Błąd „$ is not a function" naprawiony, co dalej?

Główny wniosek: problem nie leży w Pana kodzie ani w WordPressie. To standardowe zachowanie CMS-a i naprawia się je jedną obudową. W przeważającej większości przypadków wystarczy sposób 1 (IIFE) lub sposób 2 (.ready() z $). Nie psują one innych skryptów i działają w dowolnej wersji WordPressa, od 4.0 do najnowszej.

Jeśli często pracuje Pan z jQuery w WordPressie, proszę wyrobić nawyk zaczynania każdego skryptu od (function($) { i kończenia })(jQuery);, wejdzie to w pamięć mięśniową w tydzień i na zawsze uwolni od błędu.

Proszę podzielić się artykułem z kolegami, którzy jeszcze edytują functions.php na chybił trafił, jedna gotowa obudowa zaoszczędzi im godzinę debugowania.