最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

theme customizer - Add or remove HTML class with selective refresh?

programmeradmin1浏览0评论

I've read about Selective Refresh and I understand it. It completely rewrites the element targeted by the specified selector. For example:

$wp_customize->get_setting( 'nav_type' )->transport = 'postMessage';
$wp_customize->selective_refresh->add_partial( 'nav_type', array(
    'selector' => '#container nav',
    'render_callback' => 'change_body_class',
) );

This will remove the <nav> inside an element with id container and replace it with whatever happens in the change_body_class function. As the name of the function suggests, though, I just want to change the class of the <body> element. Why? Well, in my CSS, I have different layouts for the navigation that are toggled through a <body> class.

Question

I want a selective refresh that shows the shortcut icon next to Element A while changing the class of Element B. Is this possible? If yes, how do I do it?

I've read about Selective Refresh and I understand it. It completely rewrites the element targeted by the specified selector. For example:

$wp_customize->get_setting( 'nav_type' )->transport = 'postMessage';
$wp_customize->selective_refresh->add_partial( 'nav_type', array(
    'selector' => '#container nav',
    'render_callback' => 'change_body_class',
) );

This will remove the <nav> inside an element with id container and replace it with whatever happens in the change_body_class function. As the name of the function suggests, though, I just want to change the class of the <body> element. Why? Well, in my CSS, I have different layouts for the navigation that are toggled through a <body> class.

Question

I want a selective refresh that shows the shortcut icon next to Element A while changing the class of Element B. Is this possible? If yes, how do I do it?

Share Improve this question asked Jul 11, 2017 at 8:18 dodovdodov 1971 silver badge9 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 2

Yes. This can be accomplished by creating a custom selective refresh Partial type, and overriding the refresh method in the JavaScript class.

Here's the relevant JavaScript which should get enqueued in the Customizer preview, with customize-selective-refresh as its script dependency:

wp.customize.selectiveRefresh.partialConstructor.body_class = wp.customize.selectiveRefresh.Partial.extend({

    /**
     * Class name choices.
     *
     * This is populated in PHP via `wp_add_inline_script()`.
     *
     * @type {Array}
     */
    choices: [],

    /**
     * Refresh partial.
     *
     * Override refresh behavior to bypass partial refresh request in favor of direct DOM manipulation.
     *
     * @returns {jQuery.Promise} Resolved promise.
     */
    refresh: function() {
        var partial = this, setting, body, deferred, className;

        setting = wp.customize( partial.params.primarySetting );
        className = setting.get();
        body = $( document.body );
        body.removeClass( partial.choices.join( ' ' ) );
        body.addClass( className );

        // Do good diligence and return an expected value from the function.
        deferred = new $.Deferred();
        deferred.resolveWith( partial, _.map( partial.placements(), function() {
            return '';
        } ) );
        return deferred.promise();
    }
});

Then you can make use of this custom type when you register the partial in PHP:

$wp_customize->selective_refresh->add_partial( 'nav_body_class', array(
    'selector' => 'nav',
    'type' => 'body_class',
) );

Here is a full working plugin that demonstrates the technique: https://gist.github/westonruter/731e3106177ce2b067290ddbe602ce05

发布评论

评论列表(0)

  1. 暂无评论