Загрузка и выгрузка скриптов в WordPress -- wp_deregister_script('jquery')
У меня есть несколько вопросов, связанных с загрузкой и выгрузкой 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. Я протестировал ее, но не заметил никакого эффекта на своем сайте, поэтому убрал для улучшения скорости загрузки. Вопрос: Это плохая идея?
Ссылки:
В 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 — это тот, который будет выведен. Именно для этого и предназначена система приоритетов в действиях/фильтрах.
Теперь мне стало понятнее... Два замечания: 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
Хочу добавить, прежде всего, спасибо за комплимент, приятно.
Вы используете дочернюю тему, в которой родительская тема должна была подключить библиотеку jQuery, встроенную в WordPress. Как я уже говорил в посте, на который вы ссылаетесь, это плохая практика (подчеркиваю), если родительская тема по умолчанию не подключает jQuery.
У вас есть несколько проблем с кодом. Во-первых, никогда не отключайте стандартную библиотеку jQuery — это может что-то сломать в будущем. Правильный способ — убрать скрипт из очереди с помощью wp_dequeue_scripts.
Но вопрос: зачем вам убирать jQuery из очереди и снова добавлять? Обычно это делают авторы плагинов, чтобы гарантировать, что jQuery не загрузится дважды, потому что плагины работают со всеми темами, и невозможно заранее знать, загружает ли тема jQuery. Но ваша дочерняя тема работает только с конкретной родительской темой, поэтому вы точно знаете, загружается ли jQuery в родительской теме. Так что в вашем случае это не нужно.
Во-вторых, обратите внимание на приоритеты. У add_action есть 4 параметра, третий из которых — приоритет ($priority). Обычно плагины и дочерние темы загружают свои скрипты после родительской темы, чтобы их не переопределили. Поэтому хорошей практикой будет запускать ваш action самым последним. Для этого нужно указать очень низкий приоритет (то есть очень большое число).
add_action( 'wp_enqueue_scripts', 'jquery_loadup', 999 );