Загрузка и выгрузка скриптов в WordPress -- wp_deregister_script('jquery')

3 июл. 2014 г., 10:20:22
Просмотры: 15.4K
Голосов: 2

У меня есть несколько вопросов, связанных с загрузкой и выгрузкой JavaScript-библиотек в WordPress. После прочтения отличного ответа Pieter Goosen на один из вопросов, я решил изучить тему и почистить код, который отвечает за загрузку библиотек в моей дочерней теме. Этот код находится в файле function.php моей дочерней темы. На сайте есть функции, использующие datepicker, а также плагины, которые точно используют jQuery.

function jquery_loadup() {
        //wp_deregister_script('jquery');    <--- ?H
        wp_enqueue_script('jquery');
        //wp_enqueue_script('jquery-migrate');
        wp_enqueue_script('jquery-ui-core');
        wp_enqueue_script('jquery-ui-datepicker');
        wp_enqueue_style('jquery-style', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css');
}
add_action('wp_enqueue_scripts','jquery_loadup');

Я предполагал, что строка wp_deregister_script('jquery') фактически сбрасывает/очищает все предыдущие "запросы" к скриптам jQuery, чтобы они не конфликтовали между собой. Эта строка, за которой следует wp_enqueue_script('jquery');, должна привести к чистой загрузке jQuery через систему регистрации скриптов WordPress, верно? Я думал, что вызов deregister проверяет наличие предыдущих загрузок jQuery и, если находит одну или несколько, останавливает их загрузку, а если ничего не найдено - просто пропускает.

Однако, когда я использую wp_deregister_script('jquery'), на сайте появляется ошибка "ReferenceError: jQuery is not defined". При этом все мои JavaScript-функции перестают работать. Что происходит? Если закомментировать эту строку, сайт работает нормально.

Вопросы: В чем моя ошибка? Что я не понимаю в работе функции deregister? Почему появляется это сообщение об ошибке?

Примечание: строка с jquery-migrate предназначена для совместимости с кодом, использующим старые версии jQuery. Я протестировал ее, но не заметил никакого эффекта на своем сайте, поэтому убрал для улучшения скорости загрузки. Вопрос: Это плохая идея?

Ссылки:

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

wp_deregister означает, что вы отменяете регистрацию 'jquery'. Поэтому когда вы вызываете 'jquery' с помощью wp_enqueue_script('jquery'), WordPress не может найти jquery, так как вы уже отменили его регистрацию. В результате ваше приложение, которому нужен jQuery, также перестает работать.

ucon89 ucon89
3 июл. 2014 г. 10:41:34

Что? О... теперь я понял... это абсолютно логично. Это обнуляет область действия jquery, определенную системой WordPress. Никто не хочет с этим связываться. Но подождите... как WordPress понимает, как остановить беспорядок, оставленный 8 разными плагинами, которые пытаются добавить разные версии jquery? И да, ответьте на вопрос, чтобы я мог проголосовать за вас?

zipzit zipzit
3 июл. 2014 г. 10:53:12
Все ответы на вопрос 2
2

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

  • wp_register_script Регистрирует скрипт в WordPress. Он не вызывается, а просто становится доступным для WordPress, если потребуется.
  • wp_deregister_script Делает обратное. Удаляет определения, сделанные в wp_register_script, и скрипт больше не доступен как зависимость или для добавления в очередь.

Зарегистрированные скрипты не выводят ничего в коде. Они просто программно определяют скрипт, чтобы WordPress мог учитывать зависимости и добавлять их в очередь.

  • wp_enqueue_script Фактически определяет и добавляет скрипт в очередь для вывода в заголовке или подвале HTML-страницы.
  • wp_dequeue_script Делает обратное и удаляет скрипт из очереди вывода.

Фактический вывод происходит в действиях 'wp_head' или 'wp_footer', в зависимости от деталей регистрации.

Пример:

wp_deregister_script('jquery');
wp_register_script('jquery', ("https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"), false, '1.9.1', true);

wp_enqueue_script( 'script-1', get_template_directory_uri() . '/js/example1.js', array('jquery'), '1.0.0', false );
wp_enqueue_script( 'script-2', get_template_directory_uri() . '/js/example2.js', array('jquery'), '1.0.0', true );
wp_enqueue_script( 'script-3', get_template_directory_uri() . '/js/example3.js', array('jquery'), '1.0.0', true );
wp_enqueue_script( 'script-4', get_template_directory_uri() . '/js/example4.js', array('jquery'), '1.0.0', true );
wp_enqueue_script( 'script-5', get_template_directory_uri() . '/js/example5.js', array('jquery'), '1.0.0', true );

В этом примере я отменяю регистрацию jQuery. Теперь он больше не доступен, и я получил бы ту же ошибку, что и вы, если бы не зарегистрировал его снова. (На этот раз с CDN Google в надежде ускорить загрузку страницы.)

Но начиная с третьей строки jQuery не будет выводиться. Он нигде не появится. Однако начиная с четвертой строки я вызываю несколько скриптов, у которых jQuery указан как зависимость. Первый скрипт загружается в заголовке, остальные — в подвале. Благодаря зависимостям jQuery автоматически добавляется в очередь и загружается в заголовке, так как он нужен там в первую очередь.

Таким образом, с системой скриптов WordPress, которая довольно надежна, нет необходимости управлять конфликтами или предыдущими запросами. Зарегистрированные скрипты вызываются только один раз и только тогда, когда это необходимо.

В вашем примере вы отменяете регистрацию скрипта в первой строке функции и снова вызываете его во второй. Но из-за отмены регистрации WordPress забывает все детали, такие как URL, версия, зависимости и т. д. Правильной функцией в вашей логике была бы wp_dequeue_script, но даже она не нужна. WordPress сам определяет необходимость, анализируя скрипты в очереди или их зависимости.

Редактирование:

как WordPress понимает, как остановить беспорядок, оставленный 8 разными плагинами, которые пытаются добавить разные версии jQuery?

Последний экземпляр регистрации jQuery перед действием wp_print_scripts — это тот, который будет выведен. Именно для этого и предназначена система приоритетов в действиях/фильтрах.

3 июл. 2014 г. 11:01:13
Комментарии

Теперь мне стало понятнее... Два замечания: 1) По мере дальнейшего поиска я вижу, что в ядре WordPress jquery = jquery.js & jquery-migrate.js (упс... тут же ответил на свой второй вопрос!) согласно http://codex.wordpress.org/Function_Reference/wp_register_script#Handles_and_Their_Script_Paths_Registered_by_WordPress. 2) Я всё ещё не понимаю, что происходит, когда 8 разных плагинов пытаются ЗАРЕГИСТРИРОВАТЬ и затем подключить свою версию jquery. Какая из них имеет приоритет? Это как специфичность в CSS?

zipzit zipzit
3 июл. 2014 г. 11:12:04

Приоритет имеет последний вызов register. Имейте в виду: ничего не выполняется одновременно, всё выполняется последовательно, вам просто нужно понимать порядок выполнения.

Hendrik Luehrsen Hendrik Luehrsen
3 июл. 2014 г. 11:16:30
0

Хочу добавить, прежде всего, спасибо за комплимент, приятно.

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

У вас есть несколько проблем с кодом. Во-первых, никогда не отключайте стандартную библиотеку jQuery — это может что-то сломать в будущем. Правильный способ — убрать скрипт из очереди с помощью wp_dequeue_scripts.

Но вопрос: зачем вам убирать jQuery из очереди и снова добавлять? Обычно это делают авторы плагинов, чтобы гарантировать, что jQuery не загрузится дважды, потому что плагины работают со всеми темами, и невозможно заранее знать, загружает ли тема jQuery. Но ваша дочерняя тема работает только с конкретной родительской темой, поэтому вы точно знаете, загружается ли jQuery в родительской теме. Так что в вашем случае это не нужно.

Во-вторых, обратите внимание на приоритеты. У add_action есть 4 параметра, третий из которых — приоритет ($priority). Обычно плагины и дочерние темы загружают свои скрипты после родительской темы, чтобы их не переопределили. Поэтому хорошей практикой будет запускать ваш action самым последним. Для этого нужно указать очень низкий приоритет (то есть очень большое число).

  add_action( 'wp_enqueue_scripts', 'jquery_loadup', 999 );
3 июл. 2014 г. 11:25:14