Yes, you can change the `transport` of a registered setting dynamically after the page loads. And actually the `active_callback` can be used in conjunction with JS to change the `transport` _instead of_ causing the control to be hidden.

Assuming you have registered a control with the ID of `excerpt_length`, and you have registered a setting and control as follows:

	$wp_customize->add_setting( 'excerpt_length', array(
		'transport'         => 'refresh',
		'sanitize_callback' => function( $value ) {
			return intval( $value );
		},
	) );

	$wp_customize->add_control( 'excerpt_length', array(
		'label'           => __( 'Excerpt length', 'example' ),
		'section'         => 'something',
		'type'            => 'number',
		'active_callback' => function() {
			// Admin check is for initial state in customize.php.
			return is_admin() || is_archive() || ( is_home() && ! is_front_page() );
		},
	) );

Then you can enqueue some JS for the Customizer controls app (at `customize_controls_enqueue_scripts`) which overrides the behavior for when the `active` state changes, like so to toggle the setting's `transport` when `active` state changes instead of toggling the visibility of control:

	wp.customize.control( 'excerpt_length', function( control ) {
		control.onChangeActive = function( active ) {
			control.setting.transport = active ? 'refresh' : 'postMessage';
		};
	} );

There's other ways to do it, but this is probably the least amount of code.