Add a “loading” notice when Customizer is making changes

I really want to try and add an overlay and “loading” notice to the wordpress customizer when a change is made.

For some of my larger theme changes that are made through the customizer, I am using the refresh (default) transport mode. However, to increase my user experience, I think some kind of notice to say that the change is loading is necessary.

I’ve tried loading a few lines of jquery into the Customizer to do a bit of a work around, I noticed when you make a change, what is actually happening is an additional iframe is added to the preview with the new change and the old iframe is removed, so I tried this:

if ($('#customize-preview').children().length = 2) {
  $('#customize-preview').addClass('loading');
  } else {
  $('#customize-preview').removeClass('loading');
  $('#customize-preview').addClass('loaded');
  }

With no avail, I also tried this to add a class when the iframe was loaded:

$('#customize-preview iframe').ready(function () {
$('#customize-preview').addClass('loading');
$('#customize-preview').removeClass('loaded');
});

I’ve tried a few other methods to detect when the iframe is reloading, but had no success. So I thought I’d put it out on here to see if anyone else had any bright ideas.

To be clear, I want to find a way to add a “loading” notice and ideally an overlay div when a change is being made in the Customizer.

Answer below has helped me add a class when the preview is loading. However I need to try and add a overlay div when the preview is loading, and then remove it once it has loaded.

setInterval(function(){
if( previewDiv.children('iframe').length > 1 ) {
    previewDiv.addClass('loading');
    previewDiv.html('<div class="loading-overlay"></div>');

} else{
    previewDiv.removeClass('loading');
    previewDiv.addClass('loaded');
    previewDiv.remove('.loading-overlay');
}
}, 100);

This code here will add the overlay – but won’t remove it.

Solutions Collecting From Web of "Add a “loading” notice when Customizer is making changes"

While this might not a be the perfect solution but this should work. You can set an interval to check against the preview iframe, like this:

var previewDiv = $('#customize-preview');
previewDiv.prepend('<div class="loading-overlay"></div>');
var loadingOverlay = previewDiv.find('.loading-overlay');

setInterval(function(){
    if( previewDiv.children('iframe').length > 1 ) {
        previewDiv.addClass('loading');
    } else{
        previewDiv.removeClass('loading');
        previewDiv.addClass('loaded');
    }
}, 100);

I use this simple process:

add_action( 'customize_controls_print_footer_scripts', 'add_loader' );

function add_loader() {
    ?>
    <script type="text/javascript">
    jQuery(function($) {
        var loader = '<div class="custom_loading"/>';
        $( "body" ).append( loader );
    });
    </script>
    <style>
        .custom_loading{width: 100%; height: 100%; position: fixed; top: 0; left: 0; background: rgba(0,0,0,0.5); z-index: 999999; display: none;}
        .saving .custom_loading{display: block}
    </style>
    <?php
}

Here in .custom_loading class you can set a loading icon as background: background: url(../path/to/loading/image) center center no-repeat;

It should work 🙂

Edit: You can also add css3 animation and transition property to the loading div to make an animated loading.