Как подключить основной jQuery в футере?

30 дек. 2014 г., 21:44:44
Просмотры: 64.1K
Голосов: 33

У меня в файле functions.php есть следующий код, но я не могу добиться загрузки jQuery в футере. Файл includes загружается в футере нормально. Что еще нужно сделать?

function starter_scripts() {
    wp_enqueue_style( 'starter-style', get_stylesheet_uri() );

    wp_enqueue_script( 'jquery', '', '', '', true );

    wp_enqueue_script( 'includes', get_template_directory_uri() . '/js/min/includes.min.js', '', '', true );
}
add_action( 'wp_enqueue_scripts', 'starter_scripts' );
2
Комментарии

Если вы делаете это по соображениям производительности, можно рассмотреть добавление атрибута defer к тегам скриптов: https://matthewhorne.me/defer-async-wordpress-scripts/

diachedelic diachedelic
25 авг. 2017 г. 07:06:09

Разработчик WP здесь, я создал плагин для решения этой проблемы: https://wordpress.org/plugins/jquery-manager/

Remzi Cavdar Remzi Cavdar
4 июл. 2019 г. 12:55:20
Все ответы на вопрос 6
16
61

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

/**
 * Перемещение jQuery в подвал (футер) страницы.
 */
function wpse_173601_enqueue_scripts() {
    wp_scripts()->add_data( 'jquery', 'group', 1 );
    wp_scripts()->add_data( 'jquery-core', 'group', 1 );
    wp_scripts()->add_data( 'jquery-migrate', 'group', 1 );
}
add_action( 'wp_enqueue_scripts', 'wpse_173601_enqueue_scripts' );

Это решение имитирует поведение ядра WordPress, устанавливая параметр group в значение 1, что определяет, должен ли скрипт загружаться в подвале страницы (как отметил @jgraup в комментариях, выбор значения 1 кажется несколько произвольным, точная логика этого выбора неизвестна).

7 мая 2016 г. 17:11:29
Комментарии

Интересно. Похоже, что wp_register_script использует add_data( $handle, 'group', 1 ) для перемещения скриптов в футер. https://core.trac.wordpress.org/browser/tags/4.5/src/wp-includes/functions.wp-scripts.php#L117 - Не могли бы вы подробнее рассказать, почему это так? На первый взгляд, параметр 'group' кажется несколько произвольным. Но в коде видно, как он используется в WP_Scripts->do_item дальше, согласно https://core.trac.wordpress.org/browser/tags/4.5/src/wp-includes/class.wp-scripts.php#L231. В любом случае, это кажется наименее разрушительным решением.

jgraup jgraup
7 мая 2016 г. 21:37:30

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

ssaltman ssaltman
18 мая 2016 г. 16:32:12

Лучший ответ! Примечание: работает начиная с WordPress 4.2.0, используйте его в functions.php в хуке 'wp_enqueue_scripts'.

realmag777 realmag777
1 июл. 2016 г. 21:22:28

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

iSaumya iSaumya
31 авг. 2016 г. 15:13:44

@iSaumya Возможно, вам стоит добавить некоторые детали о том, почему это не сработало / что произошло. Это довольно загадочный запрос! Также ознакомьтесь с другим новым ответом и учтите, что этот ответ всё ещё нужно обернуть в функцию и вызов фильтра.

Tim Malone Tim Malone
21 окт. 2016 г. 01:08:19

@tim Я попробовал это, но скрипт по-прежнему не перемещается в футер. Вот что произошло.

iSaumya iSaumya
21 окт. 2016 г. 01:10:36

@iSaumya Я добавил для вас дополнительные детали, надеюсь, это поможет!

Matthew Boynes Matthew Boynes
22 окт. 2016 г. 02:41:27

WordPress использует настолько старую версию jQuery, что на данном этапе лучше отменить регистрацию и зарегистрировать новейшую версию.

tehlivi tehlivi
16 янв. 2018 г. 21:27:33

Это просто отлично! Большое спасибо. Однако, стоит отметить, как указывает @tehlivi — WordPress использует старую версию jQuery — подумайте об отмене регистрации и регистрации более новой версии.

skolind skolind
8 мар. 2018 г. 11:24:00

Этот код возвращает мне ошибку 500. У меня WordPress 4.9.9

Marco Panichi Marco Panichi
8 янв. 2019 г. 11:18:04

@MarcoPanichi возможно, у вас конфликтующая тема или плагин? Попробуйте проверить на чистой установке WordPress без плагинов, используя стандартную тему?

Matthew Boynes Matthew Boynes
8 янв. 2019 г. 16:32:38

@MatthewBoynes Думаю, вы правы. На другой установке всё работает.

Marco Panichi Marco Panichi
9 янв. 2019 г. 14:36:31

@MatthewBoynes Я всё ещё ищу больше разработчиков, которые хотели бы помочь поддерживать проект с открытым исходным кодом, см.: https://wordpress.org/plugins/jquery-manager/ и https://github.com/Remzi1993/jquery-manager Этот плагин/проект должен помочь пользователям использовать последнюю версию jQuery простым кликом.

Remzi Cavdar Remzi Cavdar
4 июл. 2019 г. 12:57:46

Это работает, но 1 — это "магическое число". Если оно изменится, этот код сломается. И, к сожалению, мы не знаем, что оно означает, поэтому не можем заменить его константой. Кто-нибудь на самом деле знает, на что оно ссылается?

lonix lonix
8 дек. 2019 г. 08:16:22

Параметр 1 отвечает на вопрос "Должны ли мы переместить скрипт в футер?" в функции — я думаю, он означает "true".

Simo Patrek Simo Patrek
16 янв. 2020 г. 23:33:53

работает отлично в wordpress 5.6, спасибо, мужик :)

sorrow poetry sorrow poetry
22 февр. 2021 г. 17:48:30
Показать остальные 11 комментариев
8
29

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

function starter_scripts() {
    wp_deregister_script( 'jquery' );
    wp_register_script( 'jquery', includes_url( '/js/jquery/jquery.js' ), false, NULL, true );
    wp_enqueue_script( 'jquery' );

    wp_enqueue_style( 'starter-style', get_stylesheet_uri() );
    wp_enqueue_script( 'includes', get_template_directory_uri() . '/js/min/includes.min.js', '', '', true );
}
add_action( 'wp_enqueue_scripts', 'starter_scripts' );

Если вы используете версию jQuery, размещенную на Google CDN, дайте мне знать - я изменю этот код для URL Google CDN.

30 дек. 2014 г. 22:23:44
Комментарии

Я попробовал это, но скрипт всё ещё в подвале, есть идеи почему?

Toni Michel Caubet Toni Michel Caubet
3 сент. 2015 г. 13:05:06

Что ты имеешь в виду? Решение как раз про перемещение jQuery в подвал.

Robert hue Robert hue
3 сент. 2015 г. 13:58:17

Возможно, также стоит проверить is_admin(), чтобы избежать изменений в jQuery бэкенда - в конце концов, нам нужно оптимизировать только фронтенд наших сайтов :)

Tim Malone Tim Malone
21 окт. 2016 г. 01:10:07

@TimMalone - на самом деле, нет - wp_enqueue_scripts используется только для фронтенда, тогда как admin_enqueue_scripts предназначен для бэкенда

dev_masta dev_masta
4 мар. 2017 г. 19:18:55

Иногда это не работает, потому что плагин добавляет свой скрипт с параметром "in_footer" равным false. Это приводит к перемещению jquery-скрипта в head.

Pons Pons
8 мар. 2017 г. 15:42:49

Я считаю, что это решение на самом деле ужасно. Удаляются ли теги версий этим способом? Что это за starter-style и что это за includes.min.js, и какое отношение это имеет к jQuery.

NextGenThemes NextGenThemes
31 июл. 2017 г. 12:09:46

@redanimalwar starter-style и включаемые файлы взяты непосредственно из вопроса.

tehlivi tehlivi
16 янв. 2018 г. 20:43:14

@Roberthue Я всё ещё ищу больше разработчиков, которые хотели бы помочь в поддержке open source проекта, см.: https://wordpress.org/plugins/jquery-manager/ и https://github.com/Remzi1993/jquery-manager этот плагин / проект должен помочь пользователям использовать последнюю версию jQuery простым кликом.

Remzi Cavdar Remzi Cavdar
4 июл. 2019 г. 12:56:32
Показать остальные 3 комментариев
7
25

Лучшее решение:

add_action( 'wp_default_scripts', 'move_jquery_into_footer' );

function move_jquery_into_footer( $wp_scripts ) {

    if( is_admin() ) {
        return;
    }

    $wp_scripts->add_data( 'jquery', 'group', 1 );
    $wp_scripts->add_data( 'jquery-core', 'group', 1 );
    $wp_scripts->add_data( 'jquery-migrate', 'group', 1 );
}

Почему это решение лучше принятого ответа (по моему мнению)

  1. Изменения происходят на самом глубоком уровне, а не на позднем этапе, когда другие процессы могли уже повлиять на скрипты.
  2. Строка версии сохраняется и не удаляется!
  3. Вместо удаления и повторной регистрации скрипта просто устанавливается значение группы, что по сути эквивалентно регистрации скрипта с параметром $footer = true.

О том, почему не стоит делать это для админки

Если плагины добавляют inline jQuery в wp_head, это вызовет ошибку, когда jQuery не загружен в этот момент. Я рекомендую избегать этого, пока у вас не будут миллионы правок на сайте и вы не начнёте оптимизировать производительность админки. Это актуально и для фронтенда — следите за плохо написанными темами или плагинами, которые предполагают загрузку jQuery в head через inline-код. WP и плагины регистрируют другие скрипты в админке с jQuery в зависимостях, так что это всё равно не сработает.

Если решение не работает

Важно понимать: если любой другой скрипт загружается в head и зависит от jQuery, это приведёт к загрузке jQuery в head прямо перед ним. Это нормально и ожидаемо — так работает система wp_enqueue. Это означает, что при использовании нескольких плагинов вы быстро узнаете, если один из них потребует jQuery в head. К сожалению, это поведение по умолчанию для подключаемых скриптов.

Радикальное решение

Думаю, это сломает любой inline JS, который полагается на jQuery, но такое встречается редко. Этот код принудительно переместит все скрипты в футер, независимо от того, как они были подключены.

add_action( 'wp_enqueue_scripts', 'js_to_footer' );

function js_to_footer() {
  remove_action( 'wp_head', 'wp_print_scripts' );
  remove_action( 'wp_head', 'wp_print_head_scripts', 9 );
  remove_action( 'wp_head', 'wp_enqueue_scripts', 1 );
}
26 сент. 2016 г. 23:50:35
Комментарии

Хотя этот ответ отвечает на вопрос и содержит несколько полезных моментов для размышления, в нём слишком много лишнего (воды?) и он очень похож на ранее опубликованные ответы с незначительными улучшениями кода. Ответ был бы воспринят лучше, если бы его отредактировали и сократили до более информативной версии. Также нет реальной необходимости указывать конкретных пользователей или ответы (так как они могут по каким-то причинам исчезнуть в будущем).

Howdy_McGee Howdy_McGee
21 окт. 2016 г. 23:38:00

Вы называете совершенно не упомянутые и, вероятно, лучшие, чем что-либо указанное в других ответах, "незначительными улучшениями кода". Это просто неправда. Кроме того, я никого не "вызывал", я просто упомянул факты, которые знаю, чтобы улучшить стиль кодирования и обучить читателей, чтобы они писали лучший код. Серьёзно, я потратил немало времени, чтобы написать лучший на данный момент ответ, и вот что я получаю за это.

NextGenThemes NextGenThemes
21 окт. 2016 г. 23:58:46

Другие ответы вообще не упоминают о том, что сторонние скрипты могут загружать jQuery в head, в то время как мой ответ развеивает непонимание у людей, которые не знают, почему это не работает. Ни один из других ответов не упоминает о потенциальных рисках...

NextGenThemes NextGenThemes
22 окт. 2016 г. 00:03:02

Этот код (как и код в ответе выше) возвращает мне ошибку 500. У меня WordPress 4.9.9

Marco Panichi Marco Panichi
8 янв. 2019 г. 11:19:46

Сложно поверить, что этот код вызывает 500 ошибку, скорее всего вы допустили ошибку при реализации этого в своем коде. Это не совсем правильное место для такого вопроса, и ваша устаревшая версия WP — это слишком мало информации.

NextGenThemes NextGenThemes
9 янв. 2019 г. 20:19:59

@NextGenThemes Я всё ещё ищу разработчиков, которые хотели бы помочь в поддержке open source проекта, см.: https://wordpress.org/plugins/jquery-manager/ и https://github.com/Remzi1993/jquery-manager этот плагин / проект должен помочь пользователям использовать последнюю версию jQuery простым кликом.

Remzi Cavdar Remzi Cavdar
4 июл. 2019 г. 12:57:28

Привет, чувак, отличное радикальное решение, как раз то, что я искал. Возможно, твой ответ в чем-то похож на предыдущий, но он понятнее. Спасибо!

Andres Felipe Andres Felipe
10 дек. 2020 г. 17:01:35
Показать остальные 2 комментариев
1

Я разработал плагин для решения этой конкретной проблемы. Этот плагин не вмешивается в jQuery WordPress, так как загружается только во фронтенде. Смотрите: jQuery Manager for WordPress

Зачем еще один инструмент для обновления / управления / разработки / отладки jQuery?

Потому что ни один из существующих инструментов не позволяет выбрать конкретную версию jQuery и/или jQuery Migrate, предоставляя как сжатую (production), так и несжатую (development) версии. Смотрите возможности ниже!

✅ Выполняется только во фронтенде, не влияет на админку WordPress и кастомайзер (для совместимости). Смотрите: https://core.trac.wordpress.org/ticket/45130 и https://core.trac.wordpress.org/ticket/37110

Включает/выключает jQuery и/или jQuery Migrate

✅ Активирует конкретную версию jQuery и/или jQuery Migrate

И многое другое! Код открыт, так что вы можете изучать его, учиться и вносить свой вклад.


Почти все используют неверный хэндл

WordPress на самом деле использует хэндл jquery-core, а не jquery:

https://github.com/WordPress/WordPress/blob/f84ab5e19f0038a3abec71821c9b8f47a4272942/wp-includes/script-loader.php#L1017

// jQuery
$scripts->add( 'jquery', false, array( 'jquery-core', 'jquery-migrate' ), '1.12.4-wp' );
$scripts->add( 'jquery-core', '/wp-includes/js/jquery/jquery.js', array(), '1.12.4-wp' );
$scripts->add( 'jquery-migrate', "/wp-includes/js/jquery/jquery-migrate$suffix.js", array(), '1.4.1' );

Хэндл jquery — это просто алиас для загрузки jquery-core вместе с jquery-migrate

Подробнее об алиасах: wp_register_script multiple identifiers?

Правильный способ сделать это

В моем примере ниже я использую официальный CDN jQuery на https://code.jquery.com. Также я применяю script_loader_tag, чтобы добавить атрибуты CDN.
Вы можете использовать следующий код:

// Фронтенд — не выполняется в админке и кастомайзере WordPress (для совместимости)
// Смотрите: https://core.trac.wordpress.org/ticket/45130 и https://core.trac.wordpress.org/ticket/37110
function wp_jquery_manager_plugin_front_end_scripts() {
    $wp_admin = is_admin();
    $wp_customizer = is_customize_preview();

    // jQuery
    if ( $wp_admin || $wp_customizer ) {
        // echo 'Мы в админке WordPress или в кастомайзере';
        return;
    }
    else {
        // Удаляем стандартный jQuery WordPress (см. https://github.com/Remzi1993/wp-jquery-manager/issues/2 и https://github.com/WordPress/WordPress/blob/91da29d9afaa664eb84e1261ebb916b18a362aa9/wp-includes/script-loader.php#L226)
        wp_deregister_script( 'jquery' ); // хэндл jquery — это алиас для загрузки jquery-core и jquery-migrate
        // Удаляем стандартный jQuery WordPress
        wp_deregister_script( 'jquery-core' );
        // Удаляем стандартный jQuery Migrate WordPress
        wp_deregister_script( 'jquery-migrate' );

        // Регистрируем jQuery в head
        wp_register_script( 'jquery-core', 'https://code.jquery.com/jquery-3.3.1.min.js', array(), null, false );

        /**
         * Регистрируем jquery с зависимостью от jquery-core, чтобы другие скрипты могли использовать хэндл jquery
         * см. https://wordpress.stackexchange.com/questions/283828/wp-register-script-multiple-identifiers
         * Сначала регистрируем скрипт, а затем подключаем его. Почему? Смотрите:
         * https://wordpress.stackexchange.com/questions/82490/when-should-i-use-wp-register-script-with-wp-enqueue-script-vs-just-wp-enque
         * https://stackoverflow.com/questions/39653993/what-is-diffrence-between-wp-enqueue-script-and-wp-register-script
         */
        wp_register_script( 'jquery', false, array( 'jquery-core' ), null, false );
        wp_enqueue_script( 'jquery' );
    }
}
add_action( 'wp_enqueue_scripts', 'wp_jquery_manager_plugin_front_end_scripts' );


function add_jquery_attributes( $tag, $handle ) {
    if ( 'jquery-core' === $handle ) {
        return str_replace( "type='text/javascript'", "type='text/javascript' integrity='sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=' crossorigin='anonymous'", $tag );
    }
    return $tag;
}
add_filter( 'script_loader_tag', 'add_jquery_attributes', 10, 2 );
4 июл. 2019 г. 13:06:13
Комментарии

Это помещает jQuery в head (как указано в вашем собственном inline-комментарии) и не является ответом на вопрос OP.

Pim Schaaf Pim Schaaf
30 янв. 2020 г. 19:58:28
0
add_action("wp_enqueue_scripts", "myscripts");

function myscripts() { 
   wp_enqueue_script( 'jquery' , '', array(), true); // true - загрузка в футере
   wp_enqueue_script( 'someScript-js', 'https://domain.com/someScript.js' , '', '', true );
}
18 мая 2019 г. 00:10:41
4
-3

Попробуйте изменить ваш код следующим образом:

function starter_scripts() {
        wp_enqueue_style( 'starter-style', get_stylesheet_uri() );
        wp_enqueue_script('jquery');
        wp_enqueue_script( 'includes', get_template_directory_uri() . '/js/min/includes.min.js', array( 'jquery' ) );
    }
    add_action( 'wp_enqueue_scripts', 'starter_scripts' );

Думаю, это должно работать правильно

Добавьте эти строки в ваш файл functions.php

remove_action('wp_head', 'wp_enqueue_scripts', 1);
add_action('wp_footer', 'wp_enqueue_scripts', 5);

Это перенесет подключение скриптов в подвал сайта (footer)

30 дек. 2014 г. 22:05:33
Комментарии

Это помещает jQuery в head. Мне нужно, чтобы он был в подвале сайта (футере).

Desi Desi
30 дек. 2014 г. 22:06:09

Привет, Деси, пожалуйста, проверь отредактированный ответ, думаю, он тебе поможет

Amit Mishra Amit Mishra
30 дек. 2014 г. 22:13:17

Я почти уверен, что это ужасная идея — ты фактически предотвратил загрузку любых скриптов в заголовке, а не только jQuery, и, возможно, дублируешь их подключение (не вдавался в подробности). На самом деле, если уж делать таким способом, тебе, вероятно, нужна только часть с remove_action / add_action.

drzaus drzaus
26 янв. 2016 г. 22:34:21

Действительно ужасная идея, не делайте так!

NextGenThemes NextGenThemes
26 сент. 2016 г. 23:50:23