web-dev-qa-db-fra.com

Personnalisateur: plusieurs styles CSS sur le même élément dans l'aperçu en direct

J'ai un en-tête collant qui a une couleur d'arrière-plan initiale et une couleur d'arrière-plan différente lors du défilement. J'ai du javascript qui ajoute une classe .navbar-scroll à la barre de navigation suivante lors du défilement:

<nav id="nav" class="navbar navbar-fixed-top">
    ...
</nav>

Le css ressemble à ceci:

.navbar {
    background-color: #000;
}

.navbar-scroll {
    background-color: #fff;
}

J'ai le code suivant dans customizer.php:

// Header Background Color
$wp_customize->add_setting( 'header_background_color', array(
    'default'           => '#000',
    'transport'         => 'postMessage'
) ); 
$wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'header_background_color', array(
    'label'             => __( 'Header Background Color', 'my-theme' ),
    'section'           => 'title_tagline',
    'settings'          => 'header_background_color',
) ) );

// Sticky Header Background Color
$wp_customize->add_setting( 'sticky_header_background_color', array(
    'default'           => '#fff',
    'transport'         => 'postMessage'
) ); 
$wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'sticky_header_background_color', array(
    'label'             => __( 'Sticky Header Background Color', 'my-theme' ),
    'section'           => 'title_tagline',
    'settings'          => 'sticky_header_background_color',
) ) );

function header_output() {
    <style type="text/css">
    .navbar { 
        background-color: <?php echo get_theme_mod( 'header_background_color' , '#000' ); ?>;
    }
    .navbar-scroll { 
        background-color: <?php echo get_theme_mod( 'sticky_header_background_color' , '#fff' ); ?>;
    }
    </style>
} 
function generate_css( $selector, $style, $mod_name, $prefix='', $postfix='', $echo=true ) {
    ... // I'll omit this code here
}
add_action( 'wp_head' , 'header_output' );

J'ai le code suivant dans customizer.js:

// Background Color
wp.customize( 'header_background_color', function( value ) {
    value.bind( function( newval ) {
        $('.navbar').css( 'background-color', newval );
    } );
} );

// Sticky Background Color
wp.customize( 'sticky_header_background_color', function( value ) {
    value.bind( function( newval ) {
        $('.navbar-scroll').css( 'background-color', newval );
    } );
} );

Le problème que je rencontre est dans l'aperçu en direct du personnalisateur. Lorsque l'utilisateur change de couleur, il injecte le style CSS sur cet élément et remplace le style existant sur cet élément. Par conséquent, l'utilisateur ne peut voir qu'une couleur à la fois. Par exemple, si la couleur d'arrière-plan de l'en-tête initiale est modifiée, cette couleur sera toujours visible lors du défilement. Si la couleur d'arrière-plan de l'en-tête collant est modifiée, seule cette couleur sera visible, que l'utilisateur ait fait défiler l'écran ou non. Une fois sauvegardé, cela fonctionnera bien au début mais je ne veux pas expliquer ce bug à l'utilisateur.

Y a-t-il un moyen de garder les deux styles actifs? Peut-être injecter le css pour chaque classe dans la tête au lieu d'inline?

1
Troy Templeman

Oui, au lieu de mettre à jour la style en ligne pour les éléments directement, une feuille de style devrait être utilisée. Vous pouvez créer un modèle de feuille de style utilisé à la fois en JS et en PHP. Cela a été fait dans le thème Twenty Sixteen et je viens de travailler dessus dans un exemple plugin autonome pour une autre réponse .

Notez comment une chaîne stylesheet_template est créée et que cette chaîne de modèle est rendue par PHP à l'action wp_print_styles:

/**
 * Print styles.
 */
public function print_styles() {
    echo '<style id="wpse-286268" type="text/css">';
    $css = $this->stylesheet_template;
    $tpl_vars = array();
    foreach ( $this->device_configs as $slug => $params ) {
        $tpl_vars[ '{{outline_color_' . $slug . '}}' ] = get_theme_mod( "outline_color_{$slug}", $params['default'] );
    }
    echo esc_html( str_replace(
        array_keys( $tpl_vars ),
        array_values( $tpl_vars ),
        $css
    ) );
    echo '</style>';
}

Et puis aussi, il est rendu par JS dans l'aperçu du personnalisateur :

/**
 * Update preview.
 *
 * @returns {void}
 */
component.updatePreview = function updatePreview() {
    var css = component.stylesheetTemplate;
    _.each( component.deviceSettings, function( setting ) {
        css = css.replace( '{{' + setting.id + '}}', setting.get() );
    } );
    component.style.text( css );
};
0
Weston Ruter