0

I'm just familiarising myself with Wordpress and enqueuing scripts so I'd appreciate some help with this. I'll try and give as much detail as possible.

It's worth nothing that all this scripts and how they're loaded work fine in my html templates but now they're in Wordpress they don't seem to load/I get console errors which aren't there in the static templates.

In my static templates I load the following files:

<script src="js/jquery-1.12.0.min.js"></script>
<script src="js/responsive-nav.js"></script>
<script src="js/jquery.uniform.min.js"></script>
<script src="js/main.js"></script>

In main.js I load the 2 scripts that preceed it with the following:

/**
 * RESPONSIVE-NAV.JS (plug-in)
 */ 

$(function(){

    var navigation = responsiveNav(".site-nav__list", {
        customToggle: "#site-nav__toggle",
        open: function(){
            $("#site-nav__toggle").addClass('open');
        },
        close: function(){
            $("#site-nav__toggle").removeClass('open');
        }
    });
});

/**
 * UNIFORM.JS (plug-in)
 */ 

$("select, input[type='file'], input[type='checkbox'], input[type='radio']").uniform({selectAutoWidth: false, fileButtonClass: 'btn'});

The scripts don't load and I get these console errors:

Uncaught TypeError: $ is not a function
    at main.js?ver=4.6.4:10
(anonymous) @ main.js?ver=4.6.4:10

(index):46 Uncaught ReferenceError: conditionizr is not defined
    at (index):46

And my scripts are queued like this:

add_action( 'wp_enqueue_scripts', 'my_theme_enqueue_styles', 100 );
function my_theme_enqueue_styles() {

    // Dequeue files
    wp_dequeue_style( 'normalize');
    wp_dequeue_style( 'html5blank');

    // Equeue files
    wp_enqueue_style( 'main-css', get_stylesheet_directory_uri() . '/css/main.css' );

    wp_enqueue_style( 'google-fonts', 'https://fonts.googleapis.com/css?family=Montserrat:400,700|Open+Sans:300,300i,400,400i,600,600i,700,700i');
}

add_action( 'wp_enqueue_scripts', 'my_theme_enqueue_scripts', 100 );
function my_theme_enqueue_scripts() {

    // Dequeue files
    wp_deregister_script( 'conditionizr');
    wp_deregister_script( 'modernizr');
    wp_deregister_script( 'html5blankscripts');

    // Register/equeue files
    wp_register_script('responsive-nav', get_stylesheet_directory_uri() . '/js/responsive-nav.js', array('jquery'));
    wp_enqueue_script('responsive-nav'); // Enqueue it!

    wp_register_script('uniform-js', get_stylesheet_directory_uri() . '/js/jquery.uniform.min.js', array('jquery'));
    wp_enqueue_script('uniform-js');

    wp_register_script('main-js', get_stylesheet_directory_uri() . '/js/main.js', array('jquery'));
    wp_enqueue_script('main-js');
}

If I remove the wp_deregister_script( 'conditionizr'); that seems to get rid of one of the errors but it's not a script I need - I'm using a child-theme so I just wanted to strip any of the parent themes css/scripts from the markup and use my own.

Hope someone can help with this!

If it helps, here's the parent themes enqueued styles also:

// Load HTML5 Blank scripts (header.php)
function html5blank_header_scripts()
{
    if ($GLOBALS['pagenow'] != 'wp-login.php' && !is_admin()) {

        wp_register_script('conditionizr', get_template_directory_uri() . '/js/lib/conditionizr-4.3.0.min.js', array(), '4.3.0'); // Conditionizr
        wp_enqueue_script('conditionizr'); // Enqueue it!

        wp_register_script('modernizr', get_template_directory_uri() . '/js/lib/modernizr-2.7.1.min.js', array(), '2.7.1'); // Modernizr
        wp_enqueue_script('modernizr'); // Enqueue it!

        wp_register_script('html5blankscripts', get_template_directory_uri() . '/js/scripts.js', array('jquery'), '1.0.0'); // Custom scripts
        wp_enqueue_script('html5blankscripts'); // Enqueue it!
    }
}

// Load HTML5 Blank conditional scripts
function html5blank_conditional_scripts()
{
    if (is_page('pagenamehere')) {
        wp_register_script('scriptname', get_template_directory_uri() . '/js/scriptname.js', array('jquery'), '1.0.0'); // Conditional script(s)
        wp_enqueue_script('scriptname'); // Enqueue it!
    }
}

// Load HTML5 Blank styles
function html5blank_styles()
{
    wp_register_style('normalize', get_template_directory_uri() . '/normalize.css', array(), '1.0', 'all');
    wp_enqueue_style('normalize'); // Enqueue it!

    wp_register_style('html5blank', get_template_directory_uri() . '/style.css', array(), '1.0', 'all');
    wp_enqueue_style('html5blank'); // Enqueue it!
}
miken32
  • 42,008
  • 16
  • 111
  • 154
user1406440
  • 1,329
  • 2
  • 24
  • 59
  • `conditionizr is not defined` seems pretty straightforward. – miken32 Mar 20 '17 at 22:06
  • Bit I've deregistered it with `wp_deregister_script( 'conditionizr');` haven't I? Or am I missing something? – user1406440 Mar 20 '17 at 22:10
  • 1
    But something must be trying to use it, or you wouldn't get that error, so maybe you shouldn't deregister it? (I'm not familiar enough with Wordpress to know what "deregistering" is doing, but it sounds like it would make it unavailable.) – miken32 Mar 20 '17 at 22:11
  • Yeah I was thinking that but I couldn't find it anywhere in the `functions.php`. Just woke up and found some script in the `header.php`. I removed that and it looks like it now doesn't throw up the error. Looks like it was just settings/config for the file, so not needed if it's not called: `conditionizr.config({assets: '',tests: {}});` Thanks for the help! :) – user1406440 Mar 21 '17 at 08:07

3 Answers3

2

As others have pointed out, you need to fix your dependency array in your wp_register_script() statements.

On a side note, you do not need to use both wp_register_script() and wp_enqueue_script(). Just follow the wp_register_script() syntax and you're fine. For example:

wp_enqueue_script( 'my-script', get_stylesheet_directory_uri() . /js/script.js', array( 'jquery', 'responsive-nav', 'uniform-js', '', true);

This will register the handle 'my-script', associate it with the script.js file in your theme directory's /js directory, tell WordPress it needs jQuery, 'responsive-nav', and 'uniform-js' in order to run, there's no version number, and to load it in the footer. All dependencies must be loaded prior. jQuery is the only one that comes with WordPress so the others will need to be enqueued first.

As for jQuery, WordPress loads it in no-conflict mode so you will NOT have access to $() by default. There are a few work-arounds for this. The easiest is to simply replace $() with jQuery(). If your script has to load in the header, then this is what you want to do.

If it can load in the footer, which is the option you want, then you can wrap your entire script in an anonymous function passing jQuery in. So it would look like this:

( function( $ ) {
   // Your jQuery Script Here
} )( jQuery );

Also, instead of just using wp_deregister_script(), try using just wp_dequeue_script() instead. So:

wp_dequeue_script( 'modernizr' );
Cedon
  • 627
  • 7
  • 15
  • Thanks for the reply. I guess the first part won't work as I deregister html5blankscripts - is that not advisable? What is the difference between dequeue and deregister? Sorry, I've not got my script to hand at the minute but I'll check it out a bit later. Is my code basically doing the same thing but in a long-winded/unnecessary way? The way you suggest streamlines the code a lot more? – user1406440 Mar 21 '17 at 16:17
  • 1
    I'm not sure what `html5blankscripts` does so I cannot advise you there. `wp_dequeue_script()` is a newer function (WP 3.1). The reason I suggest using that instead of `wp_deregister_script()` is because your theme's parent might still be trying to enqueue it. As for the pairing of `wp_register_script()` and `wp_enqueue_script()`, using just the enqueue is a better practice. If a script is going to load conditionally though, then using both functions is fine. – Cedon Mar 21 '17 at 17:32
  • is it fine to use `jQuery(function($){ [SCRIPT HERE] });`? What are the benefits of putting the jQuery bit on the end? Or are they both the same thing, really? – user1406440 Mar 23 '17 at 11:29
  • There are some performance benefits. The loading of your scripts will not interfere with DOM loading and all DOM elements will be available to the script. Plus if jQuery loads in the footer, you don't need `$(document).ready() { });` because the DOM will already be loaded since the jQuery is one of the last things loaded. – Cedon Mar 23 '17 at 15:01
1

I won't pretend to know much about those Wordpress internal functions, but your first error indicates that something is using the conditionizr object. You should probably not be using wp_deregister_script('conditionizr') unless you deal with the script file referencing it first.

As to the other error, I did have to add some jQuery script to a WP site recently, and was having trouble using $. Replacing it with jQuery solved that issue. For example:

jQuery(function(){

    var navigation = responsiveNav(".site-nav__list", {
        customToggle: "#site-nav__toggle",
        open: function(){
            jQuery("#site-nav__toggle").addClass('open');
        },
        close: function(){
            jQuery("#site-nav__toggle").removeClass('open');
        }
    });
});

jQuery("select, input[type='file'], input[type='checkbox'], input[type='radio']").uniform({selectAutoWidth: false, fileButtonClass: 'btn'});

According to a comment below, this is because jQuery has a no-conflict mode which will "relinquish control of the $ variable."

miken32
  • 42,008
  • 16
  • 111
  • 154
  • I couldn't get that to work but swapping `$(function(){` for `jQuery(function($){` seems to do the trick! I take it that's essentially doing the same thing? – user1406440 Mar 21 '17 at 08:13
  • Yes, sorry I missed that one. Anywhere you have $ it won't work – miken32 Mar 21 '17 at 14:15
  • 3
    It's because WordPress loads jQuery in no-conflict mode so you cannot use `$()` out of the box. You either replace `$()` with `jQuery()` or wrap the entire script in `(function( $ ) { } )( jQuery )` – Cedon Mar 21 '17 at 19:17
1

• You need to include both responsive-nav and uniform-js in the dependancies of main-js, because you are making use of them inside main.js. (Actually, as you are calling jQuery as a dependency in each of those scripts there is no need to call it again)

wp_register_script('main-js', get_stylesheet_directory_uri() . '/js/main.js', array('jquery','responsive-nav','uniform-js'));
wp_enqueue_script('main-js');

• Error 1. Instead of starting your function:

$(function(){

try:

jQuery(function($){

• Error 2. It seems like some of the scripts is calling conditionizr function so, as you are deregistering, it JavaScript throws an error. Find out which script is calling it and remove that function call. (I might be wrong but it looks like it is being called from an inline script, check for wp_add_inline_script)

Alvaro
  • 9,247
  • 8
  • 49
  • 76
  • You're right, having a fresh look at it this morning I found some script referencing Conditionizr in `header.php`. It looked like they were settings/config for the script which obviously isn't needed anymore. Removing it seems to get rid of the error. :) – user1406440 Mar 21 '17 at 08:08
  • I take it I should wrap the second (uniform.js) script in that jQuery function as well, like this? `jQuery(function($){ [SCRIPT HERE] });` – user1406440 Mar 21 '17 at 08:10
  • 1
    If you are not making use of jQuery in that script there is no need to wrap it that way (nor to use it as a dependancy for that script). If jQuery is need there then yes, probably this should be the way :) – Alvaro Mar 21 '17 at 08:17
  • Hmmm well it did throw a console error about $ not being a function, then I wrapped it in a jQuery function and the error didn't show anymore ...so I guess I need it ;) – user1406440 Mar 21 '17 at 09:07
  • @user1406440 You use `jQuery(function($){` inside the script that is making use of jQuery (previously added as a dependancy). If you are not using jQuery (no need to add it as dependancy) you don't need to use `$(function(){` neither. – Alvaro Mar 21 '17 at 09:34
  • I've just looked up uniform.js and it is a jQuery plug-in so I guess it needs it as well. Currently it's just `$("select, input[type='file'], input[type='checkbox'], input[type='radio']").uniform({selectAutoWidth: false, fileButtonClass: 'btn'});` – user1406440 Mar 21 '17 at 13:17