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?

2
  • do you really need jQuery noConflict? are you using any other libraries? Commented Sep 1, 2012 at 7:15
  • Yes. If I don't I get error TypeError: $ is not a function [Break On This Error] $(document).ready(function() { Commented Sep 1, 2012 at 7:21

6 Answers 6

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.

Sign up to request clarification or add additional context in comments.

2 Comments

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?
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 :-)
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

4 Comments

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?
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.
I think that would be like making a simple thing more complicated. There are many ifs and buts in what you suggest.
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 :)
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>

Comments

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);

Comments

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.

Comments

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.