Jaki jest preferowany sposób dodawania niestandardowych plików javascript do witryny?

68

Dodałem już swoje skrypty, ale chciałem poznać preferowany sposób.
Po prostu wstawiam <script>tag bezpośrednio do header.phpmojego szablonu.

Czy istnieje preferowana metoda wstawiania zewnętrznych lub niestandardowych plików js?
Jak powiązać plik js z jedną stroną? (Mam na myśli stronę główną)

naugtur
źródło
Spójrz na moje pytanie sprzed kilku dni , odpowiedź na część twojego pytania jest tam: - Jak połączyć zewnętrzne pliki jQuery / JavaScript z WordPress
Ben Everard
4
Świetne pytanie! Ludzie pytają o to bardzo często i coś, co zdecydowanie musimy tutaj dobrze udokumentować.
MikeSchinkel,
Dzięki. Widziałem to już, ale nie wyczerpało to w pełni mojego pytania.
naugtur,
W porządku, wiedziałem, że nie odpowie na wszystkie twoje pytania, ale dla osób surfujących w przyszłości jest odniesienie do drugiego postu :-)
Ben Everard

Odpowiedzi:

78

Użyj wp_enqueue_script()w swoim motywie

Odpowiedź podstawowym jest użycie wp_enqueue_script()w wp_enqueue_scriptshak do przodu admin_enqueue_scriptsdla administratora. Może to wyglądać mniej więcej tak (zakładając, że dzwonisz z functions.phppliku motywu ; zwróć uwagę na to, jak odwołuję się do katalogu arkuszy stylów):

<?php
add_action( 'wp_enqueue_scripts', 'mysite_enqueue' );

function mysite_enqueue() {
  $ss_url = get_stylesheet_directory_uri();
  wp_enqueue_script( 'mysite-scripts', "{$ss_url}/js/mysite-scripts.js" );
}

To są podstawy.

Wstępnie zdefiniowane i wiele skryptów zależnych

Powiedzmy, że chcesz dołączyć jQuery i jQuery UI Sortable z listy domyślnych skryptów zawartych w WordPress i chcesz, aby Twój skrypt był od nich zależny? Łatwo, wystarczy dołączyć dwa pierwsze skrypty za pomocą wstępnie zdefiniowanych uchwytów zdefiniowanych w WordPress, a dla swojego skryptu podaj trzeci parametr, do wp_enqueue_script()którego należy tablica uchwytów skryptu używanych przez każdy skrypt, na przykład:

<?php
add_action( 'wp_enqueue_scripts', 'mysite_enqueue' );

function mysite_enqueue() {
  $ss_url = get_stylesheet_directory_uri();
  wp_enqueue_script( 'mysite-scripts', "{$ss_url}/js/mysite-scripts.js", array( 'jquery', 'jquery-ui-sortable' ) );
}

Skrypty we wtyczce

Co jeśli chcesz to zrobić we wtyczce? Użyj plugins_url()funkcji, aby określić adres URL pliku JavaScript:

<?php
define( 'MY_PLUGIN_VERSION', '2.0.1' );
add_action( 'wp_enqueue_scripts', 'my_plugin_enqueue' );

function my_plugin_enqueue() {
  wp_enqueue_script( 'my-script', plugins_url('/js/my-script.js',__FILE__), array('jquery','jquery-ui-sortable'), MY_PLUGIN_VERSION );
}

Wersjonowanie skryptów

Zauważ też, że powyżej podaliśmy naszemu pluginowi numer wersji i przekazaliśmy go jako czwarty parametr do wp_enqueue_script(). Numer wersji jest wyprowadzany w źródle jako argument zapytania w adresie URL do skryptu i służy do zmuszenia przeglądarki do ponownego pobrania ewentualnie buforowanego pliku, jeśli wersja zostanie zmieniona.

Ładuj skrypty tylko tam, gdzie to konieczne

1-ty reguła Web Performance mówi Minimalizacja żądań HTTP , więc w miarę możliwości należy ograniczyć skrypty, aby załadować tylko w razie potrzeby. Na przykład, jeśli potrzebujesz skryptu tylko w adminie, ogranicz go do stron administracyjnych za pomocą admin_enqueue_scriptshaka:

<?php
define( 'MY_PLUGIN_VERSION', '2.0.1' );
add_action( 'admin_enqueue_scripts', 'my_plugin_admin_enqueue' );

function my_plugin_admin_enqueue() {
  wp_enqueue_script( 'my-script', plugins_url( '/js/my-script.js', __FILE__ ), array( 'jquery', 'jquery-ui-sortable' ), MY_PLUGIN_VERSION );
}

Załaduj swoje skrypty w stopce

Jeśli twoje skrypty są jednym ze skryptów, które należy załadować do stopki, istnieje piąty parametr, wp_enqueue_script()który mówi WordPressowi, aby go opóźnił i umieścił w stopce (zakładając, że Twój motyw nie zachował się źle i że rzeczywiście wywołuje hak wp_footer jak wszystkie dobre motywy WordPress powinny ):

<?php
define( 'MY_PLUGIN_VERSION', '2.0.1' );
add_action( 'admin_enqueue_scripts', 'my_plugin_admin_enqueue' );

function my_plugin_admin_enqueue() {
  wp_enqueue_script( 'my-script', plugins_url( '/js/my-script.js', __FILE__ ), array( 'jquery', 'jquery-ui-sortable' ), MY_PLUGIN_VERSION, true );
}

Dokładniejsza kontrola ziarna

Jeśli potrzebujesz dokładniejszej kontroli, Ozh ma świetny artykuł zatytułowany Porady : ładowanie Javascript za pomocą wtyczki WordPress, która zawiera więcej szczegółów.

Wyłączanie skryptów w celu uzyskania kontroli

Justin Tadlock ma fajny artykuł zatytułowany Jak wyłączyć skrypty i style, jeśli chcesz:

  1. Łącz wiele plików w pojedyncze pliki (przebieg może się różnić w JavaScript tutaj).
  2. Załaduj pliki tylko na strony, na których używamy skryptu lub stylu.
  3. Przestań używać! Ważne w naszym pliku style.css, aby dokonywać prostych korekt CSS.

Przekazywanie wartości z PHP do JS za pomocą wp_localize_script()

Na swoim blogu Vladimir Prelovac ma świetny artykuł zatytułowany Najlepsza praktyka dodawania kodu JavaScript do wtyczek WordPress, w którym omawia użycie, wp_localize_script()aby umożliwić ustawienie wartości zmiennych w PHP po stronie serwera, aby później użyć w JavaScript po stronie klienta.

Naprawdę drobnoziarnista kontrola dzięki wp_print_scripts()

I na koniec, jeśli potrzebujesz naprawdę drobiazgowej kontroli, możesz zajrzeć, wp_print_scripts()jak omówiono na Beer Planet w poście zatytułowanym Jak dołączyć CSS i JavaScript warunkowo i tylko wtedy, gdy jest potrzebny postom .

Epiloque

To wszystko na temat najlepszych praktyk dołączania plików JavaScript do WordPress. Jeśli coś przeoczyłem (co prawdopodobnie mam), daj mi znać w komentarzach, abym mógł dodać aktualizację dla przyszłych podróżników.

MikeSchinkel
źródło
1
To ogromny artykuł! Teraz mam dużo do wyboru;)
naugtur
Ok, zadziałało. Teraz druga część pytania - jak sprawdzić, czy jestem na stronie głównej?
naugtur,
Poszukaj odpowiedzi tutaj: wordpress.stackexchange.com/questions/575/…
naugtur
3
Zaczep się admin_initzamiast prosić is_admin(). Usuń parametr wersji, jeśli korzystasz z sieci CDN Google, w przeciwnym razie pamięć podręczna przeglądarki będzie przechowywać dwie wersje: jedna bez ciągu zapytania z innych witryn i twoją.
fuxia
@toscho - Dobra rozmowa, zaktualizuję.
MikeSchinkel,
11

Aby skomplementować wspaniałą ilustrację użycia kolejek Mikesa, chcę jedynie zaznaczyć, że skrypty zawarte jako zależności nie muszą być kolejkowane ...

Użyję tego przykładu pod nagłówkiem Skrypty we wtyczce w odpowiedzi Mike'a.

define('MY_PLUGIN_VERSION','2.0.1');

add_action( 'wp_enqueue_scripts', 'my_plugin_enqueue_scripts' );
function my_plugin_enqueue_scripts() {
    wp_enqueue_script('jquery');
    wp_enqueue_script('jquery-ui-sortable');
    wp_enqueue_script('my-script',plugins_url('/js/my-script.js',__FILE__),array('jquery','jquery-ui-sortable'),MY_PLUGIN_VERSION);
}

Można to przyciąć, aby przeczytać.

define('MY_PLUGIN_VERSION','2.0.1');

add_action( 'wp_enqueue_scripts', 'my_plugin_enqueue_scripts' );
function my_plugin_enqueue_scripts() {
    wp_enqueue_script('my-script', plugins_url( '/js/my-script.js', __FILE__ ), array('jquery','jquery-ui-sortable'), MY_PLUGIN_VERSION);
}

Po ustawieniu zależności WordPress znajdzie je w kolejce i przygotuje do skryptu, więc nie musisz wykonywać żadnych niezależnych wywołań dla tych skryptów.

Ponadto niektórzy z was mogą się zastanawiać, czy ustawienie wielu zależności może spowodować, że skrypty będą wyświetlać się w niewłaściwej kolejności, tutaj podam przykład

wp_enqueue_script( 'first-script', 'example/path/example_script_1.js', array('second-script','third-script') );

Jeśli skrypt drugi był zależny od skryptu trzeciego (tzn. Skrypt trzeci powinien zostać załadowany jako pierwszy), nie miało to znaczenia, WordPress określi priorytety kolejki dla tych skryptów i wyświetli je we właściwej kolejności, krótko mówiąc, wszystko zostanie opracowane automatycznie dla ciebie przez WordPress.

t31os
źródło
Myślę, że initnie jest właściwe miejsce na wysłanie kolejki.
brasofilo
Kod został pierwotnie skopiowany z odpowiedzi Mike'a, a następnie dostosowany w celu zilustrowania pewnej kwestii. Masz jednak rację, więc zaktualizowałem odpowiedź, aby użyć lepszego i bardziej poprawnego haka.
t31os
0

W przypadku małych fragmentów skryptów, których możesz nie chcieć umieszczać w osobnym pliku, na przykład ponieważ są one generowane dynamicznie, WordPress 4.5 i dalsze oferty wp_add_inline_script. Ta funkcja zasadniczo blokuje skrypt na innym skrypcie.

Załóżmy na przykład, że opracowujesz motyw i chcesz, aby Twój klient mógł wstawiać własne skrypty (takie jak Google Analytics lub AddThis) na stronie opcji. Następnie można użyć wp_add_inline_scriptdo zablokowania tego skryptu w głównym pliku js (powiedzmy mainjs) w następujący sposób:

$custom_script = get_option('my-script')
if (!empty($custom_script)) wp_add_inline_script ('mainjs', $custom_script);
cjbj
źródło
0

Moim preferowanym sposobem jest osiągnięcie dobrej wydajności, więc zamiast wp_enqueue_scriptużywać HEREDOC z interfejsem API Fetch, aby ładować wszystko asynchronicznie równolegle:

$jquery_script_path = '/wp-includes/js/jquery/jquery.js?ver=1.12.4';
$jquery_dependent_script_paths = [
  get_theme_file_uri( '/assets/js/global.js' ),
  get_theme_file_uri( '/assets/js/jquery.scrollTo.js' ),
  get_theme_file_uri( '/assets/js/skip-link-focus-fix.js' ),
  get_theme_file_uri( '/assets/js/navigation.js' )
];
$jquery_dependent_script_paths_json = json_encode($jquery_dependent_script_paths);
$inline_scripts = <<<EOD
<script>
(function () {
  'use strict';
  if (!window.fetch) return;
  /**
   * Fetch Inject v1.6.8
   * Copyright (c) 2017 Josh Habdas
   * @licence ISC
   */
  var fetchInject=function(){"use strict";const e=function(e,t,n,r,o,i,c){i=t.createElement(n),c=t.getElementsByTagName(n)[0],i.type=r.blob.type,i.appendChild(t.createTextNode(r.text)),i.onload=o(r),c?c.parentNode.insertBefore(i,c):t.head.appendChild(i)},t=function(t,n){if(!t||!Array.isArray(t))return Promise.reject(new Error("`inputs` must be an array"));if(n&&!(n instanceof Promise))return Promise.reject(new Error("`promise` must be a promise"));const r=[],o=n?[].concat(n):[],i=[];return t.forEach(e=>o.push(window.fetch(e).then(e=>{return[e.clone().text(),e.blob()]}).then(e=>{return Promise.all(e).then(e=>{r.push({text:e[0],blob:e[1]})})}))),Promise.all(o).then(()=>{return r.forEach(t=>{i.push({then:n=>{"text/css"===t.blob.type?e(window,document,"style",t,n):e(window,document,"script",t,n)}})}),Promise.all(i)})};return t}();
  fetchInject(
    $jquery_dependent_script_paths_json
  , fetchInject([
    "{$jquery_script_path}"
  ]));
})();
</script>
EOD;

A następnie włóż je do głowy, czasami wraz z takimi stylami:

function wc_inline_head() {
  global $inline_scripts;
  echo "{$inline_scripts}";
  global $inline_styles;
  echo "{$inline_styles}";
}

Powoduje powstanie wodospadu, który wygląda tak, ładując wszystko na raz, ale kontrolując kolejność wykonywania:

wprowadź opis zdjęcia tutaj

Uwaga: Wymaga to użycia interfejsu API pobierania, który nie jest dostępny we wszystkich przeglądarkach.

Josh Habdas
źródło