Force wp_enqueue_scripts to the HEADER?

A plugin I’m working on requires jquery to be loaded before the content is processed. Some stock themes, like 2010, 2011 and 2012 (I believe) put the JS in the footer.

How can I force the scripts to be loaded in the header (I will notify users of the plugin that the plugin requires this)?

Related posts

Leave a Reply

5 comments

  1. The normal behavior of wp_enqueue_script is to put the script output into the head section, the parameter $in_footer is optional and defaults to false. So, you can load jQuery with your plugin into the head and, assumed your dealing with well programmed themes/plugins, it won’t load again, because wp_enqueue_script prevents this by default – additional information about that here.

  2. The third parameter of wp_enqueue_script() allows you declare dependencies for the script you’re enqueueing, i.e. what other scripts are required for them to run.

    add_action( 'wp_enqueue_scripts', 'include_script_that_depends_on_jquery' );
    
    function include_script_that_depends_on_jquery() {
        wp_enqueue_script( 'my_script.js', '/path/to/my_scripts.js', array( 'jquery' ) );
    }
    

    That way, no matter where any theme, plugin, whatever loads jquery, your script will always load later, assuming they follow best practices as well and don’t deregister it.

  3. For example, if I wanted a simple
    jQuery(“body”).css(“background-color”,”red”); executed from within a
    shortcode in the body, I can’t do it. Let’s say my shortcode is [body
    color=red] but jquery isn’t loaded till the footer, then my code won’t
    work.

    In your shortcode handler You could return an HTML placeholder element or JavaScript variable, and then hook onto wp_footer with another function that “runs” jQuery.

    function wpse_139154_shortcode( $atts ) {
        // Awesome code
    
        wp_enqueue_script( 'jquery' ); // Will output in the footer if not already in the head
        add_action( 'wp_footer', 'wpse_139154_shortcode_script', 100 ); // Ensure we run after wp_print_footer_scripts
    
        return <<<html
    <script>
        var arguments = arguments || {}; arguments.backgroundColor = "{$atts['color']}";
    </script>
    html;
    }
    
    function wpse_139154_shortcode_script() {
        echo <<<html
    <script>jQuery( "body" ).css( arguments );</script>
    html;
    }
    
  4. Accoriding to the WP Reference for wp_enqueue_scripts

    wp_enqueue_script( string $handle, string $src = false, array $deps = array(), string|bool|null $ver = false, bool $in_footer = false )
    

    The last parameter is responsible for where the script will be loaded.
    There are some snags which can change his behaviour !
    Try to find and comment/remove this lines from your function.php file

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

    The purpose of this six actions is to automatically move JavaScript code to page footer making the last parameter from wp_enqueue_scripts unuseful!
    If this actions can not be removed, then you can change the priorities of them. From 5 to 9999 per example. Play with the priorities to find the right one for you.

    You also need to check if the are some dependencies specified in the $deps array.Witch gone force the script to be loaded after resolving them.

    Don’t try any dirty hacks, it is a bad practice

    Happy coding

  5. First, dequeue the jQuery enqueued by the theme. Then enqueue it again.

    function jquery_at_header() {
        // De-Queue current jQuery 
        wp_dequeue_script( 'jquery' );
    
        // Re Enqueue jQuery
        wp_enqueue_script( 'jquery' );
    
        //Then your script
        wp_enqueue_script( 'script-name', plugins_url( 'js/scrip-name.js' , __FILE__ ), array( 'jquery' ), '1.0' );
    }
    add_action( 'wp_enqueue_scripts', 'jquery_at_header', 5 );
    

    You might need to play with the priority to get what you need.