Где и как размещать встроенный JavaScript на страницах
В интернете много статей о том, как вставлять внешние скрипты в документ с помощью метода wp_enqueue_script()
.
Среди статей я не нашел ничего, что объясняло бы, как добавлять встроенные скрипты, заключенные в тег <script>
.
Я использую теги <script>
в середине своих документов, хотя полагаю, что это не самый элегантный способ. Должен быть лучший способ добавления произвольных скриптов так, чтобы код автоматически перемещался в head или footer. Существует ли такой?

Я сейчас смотрю исходный код темы Twenty Seventeen в файле functions.php
, и там оставлен шаблон для встраивания script
(или любого другого кода) в документ с приоритетом. Вот обобщенный пример с использованием именованной функции:
function add_inline_script() {
echo "<script>/* делаем что-то крутое */</script>\n";
}
add_action( 'wp_head', 'add_inline_script', 0 );
Это может быть полезно, например, если вы загружаете скрипт с атрибутом async
, такой как альтернативный фрагмент асинхронного отслеживания Google Analytics, что позволяет запускать неблокирующие запросы скриптов сразу после начала парсинга документа (если разместить их перед блокирующими запросами).
Кроме async
, современные браузеры также позволяют управлять асинхронными зависимостями, используя Fetch API, что дает возможность загружать внешние зависимости асинхронно параллельно без риска возникновения состояния гонки.
Следующее изображение и пример демонстрируют использование этой техники для уменьшения времени загрузки страницы путем неблокирующей загрузки скриптов в теме Twenty Eleven с помощью Fetch Inject:
Рисунок 1: Скрипты темы Twenty Seventeen плюс
lazysizes
, загружаемые асинхронно параллельно.
Отвечая на вопрос о интерполяции строк. Используйте её при вставке произвольных блоков контента на страницу с помощью echo
, используя NOWDOC или HEREDOC, а также глобальные присваивания и интерполяцию строк с Fetch Inject, как показано здесь:
/**
* Загружаем скрипты с помощью Fetch Inject вместо wp_enqueue_script
* для более быстрой загрузки страниц и снижения воспринимаемой задержки.
*
* @since WordCamp Ubud 2017
* @link https://wordpress.stackexchange.com/a/263733/117731
* @link https://github.com/jhabdas/fetch-inject
*
*/
function add_inline_script() {
$twentyseventeen_l10n = array(
'quote' => twentyseventeen_get_svg( array( 'icon' => 'quote-right' ) ),
'expand' => __( 'Развернуть дочернее меню', 'twentyseventeen' ),
'collapse' => __( 'Свернуть дочернее меню', 'twentyseventeen' ),
'icon' => twentyseventeen_get_svg( array( 'icon' => 'angle-down', 'fallback' => true ) )
);
$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' )
];
$lazysizes_path = get_theme_file_uri( '/assets/js/lazysizes.min.js' );
$screen_reader_text_object_name = 'twentyseventeenScreenReaderText';
$twentyseventeen_l10n_data_json = json_encode($twentyseventeen_l10n);
$jquery_dependent_script_paths_json = json_encode($jquery_dependent_script_paths);
$inline_script = <<<EOD
window.{$screen_reader_text_object_name} = $twentyseventeen_l10n_data_json;
(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}"
]));
fetchInject(["{$lazysizes_path}"])
})();
EOD;
echo "<script>{$inline_script}</script>";
}
add_action('wp_head', 'add_inline_script', 0);
Уменьшает воспринимаемую задержку в стандартной теме Twenty Seventeen примерно на 50 процентов. Можно применять к любой теме.
Как это работает?
- Заменяет все скрипты, добавленные через
wp_enqueue_script
, чтобы они загружались быстрее с помощью Fetch Injection. (Примечание: см. документацию Fetch Inject для обратной совместимости со старыми браузерами.) - Использует HEREDOC для вывода всего в теге
script
вhead
. - Определяет глобальную переменную window, которую требует тема.
- Загружает все скрипты асинхронно параллельно, как показано на изображении выше, но ожидает завершения загрузки jQuery перед выполнением зависимостей (уже загруженных).
- Выполняет всю работу в IIFE, чтобы предотвратить утечку свободных переменных в область видимости
window
.
HEREDOC идеально подходит для контроля вывода, когда вам нужно сохранить уведомления об авторских правах или другое форматирование через смешанные шаблоны. Также это ускоряет отладку скриптов, когда у вас нет минифицированного кода под рукой или вы просто хотите вставить что-то в документ для тестирования.
Если вы хотите убедиться, что элементы добавляются только один раз, см. этот ответ: https://wordpress.stackexchange.com/a/131640/117731
Наконец, если вы хотите добавить код в подвал вместо заголовка, вы можете заменить wp_head
в вызове add_action
на wp_footer
.
РЕДАКТИРОВАТЬ: После дополнительного изучения я нашел эту статью в блоге Дэвида Уолша, которая предполагает, что простая вставка кода доступна как минимум с 2012 года. Удачи!

wp_enqueue_script()
— это единственно правильный способ добавления JavaScript на ваш сайт. Он позволяет вам и другим плагинам объявлять зависимости и даже отменять регистрацию скриптов при необходимости. Как упоминалось в другой теме сегодня, плагины кэширования не могут сжимать или минифицировать ваши скрипты, если вы не используете правильный метод WordPress.
Если вы посмотрите на страницу кодекса, вы увидите, что можно управлять тем, будет ли скрипт в заголовке или в подвале сайта.

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

Не отвечает на вопрос автора и не рассматривает реальные варианты использования, такие как admin_enqueue_scripts
, login_enqueue_scripts
или скрипты, являющиеся частью шорткодов, которым нужно дождаться wp_footer
. Или enqueue_embed_scripts
, которые предназначены для использования плагинами.

Хотя mrwweb прав, и этот метод следует использовать, в реальности ничто не идеально, и бывают случаи, когда применяются встроенные скрипты и стили. Вы можете использовать wp script is
для проверки скрипта и вывода их в заголовке или подвале с помощью wp_head
или wp_footer
.
Вы можете обратиться к ответу scribu в этом посте: wp enqueue inline script из-за зависимостей

Вы можете добавить встроенный JavaScript с помощью функции wp_add_inline_script.
function prince_scripts() {
// Подключаем основной скрипт темы
wp_enqueue_script( 'prince-script', get_template_directory_uri(). 'main.js');
// Применяем фильтр для возможности изменения значения
$hide_on_mobile = apply_filters( 'prince_hide_on_mobile', true );
// Формируем данные для вставки
$data = 'var hideOnMobile = ' . ( $hide_on_mobile ? 'true': 'false' ) . ';';
// Добавляем встроенный скрипт перед основным
wp_add_inline_script( 'prince-script', $data, 'before' );
}
// Подключаем функцию к хуку загрузки скриптов
add_action( 'wp_enqueue_scripts', 'prince_scripts');
