Update: The fix here has been incorporated into WordPress Core trunk
for the upcoming 4.5 release (now in alpha). See r36371.
I think the problem with the unbinding of the event handler is that it is being done too early. Try doing it at the preview-ready
Customizer event. For example, enqueue the following JS in your Customizer preview (with customize-preview
as a script dependeny) which short-circuits the click.preview
logic if the link clicked has an in-page link target or if it uses the javascript:
protocol:
if ( /\/customize\.php$/.test( window.location.pathname ) ) {
wp.customize.bind( 'preview-ready', function() {
var body = $( 'body' );
body.off( 'click.preview' );
body.on( 'click.preview', 'a[href]', function( event ) {
var link = $( this );
if ( /^(#|javascript:)/.test( link.attr( 'href' ) ) ) {
return;
}
event.preventDefault();
wp.customize.preview.send( 'scroll', 0 );
wp.customize.preview.send( 'url', link.prop( 'href' ) );
});
} );
}
The inclusion of the href
type really should be part of Core and I’ll add it to my todo list to get that committed as part of the 4.5 cycle.
Note the test for customize.php
is to ensure that transactions with the natural URL being used as the Customizer preview iframe
URL hasn’t been implemented yet, because that change will mean changes to the click.preview
logic.