Каков предпочтительный способ добавления пользовательских файлов JavaScript на сайт?


68

Я уже добавил свои сценарии, но я хотел знать предпочтительный способ.
Я просто поместил <script>тег прямо в header.phpмой шаблон.

Есть ли предпочтительный способ вставки внешних или пользовательских файлов js?
Как бы я связал файл JS на одной странице? (Я имею в виду домашнюю страницу)



4
Отличный вопрос! Это очень распространенный вопрос, который нам обязательно нужно задокументировать.
MikeSchinkel

Спасибо. Я уже видел это, но это не полностью охватило мой вопрос.
naugtur

Это нормально, я знал, что это не ответит на все ваши вопросы, но для людей, которые будут заниматься серфингом в будущем, есть ссылка на другой пост :-)
Бен Эверард,

Ответы:


78

Используйте wp_enqueue_script()в своей теме

Основной ответ заключается в том, чтобы использовать wp_enqueue_script()в качестве wp_enqueue_scriptsпереднего конца admin_enqueue_scriptsдля администратора. Это может выглядеть примерно так (предполагается, что вы звоните из functions.phpфайла своей темы ; обратите внимание, как я ссылаюсь на каталог таблиц стилей):

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

Это основы.

Предопределенные и несколько зависимых скриптов

Но допустим, вы хотите включить jQuery и jQuery UI Sortable из списка скриптов по умолчанию, включенных в WordPress, и хотите, чтобы ваш скрипт зависел от них? Легко, просто включите первые два скрипта, используя предопределенные дескрипторы, определенные в WordPress, и для вашего скрипта предоставьте 3-й параметр, wp_enqueue_script()который представляет собой массив дескрипторов скриптов, используемых каждым скриптом, например:

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

Скрипты в плагине

Что если вы хотите сделать это в плагине? Используйте plugins_url()функцию, чтобы указать URL вашего файла 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 );
}

Создание версий ваших скриптов

Также обратите внимание, что выше мы дали нашему плагину номер версии и передали его в качестве 4-го параметра wp_enqueue_script(). Номер версии выводится в источнике в качестве аргумента запроса в URL-адресе сценария и служит для того, чтобы заставить браузер повторно загружать, возможно, кешированный файл в случае изменения версии.

Загружайте сценарии только на тех страницах, где это необходимо

Первое правило веб-производительности гласит: « Минимизировать HTTP-запросы», поэтому, по возможности, следует ограничивать загрузку сценариев только при необходимости. Например, если вам нужен только ваш скрипт в админке, ограничьте его страницами администратора, используя 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 );
}

Загрузите свои скрипты в нижний колонтитул

Если ваши скрипты являются одними из тех, которые должны быть загружены в нижний колонтитул, есть 5-й параметр, wp_enqueue_script()который сообщает WordPress отложить его и поместить в нижний колонтитул (при условии, что ваша тема не ведет себя неправильно и что он действительно вызывает хук wp_footer, как и все хорошие темы WordPress должны )

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

Более точный контроль

Если вам нужен более точный контроль, чем у этого, у Ozh есть отличная статья под названием « Как: загрузить Javascript с вашим плагином WordPress», в которой более подробно.

Отключение скриптов для получения контроля

У Джастина Тэдлока есть хорошая статья под названием « Как отключить скрипты и стили, если вы хотите:

  1. Объедините несколько файлов в один файл (пробег может варьироваться в зависимости от JavaScript здесь).
  2. Загружайте файлы только на те страницы, на которых мы используем скрипт или стиль.
  3. Прекратите использовать! Важное в нашем файле style.css, чтобы сделать простые настройки CSS.

Передача значений из PHP в JS с wp_localize_script()

В своем блоге у Владимира Преловака есть отличная статья, озаглавленная « Лучшие практики по добавлению кода JavaScript в плагины WordPress», в которой он обсуждает использование, wp_localize_script()чтобы позволить вам установить значение переменных в вашем PHP на стороне сервера, которое впоследствии будет использоваться в вашем Javascript на стороне клиента.

Действительно мелкозернистый контроль с wp_print_scripts()

И, наконец, если вам нужен действительно детальный контроль, вы можете посмотреть, wp_print_scripts()как обсуждалось на Beer Planet в посте, озаглавленном « Как включить CSS и JavaScript условно и только тогда, когда это необходимо в сообщениях» .

Epiloque

Вот и все, что касается практики включения файлов Javascript в WordPress. Если я что-то пропустил (что, вероятно, есть), обязательно сообщите мне об этом в комментариях, чтобы я мог добавить обновление для будущих путешественников.


1
Это огромная статья! Теперь мне есть из чего выбирать;)
naugtur

Хорошо, это сработало. Теперь вторая часть вопроса - как мне проверить, нахожусь ли я на домашней странице?
naugtur

Ищите ответ здесь: wordpress.stackexchange.com/questions/575/...
naugtur

3
Зацепиться admin_initвместо того, чтобы просить is_admin(). Удалите параметр version, если вы используете Google CDN, иначе в кеше браузера будут храниться две версии: одна без строки запроса с других сайтов и ваша.
fuxia

@ toscho - Хороший звонок, я обновлю.
MikeSchinkel

11

Чтобы похвалить Майкла за прекрасную иллюстрацию использования enqueues, я просто хочу отметить, что сценарии, включенные как зависимости, не нужно ставить в очередь ...

Я буду использовать пример под заголовком « Сценарии в плагине» в ответе Майка.

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

Это можно урезать, чтобы прочитать ..

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

Когда вы устанавливаете зависимости, WordPress найдет и поставит их в очередь для вашего скрипта, поэтому вам не нужно будет делать какие-либо независимые вызовы для этих скриптов.

Кроме того, некоторые из вас могут задаться вопросом, может ли установка нескольких зависимостей привести к выводу скриптов в неправильном порядке, здесь приведу пример

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

Если сценарий два зависел от сценария три (т.е. сценарий три должен загружаться первым), это не имеет значения, WordPress определит приоритеты постановки в очередь для этих сценариев и выведет их в правильном порядке, короче говоря, все это выполняется автоматически для вас по WordPress.


Я думаю, что initне самое подходящее место для отправки в очередь.
brasofilo

Код был первоначально скопирован из ответа Майка, затем откорректирован, чтобы проиллюстрировать точку. Тем не менее, вы правы, поэтому я обновил ответ, чтобы использовать лучший и более правильный хук.
t31os

0

Для небольших фрагментов скриптов, которые вы, возможно, не захотите включать в отдельный файл, например, потому что они генерируются динамически, WordPress 4.5 и другие предложения wp_add_inline_script. Эта функция в основном привязывает скрипт к другому скрипту.

Допустим, например, что вы разрабатываете тему и хотите, чтобы ваш клиент мог вставлять свои собственные скрипты (например, Google Analytics или AddThis) через страницу параметров. Затем вы можете использовать wp_add_inline_scriptэтот скрипт для фиксации вашего основного js-файла (скажем так mainjs):

$custom_script = get_option('my-script')
if (!empty($custom_script)) wp_add_inline_script ('mainjs', $custom_script);

0

Мой предпочтительный способ - добиться хорошей производительности, поэтому вместо использования wp_enqueue_scriptя использую HEREDOC с Fetch API для асинхронной загрузки всего параллельно:

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

А затем вставьте их в голову, иногда вместе с такими стилями:

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

В результате получается водопад, который выглядит следующим образом, загружая все сразу, но контролируя порядок выполнения:

введите описание изображения здесь

Примечание. Для этого необходимо использовать API Fetch, который доступен не во всех браузерах.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.