Когда использовать add_action('init') против add_action('wp_enqueue_scripts')

20 июн. 2012 г., 17:55:42
Просмотры: 35.4K
Голосов: 11

В файле functions.php моей темы я использую add_action для контроля над тем, где загружается jQuery (в футере вместе с другими скриптами темы).

Проблема в том, что когда я использую add_action('wp_enqueue_scripts'), он срабатывает только если не загружены плагины. Однако метод add_action('init') работает во всех случаях.

Насколько я помню, add_action('wp_enqueue_scripts') предпочтительнее в этом случае. Если это так, как можно заставить его работать во всех случаях?

В файле functions.php

//if(!is_admin()){add_action('init', 'my_theme_init');} //ЭТО РАБОТАЕТ ВСЕГДА
//add_action('wp_enqueue_scripts', 'my_theme_init'); //ЭТО РАБОТАЕТ ТОЛЬКО КОГДА НЕТ ПЛАГИНОВ

if(!is_admin())
{
    require_once(TEMPLATEPATH . '/functions_public.php');   
}

В файле functions_public.php

function my_theme_init()
{

/* ПРЕДОТВРАЩАЕМ ДУБЛИРОВАНИЕ JQUERY ИЗ ПЛАГИНОВ
**************************************************/
wp_deregister_script('jquery');

/* ЗАГРУЖАЕМ ЛОКАЛЬНУЮ КОПИЮ JQUERY WORDPRESS И ПОЛЬЗОВАТЕЛЬСКИЕ СКРИПТЫ ТЕМЫ В ФУТЕР
***********************************************/
wp_register_script('jquery', get_bloginfo('template_directory').'/scripts.mythemescripts.js',false,false,true);

wp_enqueue_script('jquery');

}

Второй метод, использующий add_action('wp_enqueue_scripts'), по-видимому, не выполняется в условиях, когда присутствует плагин, который прописывает зависимости скриптов в тему.

5
Комментарии

Пожалуйста, не регистрируйте свою собственную копию jQuery - используйте версию, поставляемую с WordPress, иначе вы рискуете сломать плагины :)

Stephen Harris Stephen Harris
20 июн. 2012 г. 18:02:30

Согласен, на самом деле я использую встроенную версию jQuery. Я просто загружаю её в один общий .js-файл (mythemescripts.js) вместе с другими js-файлами, которые нужны моей теме, чтобы уменьшить количество HTTP-запросов.

N2Mystic N2Mystic
20 июн. 2012 г. 18:11:11

Во всех браузерах, как только скрипт запрашивается с вашего сайта один раз, он кешируется локально. Дополнительный HTTP-запрос будет только при самой первой загрузке страницы. Если вы объедините все скрипты в один, вам придется изменять его каждый раз, когда WordPress выпускает обновление с новой версией jQuery. Это == кошмар поддержки.

EAMann EAMann
20 июн. 2012 г. 18:17:05

@EAMann, при первой установке темы и каждый раз при сохранении страницы настроек темы, я перезаписываю файл mythemescripts.js, загружая в него последнюю версию библиотеки jquery. Если пользователь обновляет версию WP, моя процедура настроек темы загружает jquery, который поставляется с этой версией. Он всегда актуален.

N2Mystic N2Mystic
20 июн. 2012 г. 18:22:28

Проблема всё ещё возникает, когда вызов jquery содержится в теле документа перед футером. Очевидно, jQuery(document).ready срабатывает до того, как скрипт .js загружается в футер.

N2Mystic N2Mystic
19 февр. 2014 г. 19:53:19
Все ответы на вопрос 3
2
28

Многие разработчики плагинов делают вещи неправильно. Правильный способ — использовать хук wp_enqueue_scripts, как вы и пытаетесь сделать.

Однако вот порядок выполнения хуков в типичном запросе:

  • muplugins_loaded
  • registered_taxonomy
  • registered_post_type
  • plugins_loaded
  • sanitize_comment_cookies
  • setup_theme
  • load_textdomain
  • after_setup_theme
  • auth_cookie_malformed
  • auth_cookie_valid
  • set_current_user
  • init
  • widgets_init
  • register_sidebar
  • wp_register_sidebar_widget
  • wp_default_scripts
  • wp_default_stypes
  • admin_bar_init
  • add_admin_bar_menus
  • wp_loaded
  • parse_request
  • send_headers
  • parse_query
  • pre_get_posts
  • posts_selection
  • wp
  • template_redirect
  • get_header
  • wp_head
  • wp_enqueue_scripts
  • wp_print_styles
  • wp_print_scripts
  • ... и многое другое

Дело в том, что изначально разработчикам говорили использовать хук init для подключения скриптов. До того, как появился хук wp_enqueue_script, это считалось "правильным" способом, и руководства, пропагандирующие эту практику, до сих пор можно найти в интернете, вводя в заблуждение даже хороших разработчиков.

Я рекомендую разделить вашу функцию на две части. Используйте wp_deregister_script/wp_register_script в хуке init, а для непосредственного подключения jQuery используйте хук wp_enqueue_scripts.

Это позволит вам оставаться в рамках "правильного" подхода к подключению скриптов и защитит от сотен разработчиков, которые до сих пор "делают это неправильно", заменяя jQuery на вашу объединенную версию перед добавлением в очередь.

Также стоит добавить ваш хук init с высоким приоритетом:

add_action( 'init', 'swap_out_jquery', 1 );
function swap_out_jquery() {
    // ...
}
20 июн. 2012 г. 18:38:40
Комментарии

Я хотел порекомендовать это, но затем понял, что автор вопроса фактически отменял регистрацию jQuery, а затем регистрирует совершенно другой скрипт и называет его "jquery". Я не думаю, что это хорошая практика, и считаю, что лучшим решением будет просто полностью убрать jQuery из очереди, а затем добавить пользовательский скрипт с использованием уникального идентификатора.

Chip Bennett Chip Bennett
20 июн. 2012 г. 18:51:54

Важное замечание о priority при добавлении действий. Все зависит от того, как вы понимаете приоритет. Если вы хотите, чтобы ваш код выполнялся "первым", то лучше использовать меньшее число — более высокий приоритет в порядке выполнения очереди. Но если вы хотите, чтобы эффект от вашей функции имел приоритет над другими, вам нужно, чтобы она выполнялась позже — то есть более высокий приоритет по "эффекту". В данном случае, вероятно, вам нужно большее число. Хотя, как отмечает предыдущий комментатор, в замене официальной версии jQuery мало смысла.

Paul G. Paul G.
8 июн. 2019 г. 12:10:18
2

Здесь есть несколько взаимосвязанных проблем.

  1. Правильный хук для подключения скриптов — wp_enqueue_scripts
  2. Чтобы выводить скрипты в подвале через wp_enqueue_script(), установите параметр $footer в true
  3. Ваши вызовы add_action( $hook, $callback ) не должны быть обёрнуты во что-либо; они должны выполняться напрямую из functions.php
  4. Проверки условия is_admin() следует размещать внутри вашего коллбэка
  5. Не следует отменять регистрацию скриптов, входящих в ядро WordPress, из темы, по любой причине. Даже если ваша цель — объединение скриптов, это территория плагинов.
  6. Если вам необходимо отменить регистрацию jQuery, то хук wp_enqueue_scripts уже слишком поздно. Разделите ваш код отмены регистрации/регистрации на коллбэк, подключённый к хуку init.
  7. Название какого-либо другого скрипта "jquery" — также не лучшая практика. Лучшим решением будет просто удалить jQuery из очереди, а затем загрузить ваш собственный скрипт.
  8. Убедитесь, что установили низкий приоритет для вашего коллбэка, чтобы переопределить плагины
  9. Используйте get_template_directory() вместо TEMPLATEPATH

Объединяя всё вместе:

<?php
function wpse55924_enqueue_scripts() {
    if ( ! is_admin() ) {

        // Удалить jQuery из очереди
        wp_dequeue_script( 'jquery' );

        // Зарегистрировать/добавить в очередь пользовательский скрипт, включающий jQuery
        wp_register_script( 'mythemescripts', get_template_directory_uri() . '/scripts.mythemescripts.js', false, false, true );
        wp_enqueue_script( 'mythemescripts' ); 
    }
}
add_action( 'wp_enqueue_scripts', 'wpse55924_enqueue_scripts', 99 );

Но снова: это не самый лучший подход. Лучшим решением будет просто удалить вызовы add_action() в плагинах, которые отменяют регистрацию jQuery из ядра — или использовать плагины, которые не делают чего-то столь безответственного, как замена встроенного в ядро jQuery.

20 июн. 2012 г. 18:50:09
Комментарии

OP объединяет версию jQuery, поставляемую с WordPress, с другими скриптами программно, чтобы его тема делала только один HTTP-запрос для загрузки всех JS-файлов. Таким образом, пользовательские скрипты действительно содержат jQuery и не сломают ничего при такой загрузке. Переопределение зарегистрированного обработчика 'jquery' необходимо, чтобы предотвратить двойную загрузку jQuery — один раз в объединённом JS-файле и ещё раз плагинами, которые пытаются загрузить jQuery самостоятельно.

EAMann EAMann
20 июн. 2012 г. 18:59:14

Семантически и практически _doing_it_wrong() называть что-то, что не является чистым jQuery, "jQuery". Также: сам jQuery можно просто удалить из очереди, чтобы гарантировать, что он не загрузится дважды. Вызов wp_dequeue_script() просто должен происходить с достаточным приоритетом, чтобы гарантировать, что никто не поставит его в очередь после этого.

Chip Bennett Chip Bennett
20 июн. 2012 г. 19:09:21
0

Этот ответ не совсем по вашему вопросу, но в вашем коде есть ещё одна проблема.

Вам никогда не нужно и не следует использовать:

wp_enqueue_script('jquery');

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

Пример:

wp_enqueue_script( 'myjslib-handle', get_stylesheet_directory_uri() . '/js/myfile.js', array('jquery'), '1.0.0', true );

array('jquery') в приведённом выше коде - это параметр, который указывает на необходимость загрузки jQuery в качестве зависимости.

22 окт. 2021 г. 17:52:54