Load javascript code after jquery.js has loaded in WordPress site
Asked Answered
F

6

6

I have a custom jquery-based slider on homepage of a WordPress site. I'm loading jQuery (jquery.js) and the slider js (jquery.advanced-slider.js) using below code in my functions.php file of my theme.

function my_load_scripts() {
  if (!is_admin()) {
    wp_enqueue_script("jquery");

    if (is_home()) {
      wp_enqueue_script('theme-advanced-slider', get_template_directory_uri().'/js/jquery.advanced-slider.js', array('jquery'));
      wp_enqueue_script('theme-innerfade', get_template_directory_uri().'/js/innerfade.js', array('jquery'));
    }
  }
}

add_action('wp_enqueue_scripts', 'my_load_scripts');

Now I put the below code in my header.php file BEFORE wp_head();

<script type="text/javascript">
  var $j = jQuery.noConflict();

  $j(document).ready(function () {
    //Slider init JS
    $j(".advanced-slider").advancedSlider({
      width: 614,
      height: 297,
      delay: 1000,
      pauseRollOver: true
    });
  });
</script>

It's obvious here that my jquery.js and jquery.advanced-slider.js load after the JavaScript code above and thus my slider doesn't work. If I put it after wp_head() call in <head> the slider works.

But if I put it after wp_head() wouldn't that be a hack? I want my code to be clean. As twentyeleven theme clearly says

/* Always have wp_head() just before the closing </head>
     * tag of your theme, or you will break many plugins, which
     * generally use this hook to add elements to <head> such
     * as styles, scripts, and meta tags.
     */

I'm very confused here. I might be missing something very simple clue here. But help me out guys. What would be the best way to put the JavaScript before wp_head() and yet have it load after jquery.js and slider.js have loaded?

Fortification answered 1/9, 2012 at 7:1 Comment(2)
do you really need jQuery noConflict? are you using any other libraries?Aboral
Yes. If I don't I get error TypeError: $ is not a function [Break On This Error] $(document).ready(function() {Fortification
P
3

Add your script block to the bottom of the HTML page, just before the </body>.

Your slider init JS code won't get executed until the full DOM has been parsed in the browser anyway so there is no disadvantage to this.

In fact web performance experts like Steve Souders suggest that script blocks should be added at the end of your HTML page as script blocks block rendering and the page appears to load faster this way.

Proconsulate answered 1/9, 2012 at 7:4 Comment(2)
I did think of loading it in body but wouldn't it be good to keep all script stuff in <head> for the sake of clarity?Fortification
Given that script tags should be at the bottom of the page based on web performance best practice, and the fact it would make your code work, it would seem the obvious choice to me :-)Proconsulate
A
3

As per wordpress function reference:

The safe and recommended method of adding JavaScript to a WordPress generated page is by using wp_enqueue_script(). This function includes the script if it hasn't already been included, and safely handles dependencies.

If you want to keep your "code clean" you might rethink how your js is organised. My approach with wordpress is to (usually) keep a scripts.js for all initialisation and small scripts and separate file(s) for plugins. But everything depends how big and how many files you have - you want to avoid too many http requests and files that are hard to manage.

As well, wp_enqueue_script lets you place the scripts in the footer. http://codex.wordpress.org/Function_Reference/wp_enqueue_script

Ashcroft answered 1/9, 2012 at 7:30 Comment(4)
Say I have 3-4 initializations on my site. However, only one is initialized on homepage. Now as you can see in my code, I'm checking if it's home page and only then including my slider.js Now if I put all initializations in scripts.js as you say, wouldn't it give error (in console) on other pages because slider.js won't be included on other pages but the initialization code for slider would then be loaded on all pages?Fortification
You could just add some logic in js to see if needs to run. In your case, you could just check if the .advanced-slider is present on the page and init nothing if it's not there.Ashcroft
I think that would be like making a simple thing more complicated. There are many ifs and buts in what you suggest.Fortification
But it keeps your js / php separate and still quite obvious in my view. Always a nice thing when your code starts growing or you are returning to it after a while :)Ashcroft
M
3

Wait for loading jQuery with window.onload function, once jQuery file and other js / content loaded then window.onload function will be fire.

<script type="text/javascript">
window.onload = function(){

var $j = jQuery.noConflict();
    $j(".advanced-slider").advancedSlider({
        width:614,
        height:297,
        delay:1000,
        pauseRollOver:true
    });
}
</script>
Mercantilism answered 1/9, 2012 at 7:36 Comment(0)
M
1

The code that you are adding to the bottom of the page should be externalized to it's own file and added with the wp_enqueue_script(); function like shown below.

Note the use of the 'true' directive at the end of each call to wp_enqueue_script. That tells WordPress that you want them included at the wp_footer(); hook (instead of the wp_head(); hook) which should appear directly before the closing </body> tag - as per the performance best practices that others have mentioned.

function my_load_scripts() {

    if (is_home()) {
        wp_enqueue_script('theme-advanced-slider', get_template_directory_uri().'/js/jquery.advanced-slider.js', array('jquery'), true);
        wp_enqueue_script('theme-innerfade', get_template_directory_uri().'/js/innerfade.js', array('jquery'), true);
        wp_enqueue_script('your-custom-script', get_template_directory_uri().'/js/yourcustomscript.js', array('jquery'), true);
        
    }

}
add_action('wp_enqueue_scripts', 'my_load_scripts');

I've removed the jQuery enqueue line you had included because you shouldn't need to register the jQuery script as it's already registered by the WP core and since you have defined it as one of the dependencies it will be included for you.

Since you have wrapped it all in an is_home() conditional statement the all 3 of these files - plus jQuery - will be included in just the homepage.

Melnick answered 3/10, 2013 at 0:38 Comment(0)
S
1

An easier - but maybe not so nice - hack is to simply add a 1-millisecond timeout

setTimeout(function () {
    jQuery('#text-6').insertBefore('#header'); 
}, 1);
Solstice answered 31/10, 2017 at 10:4 Comment(0)
C
0

get_template_directory_uri() does give you the theme directory, but this is not what you want if you are using a Child Theme.

get_stylesheet_directory_uri() will give your the directory of your "current theme", so in either case, it is safest to use.

Cryptography answered 18/3, 2021 at 7:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.