3

I have a theme that is having an issue when there are unsaved theme changes, then the user restores an autosave.

My theme has some jquery that watches for a font to be changed, then updates a second control with new font weights, and also updates a div label with the current font name. The problem is when the autosave is restored, my font selection shows the autosaved font name, but the weights section shows the previously published value still. My jquery doesn't realize that the font name has been updated by the autosave.

I'm thinking that the best way to handle this is to trigger a javascript that will run as soon as the autosave is restored, but I can't figure out a way to accomplish this.

What I'm trying now is the following: I'm already enquing a script successfully for other functions. I've created a new function inside that script as follows:

( function( wp, $ ) {

    function bob() {
        alert('bob');
    }
    // Etc
} )( wp, jQuery );

I'm enquing this script successfully using the following code, then inserting an inline script. This does insert inline successfully, but I get an error that bob is undefined.

function mytheme_enqueue() {
global $theFontsList;
wp_enqueue_style( 'mytheme-fonts', throwback_fonts_url(), array(), null );
wp_enqueue_script ( 'mytheme_font_js', get_template_directory_uri().'/inc/font.js', array('customize-controls'), false, true);

wp_add_inline_script( 'mytheme_font_js', 'const theFont = ' . json_encode( $theFontsList ) .';', 'before' );
wp_add_inline_script( 'mytheme_font_js', 'bob();', 'after' );
}

My resulting HTML looks like this:

<script id='mytheme_font_js-js-before'>
const theFont = // Removed for brevity
</script>
<script src='https://example.com/test/wp-content/themes/mytheme/inc/font.js?123&#038;ver=6.1.1' id='mytheme_font_js-js'></script>
<script id='mytheme_font_js-js-after'>
bob();
</script>

1 Answer 1

2

In the JavaScript CODE below:

( function( wp, $ ) {

    function bob() {
        alert('bob');
    }
    // Etc
} )( wp, jQuery );

bob function is scoped only within this block:

( function( wp, $ ) {
    // functions defined here are not accessible from outside
} )( wp, jQuery );

That's why when you load the inline script and call bob(), you get bob is undefined error.

You'll get the same error, if you do this:

( function( wp, $ ) {

    function bob() {
        alert('bob');
    }
    // Etc
} )( wp, jQuery );
// bob is undefined here.
bob();

This code structure is known as Immediately-Invoked Function Expression (IIFE).

You can avoid this error by doing something like this:

( function( wp, $, w ) {

    w.bob = function() {
        alert('bob');
    }
    // other code not part of the window object
} )( wp, jQuery, window );
// bob is now defined here.
bob();

But remember, now that you are using the window object, it can now have naming conflict with other variables defined in the global scope. So the function names must be unique.

1
  • That is actually quite helpful. I'm still learning some of the gotchas with Javascript and how things are being scoped. LOL
    – JWright
    Jan 31, 2023 at 2:19

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.