As default, WordPress actions put the jQuery scripts in the header of all HTML pages however, sometimes it is necessary to move these scripts to the footer of the page but a simple movement is impossible. As jQuery script (and dependents) is defined by WordPress during the first steps of its loading, when you try to redefine later its output through wp_enqueue_script( ..., $in_footer TRUE )
or similars, you haven’t got any result.
There are some methods to make this change, some more risky, others more conservatives. Today, I’m going to show two methods very simple and quite conservative based on just one function. It’s all you need.
First method
The first method is based on changing the array var $extra[]
of some elements of the array registered[]
, that’s one of the properties of the class WP_Scripts
. In our case, we’re going to add a new element called group to the array $extra[]
that’s included in all elements of the array registered[]
. See one the example of the class WP_Scripts
class WP_Scripts $wp_scripts {
Any $property_1
Any $property_2
... // Some other properties
Array $registered {
'element_1 => Array {
string $handel
string $src
... // Some other vars
Array $extra {
Int $group
}
}
'element_2 => Array {
string $handel
string $src
...
Array $extra {
Int $group
}
}
... // etc.
'element_n => Array {
string $handel
string $src
... // no extra for this script, for example
}
}
... // Some other properties
}
For doing this, as the array registered[]
is accessible by a named key, we can use a very simple function, something like that:
<?php function send_jQuery_in_footer () { global $wp_scripts; $wp_scripts->registered['jquery']->extra['group'] = 1; $wp_scripts->registered['jquery-core']->extra['group'] = 1; $wp_scripts->registered['jquery-migrate']->extra['group'] = 1; } add_action ( 'wp_head', 'send_jQuery_in_footer', 1, 0 ); ?>
With this simple function we do actually change the behaviour of the output because all the elements related to the jQuery module are marked as in_footer, ie, group = 1
.
See that it’s not enough redefining just jQuery
script. After all, the WordPress jQuery script is just a trigger empty script for enqueueing jquery-core
and jquery-migrate
–the real scripts– so, if these two last scripts are not redefined too, then jQuery will keep in header because of this, it’s necessary to change the value for the three scripts: jQuery, jQuery-core and jQuery-migrate.
By the way, it’s always better, if you write this little function, to add a if ( ! is_admin() )
before the action because we don’t want to interfere with the WP admin interface so the final code would be like.
<?php
function send_jQuery_in_footer () {
global $wp_scripts;
$wp_scripts->registered['jquery']->extra['group'] = 1;
$wp_scripts->registered['jquery-core']->extra['group'] = 1;
$wp_scripts->registered['jquery-migrate']->extra['group'] = 1;
}
if ( ! is_admin() )
add_action ( 'wp_head', 'send_jQuery_in_footer', 1, 0 ); ?>
This is the basis of the change, to add the var group and set it up to 1, for moving each one of these scripts to the footer of the page.
Refining the function
But now, instead of dealing directly with $wp_scripts->registered[]
array –it’s always dangerous–, we’re going to use the correct way for changing the properties of any script element of this array using the method add_data()
included inside the class WP_Dependencies
. So, the final function will be this next:
<?php function send_jQuery_in_footer () { global $wp_scripts; $wp_scripts->add_data
( 'jquery', 'group', 1 ); // Instead of $wp_scripts->registered['jquery']->extra['group'] = 1; ...etc } if ( ! is_admin() ) add_action ( 'wp_head', 'send_jQuery_in_footer',1
, 0 ); // Take a look to priority ?>
Just one more litle thing, don’t forget to fix the execution priority to 1
for the function send_jQuery_in_footer
inside the WP action wp_head
otherwise, the function will arrives late and the output of the jQuery scripts will have been already done inside HTML head.
Remember, the default WP priority 10 doesn’t work; it has to be 1
.
Second method
This second method is, perhaps, less conservative because it avoids the loading of the WordPress original jQuery script, in fact, two files (jQuery-core and jQuery-migrate) and loads the public version jQuery file hosted by Google. In most of cases, it’s actually the same but, sometimes there is a little variation related with the version of jQuery and, of course, jQuery-migrate is not loaded. In any case, it’s also a good method and also puts the jQuery on the footer.
In this method, first we completely deregister the WordPress original jQuery script, and then we register and enqueue a new version of the jQuery. The second method is also just one function.
<?php function reassign_jQuery() { wp_deregister_script( 'jquery' ); wp_deregister_script( 'jquery-core' ); // do not forget this wp_deregister_script( 'jquery-migrate' ); // do not forget this wp_register_script('jquery', 'https://ajax.googleapis.com/ajax/libs/jquery/1.12.4
/jquery.min.js', array(),'1.12.4'
, TRUE ); wp_enqueue_script('jquery'); } // Now you can load all of your jQuery dependent scripts, probably you'll prefer to add a priority actions checking if ( ! is_admin() ) add_action('init', 'reassign_jQuery'); ?>
Although this method is the most widespread and famous –you can easily find a lot of similar examples on the web–, I’ve preferred to talk about it in second place for two reasons that I personally consider relevant:
- As there is not an URL hosted by Google that effectively always points to the latest version of jQuery, in time, we’ll have to check (and sometimes to correct) the number of the latest jQuery file.
- Additionally, perhaps the time load of your theme increases on the opinion of speed test engines because they see that your theme need one more additional external resource.
Perhaps, you think that to include the version number inside the code is not a problem… And probably it’s right if you don’t have 50 WordPress client installations working with several themes… So, I advice you to think a little about your current installations before to choose this second method. It works but it can to need a lot of maintenance.
A final thought
Before doing this change (with any of these two method), please, firstly check the behaviour and structure of the rest of the installed scripts by your theme because, if one of them works thanks to –for example– little inserted script code in the HTML tags (div, spans, etc, ) then the change of jQuery position will not be possible, or you must also change the behaviour of the rest of dependent scripts.
Always it’s complicated to move jQuery from to top to bottom, but it’s not impossible. If you have got time load issues for example, you probably ought to do it but, this movement is very structural because the behaviour of all web page components is affected so, you just need to do the changes step by step, and also check each one of these changes individually. If you work slowly, you get it.
Have a nice WordPressing!
Hi, you have a mistype in the line
add_action ( ‘wp_head’, ‘send_jQuery_in_footer’ ), 1 , 0 );
one extra bracket.
Hi, Andre.
Your observation is correct. There was an additional innecesary and wrong “)” after ‘send_jQuery_in_footer’.
Now, It’s correct.
Thanks a lot.
Joan Miquel
Hi!
You have a wrong ) in the line:
add_action ( 'wp_head', 'send_jQuery_in_footer' ), 1, 0 );
Hi, Franco.
Your observation is correct. There was an additional innecesary and wrong “)” after ‘send_jQuery_in_footer’.
Now, It’s correct.
Thanks a lot.
Joan Miquel
Thanks Joan, very handy explanation.