salcode / bootstrap-genesis

WordPress Genesis Child Theme setup to use Bootstrap, Sass, and Grunt
MIT License
184 stars 63 forks source link

jQuery issues with enqueue scripts #116

Closed christopherarter closed 8 years ago

christopherarter commented 8 years ago

Hello,

I'm having some issues with jQuery. For testing, I created a fresh install of your theme and started from scratch.

I'm placing my .js into js/custom, running grunt (uglify), everything is working well there. I'm registering and enqueuing my scripts in a custom plugin file, but when the DOM loads, it's loading the enqueued script first before jQuery, so its throwing an error "can't find variable:jQuery".

I've tested using the old dirty wp_head hook and doing a simple script in the head is not getting any jQuery conflict, so it appears something is happening when it's registering and enqueuing the script.

Do you have an idea of what may be happening?

salcode commented 8 years ago

This doesn't sound like it is related to this theme. I suggest switching themes and seeing if you still get the same error.

My guess is you need to include 'jquery' in the $deps parameter in wp_enqueue_script(). See https://codex.wordpress.org/Function_Reference/wp_enqueue_script

bryanwillis commented 8 years ago

Here's example of what Sal is referring to with jquery dependency:

function custom_bsg_enqueue_css_js() {
    wp_register_script( 'custom-bsg-javascript', trailingslashit( get_stylesheet_directory_uri() ) . 'js/custom/bsg-custom.js', array('jquery'), '1.0.0', true );

        wp_enqueue_script( 'custom-bsg-javascript' );
}
add_action( 'wp_enqueue_scripts', 'custom_bsg_enqueue_css_js' );

Personally I think if you are adding the css/js to the theme, but registering it through a plugin that sort of defeats the purpose of the plugin.

Consider adding the css/js in your plugin. That way you can update the theme and not loose changes. Here's an example below...

Directory

myplugin/
├── myplugin.php
├── js/
│   ├── custom-bsg-scripts.js
└── lib/
       ├── custom-bsg-scripts.php

custom-bsg-scripts.php

function custom_bsg_scripts() {

    wp_register_script( 'custom-bsg-scripts', plugins_url('js/custom-bsg-scripts.js', __DIR__), array('jquery'), '1.0.0', true );

    wp_enqueue_script( 'custom-bsg-scripts' );

}
add_action( 'wp_enqueue_scripts', 'custom_bsg_scripts' );
bryanwillis commented 8 years ago

Also, it's kind of confusing when you say your placing your .js in js/custom....

Do you mean your javascript is being added to js/custom.js and then you are compiling it? If so you shouldn't need to register/enqueue anything else in your plugin.

If you look at this file below you will notice it is adding jquery to the footer which is why you need to make sure that if you add any additional jquery scripting you need to include jq as an dependency so it loads after in the footer (as Sal mentioned).

https://github.com/salcode/bootstrap-genesis/blob/develop/lib/load-assets.php

salcode commented 8 years ago

@bryanwillis great points. Thanks for your notes and making me look at this again, I was overlooking that the JS was in the theme.

@christopherarter Bryan makes a good point that generally you should be enqueuing the JavaScript in the same entity where you're housing it (i.e. JS in the plugin gets enqueued in the plugin, JS in the theme gets enqueued in the theme).

I'm enqueuing the theme JS in https://github.com/salcode/bootstrap-genesis/blob/develop/lib/load-assets.php.

One other note, a popular pattern I use when adding additional JS to the theme is adding it to the js/custom directory and then add the additional file to Gruntfile.js on these lines so it becomes part of the one minified JS file for the theme.

christopherarter commented 8 years ago

Thanks @salcode and @bryanwillis!

JS Enqueue - Grunt Shortly after posting this, I found the load-assets file which makes sense why I wouldn't need to enqueue anything anywhere, really. Especially since the JS files have been added to the Grunt.js file as @salcode suggested. I have virtually zero experience with Grunt before this, but judging from this line:

    uglify_source_files = [
        'js/vendor/**/*.js',
        'js/custom/javascript.js',

It seems I wouldn't need to enumerate each JS file to be source files if I just included:

        'js/custom/*.js',

Right?

I am listing out each file I'd like to use as source for uglify at the moment, though. Like this:

    uglify_source_files = [
        'js/vendor/**/*.js',
        'js/custom/javascript.js',
    'js/vendor/flat-ui.js',
    'js/vendor/test.js',
    'js/vendor/datatables.js',
    'js/dataTables.responsive.js',
    'js/dataTables.fixedHeader.js',
],

JS Enqueue - Plugin Structure When I develop on a normal child theme (prior to using Grunt) I kept everything self contained as you suggested @bryanwillis. I like to keep things neat! Can I just add the plug-in paths to the plugin's JS to the grunt file to add them to the uglify source? I assume so, right?

Console Log Test (new problem)

I added my test.js to the grunt file, put it in vendor (just to try different options), and I can see the code inside javascript.min.js, however, there is no console log.

This is my test.js file:

  jQuery(document).ready(function(){

  console.log("The truth is out there, Scully.");

  });

However, I see no agent Mulder in my console.. Ideas?

salcode commented 8 years ago

A couple of notes:

Why not include 'js/custom/*.js'

It seems I wouldn't need to enumerate each JS file to be source files if I just included: 'js/custom/*.js',

Yes, however then you have no control over the order in which files are loaded, which is why I don't have that as a default.

JS in Vendor directory does not need to be included explicitly

You can remove these lines from your Gruntfile.js

'js/vendor/flat-ui.js'
'js/vendor/test.js',
'js/vendor/datatables.js',

as they are included by 'js/vendor/**/*.js',

JS Enqueue - Plugin Structure

Can I just add the plug-in paths to the plugin's JS to the grunt file to add them to the uglify source? I assume so, right?

This is a tricky question and there are different schools of thought. My own thoughts are:

Console Log Test (new problem)

I don't know why this doesn't work for you. This works for me. See branch console-log-test-116

salcode commented 8 years ago

Since there hasn't been any activity on this, I'm going to close this issue. If this specific issue still exists, we can reopen. If there is something tangentially related, we can create a new issue.