Qual è il modo migliore per aggiungere file javascript personalizzati al sito?

19 ago 2010, 11:18:46
Visualizzazioni: 33.5K
Voti: 73

Ho già aggiunto i miei script, ma volevo sapere qual è il modo migliore.
Ho semplicemente inserito un tag <script> direttamente nel header.php del mio template.

Esiste un metodo preferito per inserire file js esterni o personalizzati?
Come posso collegare un file js a una singola pagina? (Sto pensando alla pagina home)

5
Commenti

Ottima domanda! È una delle domande più comuni che le persone fanno e qualcosa che dobbiamo assolutamente documentare bene qui.

MikeSchinkel MikeSchinkel
19 ago 2010 13:03:57

Dai un'occhiata a la mia domanda di qualche giorno fa, la risposta a parte della tua domanda è lì: - Come Collegare File jQuery/Javascript Esterni con WordPress

Ben Everard Ben Everard
19 ago 2010 12:09:50

Grazie. L'avevo già visto, ma non copriva completamente la mia domanda.

naugtur naugtur
19 ago 2010 15:18:03

Va bene, sapevo che non avrebbe risposto a tutta la tua domanda ma per le persone che navigheranno in futuro c'è un riferimento all'altro post :-)

Ben Everard Ben Everard
19 ago 2010 15:20:30
Tutte le risposte alla domanda 4
10
82

Usa wp_enqueue_script() nel tuo tema

La risposta di base è usare wp_enqueue_script() in un hook wp_enqueue_scripts per il front end e admin_enqueue_scripts per l'amministrazione. Potrebbe assomigliare a questo (supponendo che tu stia chiamando dal file functions.php del tuo tema; nota come faccio riferimento alla directory degli stili):

<?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" );
}

Queste sono le basi.

Script predefiniti e dipendenze multiple

Ma supponiamo che tu voglia includere sia jQuery che jQuery UI Sortable dalla lista degli script predefiniti inclusi in WordPress e che il tuo script dipenda da loro? Facile, basta includere i primi due script usando gli handle predefiniti in WordPress e per il tuo script fornire un 3° parametro a wp_enqueue_script() che è un array degli handle degli script usati da ogni script, così:

<?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' ) );
}

Script in un plugin

E se invece vuoi farlo in un plugin? Usa la funzione plugins_url() per specificare l'URL del tuo file 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 );
}

Versionare i tuoi script

Nota anche che sopra abbiamo dato al nostro plugin un numero di versione e lo abbiamo passato come 4° parametro a wp_enqueue_script(). Il numero di versione viene mostrato nel sorgente come argomento della query nell'URL dello script e serve a forzare il browser a scaricare nuovamente un file potenzialmente in cache se la versione è cambiata.

Caricare gli script solo dove servono

La prima regola delle Performance Web dice di Minimizzare le Richieste HTTP quindi ogni volta che è possibile dovresti limitare gli script al caricamento solo dove servono. Ad esempio se hai bisogno del tuo script solo nell'amministrazione limitane il caricamento alle pagine di amministrazione usando l'hook admin_enqueue_scripts:

<?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 );
}

Caricare gli script nel footer

Se il tuo script è uno di quelli che devono essere caricati nel footer c'è un 5° parametro di wp_enqueue_script() che dice a WordPress di ritardarlo e posizionarlo nel footer (supponendo che il tuo tema si comporti bene e che effettivamente chiami l'hook wp_footer come tutti i buoni temi WordPress dovrebbero fare):

<?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 );
}

Controllo più granulare

Se hai bisogno di un controllo più granulare di così Ozh ha un ottimo articolo intitolato How To: Load Javascript With Your WordPress Plugin che dettaglia ulteriormente.

Disabilitare gli script per ottenere controllo

Justin Tadlock ha un bel articolo intitolato How to disable scripts and styles nel caso tu voglia:

  1. Combinare più file in file singoli (i risultati possono variare con JavaScript).
  2. Caricare i file solo nelle pagine dove usiamo lo script o lo stile.
  3. Smettila di usare !important nel nostro file style.css per fare semplici aggiustamenti CSS.

Passare valori da PHP a JS con wp_localize_script()

Sul suo blog Vladimir Prelovac ha un ottimo articolo intitolato Best practice for adding JavaScript code to WordPress plugins dove discute l'uso di wp_localize_script() per permetterti di impostare il valore delle variabili nel tuo PHP lato server per essere poi usato nel tuo Javascript lato client.

Controllo veramente granulare con wp_print_scripts()

E infine se hai bisogno di un controllo veramente granulare puoi dare un'occhiata a wp_print_scripts() come discusso su Beer Planet in un post intitolato How To Include CSS and JavaScript Conditionally And Only When Needed By The Posts.

Epilogo

Questo è tutto sulle Best Practice per includere file Javascript con WordPress. Se ho dimenticato qualcosa (cosa probabile) fammelo sapere nei commenti così posso aggiungere un aggiornamento per i futuri viaggiatori.

19 ago 2010 13:03:06
Commenti

Che articolo enorme! Ora ho tantissimo da scegliere ;)

naugtur naugtur
19 ago 2010 15:19:40

Ok, ha funzionato. Ora la seconda parte della domanda - come faccio a verificare se sono nella homepage?

naugtur naugtur
19 ago 2010 16:39:58

Agganciati a admin_init invece di chiedere is_admin(). Rimuovi il parametro versione se usi la CDN di Google, altrimenti la cache del browser manterrà due versioni: una senza la query string da altri siti e la tua.

fuxia fuxia
10 nov 2010 01:02:40

@toscho - Ottimo suggerimento, aggiornerò.

MikeSchinkel MikeSchinkel
10 nov 2010 03:11:25

@toscho Penso sia meglio rimuovere ver in modo selettivo piuttosto che tutta la query string (non è importante per Google ma potrebbe esserlo per URL più complessi), vedi la mia versione nella raccolta di functions.php @MikeSchinkel vedi lo stesso per un bel trucco sugli URL che recupererà sempre l'ultima versione dello script dalla CDN di Google, l'ho imparato recentemente

Rarst Rarst
10 nov 2010 09:14:12

@Rarst, sì, la mia funzione influisce solo sugli URI del CDN di Google. In altri casi potrebbe essere utile mantenere il parametro.

fuxia fuxia
10 nov 2010 16:39:24

Mike, potresti voler notare che quando dichiari un array di dipendenze, non hai bisogno di accodare quegli script individualmente. Con la maggior parte degli esempi pubblicati, in realtà non ti servono un paio di enqueue (verranno caricati comunque, semplicemente perché sono stati chiamati come dipendenze).

t31os t31os
11 nov 2010 16:28:25

@t31os - Sono un po' sovraccarico al momento; perché non aggiungere un'altra risposta qui per sfruttare la mia, dettagliando quel suggerimento?

MikeSchinkel MikeSchinkel
11 nov 2010 18:27:59
Mostra i restanti 5 commenti
2
11

Per completare la meravigliosa illustrazione di Mike sull'uso degli enqueue, vorrei far notare che gli script inclusi come dipendenze non hanno bisogno di essere accodati separatamente...

Userò l'esempio sotto l'intestazione Script in un Plugin nella risposta di Mike.

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);
}

Questo può essere semplificato come segue...

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);
}

Quando imposti le dipendenze, WordPress troverà e accoderà automaticamente gli script necessari per il tuo script, quindi non è necessario fare chiamate separate per questi script.

Inoltre, alcuni di voi potrebbero chiedersi se l'impostazione di dipendenze multiple possa causare l'output degli script nell'ordine sbagliato. Ecco un esempio:

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

Se lo script due dipendesse dallo script tre (cioè lo script tre dovrebbe caricarsi per primo), questo non sarebbe un problema. WordPress determinerà le priorità di accodamento per questi script e li produrrà nell'ordine corretto. In breve, WordPress risolverà magicamente tutto per te automaticamente.

13 nov 2010 14:04:45
Commenti

Penso che init non sia il posto giusto per inviare l'enqueue.

brasofilo brasofilo
22 set 2013 02:14:01

Il codice è stato originariamente copiato dalla risposta di Mike, poi modificato per illustrare un punto. Hai ragione comunque, quindi ho aggiornato la risposta per utilizzare un hook migliore e più corretto.

t31os t31os
28 gen 2014 16:42:20
0

Per piccoli pezzi di script, che potresti non voler includere in un file separato, ad esempio perché sono generati dinamicamente, WordPress 4.5 e versioni successive offre la funzione wp_add_inline_script. Questa funzione fondamentalmente aggancia lo script a un altro script.

Supponiamo, ad esempio, che stai sviluppando un tema e vuoi che il tuo cliente possa inserire i propri script (come Google Analytics o AddThis) attraverso la pagina delle opzioni. Potresti quindi utilizzare wp_add_inline_script per agganciare quello script al tuo file js principale (diciamo mainjs) in questo modo:

$custom_script = get_option('my-script')
if (!empty($custom_script)) wp_add_inline_script ('mainjs', $custom_script);
31 ott 2016 10:51:05
0

Il mio metodo preferito per ottenere buone prestazioni è, invece di utilizzare wp_enqueue_script, usare HEREDOC con l'API Fetch per caricare tutto in modo asincrono e in parallelo:

$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;

E poi inserirli nell'head, a volte insieme agli stili in questo modo:

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

Ottenendo un caricamento a cascata che appare così, caricando tutto contemporaneamente ma controllando l'ordine di esecuzione:

Descrizione immagine qui

Nota: Questo metodo richiede l'uso dell'API Fetch, che non è disponibile in tutti i browser.

17 apr 2017 23:22:54