描述
因为客户需求改动一下,但是看网上都是用插件去实现,因为不太想用插件形式去实现,那么就使用纯代码将woocommerce中的商品属性从下拉选择框改为点选。
效果
代码
PHP代码:填写进主题或者子主题的funtcion.php中
add_filter( 'woocommerce_dropdown_variation_attribute_options_html', 'roamacg_woocommerce_dropdown_variation_attribute_options_html', 10, 2 ); function roamacg_woocommerce_dropdown_variation_attribute_options_html( $select_html, $args ) { global $roamacg_settings; $args = wp_parse_args( apply_filters( 'woocommerce_dropdown_variation_attribute_options_args', $args ), array( 'options' => false, 'attribute' => false, 'product' => false, 'selected' => false, 'name' => '', 'id' => '', 'class' => '', 'show_option_none' => __( 'Choose an option', 'woocommerce' ), ) ); $options = $args['options']; $product = $args['product']; $attribute = $args['attribute']; // show description of selected attribute $attr_description_html = ''; if ( isset( $roamacg_settings['product-attr-desc'] ) && $roamacg_settings['product-attr-desc'] && ! empty( $attribute ) && ! empty( $product ) && taxonomy_exists( $attribute ) ) { if ( empty( $options ) ) { $attributes = $product->get_variation_attributes(); $options = $attributes[ $attribute ]; } $terms = wc_get_product_terms( $product->get_id(), $attribute, array( 'fields' => 'all' ) ); /* translators: %s: Attribute title */ $attr_description_html .= '<div class="product-attr-description' . ( $args['selected'] ? ' active' : '' ) . '"><a href="#"><i class="fas fa-exclamation-circle"></i> ' . sprintf( esc_html__( '阅读更多 %s', 'storefront-wei' ), '<span>' . ( $args['name'] ? esc_html( $args['name'] ) : wc_attribute_label( $attribute ) . '</span>' ) ) . '</a><div>'; foreach ( $terms as $term ) { if ( in_array( $term->slug, $options ) && $term->description ) { $attr_description_html .= '<div class="attr-desc' . ( sanitize_title( $args['selected'] ) == $term->slug ? ' active' : '' ) . '" data-attrid="' . esc_attr( $term->slug ) . '">' . wp_kses_post( $term->description ) . '</div>'; } } $attr_description_html .= '</div></div>'; } if ( isset( $roamacg_settings['product_variation_display_mode'] ) && 'select' === $roamacg_settings['product_variation_display_mode'] ) { return $select_html . $attr_description_html; } $name = $args['name'] ? $args['name'] : 'attribute_' . sanitize_title( $attribute ); $id = $args['id'] ? $args['id'] : sanitize_title( $attribute ); $class = $args['class']; $show_option_none = $args['show_option_none'] ? true : false; $attr_type = ''; $attribute_taxonomies = wc_get_attribute_taxonomies(); if ( $attribute_taxonomies ) { foreach ( $attribute_taxonomies as $tax ) { if ( wc_attribute_taxonomy_name( $tax->attribute_name ) === $attribute ) { if ( 'color' === $tax->attribute_type ) { $attr_type = 'color'; break; } elseif ( 'label' === $tax->attribute_type ) { $attr_type = 'label'; break; } } } } if ( empty( $options ) && ! empty( $product ) && ! empty( $attribute ) ) { $attributes = $product->get_variation_attributes(); $options = $attributes[ $attribute ]; } $html = ''; if ( ! empty( $options ) ) { $swatch_options = $product->get_meta( 'swatch_options', true ); $key = md5( sanitize_title( $attribute ) ); $html .= '<ul class="filter-item-list" name="' . esc_attr( $name ) . '">'; if ( $product ) { $select_html = '<select id="' . esc_attr( $id ) . '" class="' . esc_attr( $class ) . '" name="' . esc_attr( $name ) . '" data-attribute_name="attribute_' . esc_attr( sanitize_title( $attribute ) ) . '" data-show_option_none="' . ( $show_option_none ? 'yes' : 'no' ) . '">'; $select_html .= '<option value=""></option>'; $attribute_terms = array(); if ( taxonomy_exists( $attribute ) ) { // Get terms if this is a taxonomy - ordered. We need the names too. $terms = wc_get_product_terms( $product->get_id(), $attribute, array( 'fields' => 'all' ) ); foreach ( $terms as $term ) { if ( in_array( $term->slug, $options ) ) { $attribute_terms[] = array( 'id' => md5( $term->slug ), 'slug' => $term->slug, 'label' => $term->name, 'term_id' => $term->term_id, ); } } } else { foreach ( $options as $term ) { $attribute_terms[] = array( 'id' => ( md5( sanitize_title( strtolower( $term ) ) ) ), 'slug' => esc_html( $term ), 'label' => esc_html( $term ), ); } } if ( isset( $swatch_options[ $key ] ) && isset( $swatch_options[ $key ]['type'] ) ) { if ( 'color' != $attr_type && 'color' == $swatch_options[ $key ]['type'] ) { $attr_type = 'color'; } elseif ( 'image' == $swatch_options[ $key ]['type'] ) { $attr_type = 'image'; } } if ( 'image' == $attr_type ) { $image_size = isset( $swatch_options[ $key ]['size'] ) ? $swatch_options[ $key ]['size'] : 'swatches_image_size'; } foreach ( $attribute_terms as $term ) { $color_value = ''; if ( isset( $term['term_id'] ) ) { $color_value = get_term_meta( $term['term_id'], 'color_value', true ); } if ( ( ! isset( $color_value ) || ! $color_value ) && isset( $swatch_options[ $key ] ) && isset( $swatch_options[ $key ]['attributes'][ $term['id'] ]['color'] ) ) { $color_value = $swatch_options[ $key ]['attributes'][ $term['id'] ]['color']; } $current_attribute_image_src = ''; if ( 'image' == $attr_type && isset( $swatch_options[ $key ]['attributes'][ $term['id'] ]['image'] ) ) { $current_attribute_image_id = $swatch_options[ $key ]['attributes'][ $term['id'] ]['image']; if ( $current_attribute_image_id ) { $current_attribute_image_src = wp_get_attachment_image_src( $current_attribute_image_id, $image_size ); $current_attribute_image_src = $current_attribute_image_src[0]; } } if ( 'color' == $attr_type ) { $a_class = 'filter-color'; $option_attrs = ' data-color="' . esc_attr( $color_value ) . '"'; $a_attrs = ' title="' . esc_attr( apply_filters( 'woocommerce_variation_option_name', $term['label'] ) ) . '" style="background-color: ' . esc_attr( $color_value ) . '"'; } elseif ( 'image' == $attr_type ) { $a_class = 'filter-item filter-image'; $option_attrs = ' data-image="' . esc_url( $current_attribute_image_src ) . '"'; if ( $current_attribute_image_src ) { $a_attrs = ' style="background-image: url(' . esc_url( $current_attribute_image_src ) . ')"'; } else { $a_attrs = ''; } } else { $a_class = 'filter-item'; if ( 'label' == $attr_type ) { $a_attrs = ' title="' . esc_attr( apply_filters( 'woocommerce_variation_option_name', $term['label'] ) ) . '"'; $label_value = get_term_meta( $term['term_id'], 'label_value', true ); } else { $a_attrs = ''; } $option_attrs = ''; } $select_html .= '<option' . $option_attrs . ' value="' . esc_attr( $term['slug'] ) . '" ' . selected( sanitize_title( $args['selected'] ), $term['slug'], false ) . '>' . esc_html( apply_filters( 'woocommerce_variation_option_name', $term['label'] ) ) . '</option>'; $html .= '<li>'; $html .= '<a href="#" class="' . $a_class . '" data-value="' . esc_attr( $term['slug'] ) . '" ' . ( sanitize_title( $args['selected'] ) == $term['slug'] ? ' class="active"' : '' ) . $a_attrs . '>' . esc_html( 'label' == $attr_type && $label_value ? $label_value : apply_filters( 'woocommerce_variation_option_name', $term['label'] ) ) . '</a>'; $html .= '</li>'; } $select_html .= '</select>'; } $html .= '</ul>'; } return $html . $select_html . $attr_description_html; }
JS代码:
window.theme = "storefront"; (function(theme, $) { var $supports_html5_storage; try { $supports_html5_storage = ( 'sessionStorage' in window && window.sessionStorage !== null ); window.sessionStorage.setItem( 'wc', 'test' ); window.sessionStorage.removeItem( 'wc' ); } catch( err ) { $supports_html5_storage = false; } var setCartCreationTimestamp = function() { if ( $supports_html5_storage ) { sessionStorage.setItem( 'wc_cart_created', ( new Date() ).getTime() ); } }; var setCartHash = function(cart_hash) { if ( $supports_html5_storage && wc_cart_fragments_params ) { localStorage.setItem( wc_cart_fragments_params.cart_hash_key, cart_hash ); sessionStorage.setItem( wc_cart_fragments_params.cart_hash_key, cart_hash ); } }; var updateCartFragment = function(data) { if (data && data.fragments) { var fragments = data.fragments, cart_hash = data.cart_hash; $.each(fragments, function(key, value) { $(key).replaceWith(value); }); if ( typeof wc_cart_fragments_params === 'undefined' ) { return; } /* Storage Handling */ if ( $supports_html5_storage ) { var prev_cart_hash = sessionStorage.getItem( 'wc_cart_hash' ); if ( prev_cart_hash === null || prev_cart_hash === undefined || prev_cart_hash === '' ) { setCartCreationTimestamp(); } sessionStorage.setItem( wc_cart_fragments_params.fragment_name, JSON.stringify( fragments ) ); setCartHash( cart_hash ); } } }; $(function() { // add ajax cart loading $(document).on('click', '.add_to_cart_button', function(e) { var $this = $(this); if ( $this.is('.product_type_simple') ) { if ( $this.attr('data-product_id') ) { $this.addClass('product-adding'); } //add to cart notifaction style 2 if( $this.hasClass('viewcart-style-2') ){ $('body').append('<div id="loading-mask"><div class="background-overlay"></div></div>'); if (!$(this).closest('.product').find('.loader-container').length) { $(this).closest('.product').find('.product-image').append('<div class="loader-container"><div class="loader"><i class="porto-ajax-loader"></i></div></div>'); } $(this).closest('.product').find('.loader-container').show(); } } }); // add to cart action $(document).on('click', 'span.add_to_cart_button', function(e) { var $this = $(this); if ( $this.is('.product_type_simple') ) { if ( !$this.attr('data-product_id') ) { window.location.href = $this.attr('href'); } } else { window.location.href = $this.attr('href'); } }); $(document).on( 'click', '.product-image .viewcart, .after-loading-success-message .viewcart', function( e ){ if (wc_add_to_cart_params.cart_url) { window.location.href = wc_add_to_cart_params.cart_url; } e.preventDefault(); }); var porto_product_add_cart_timer = null; $(document).on('added_to_cart', 'body', function(event) { $('.add_to_cart_button.product-adding').each(function() { var $link = $(this); $link.removeClass('product-adding'); if ($link.hasClass('viewcart-style-1')) { $link.closest('.product').find('.viewcart').addClass('added'); } else { //add to cart notifaction style 2 $('body #loading-mask').remove(); $link.closest('.product').find('.loader-container').hide(); if ($link.closest('li.outofstock').length) { return; } $('.after-loading-success-message .product-name').text($link.closest('.product').find('.woocommerce-loop-product__title').text()); $('.after-loading-success-message .msg-box img').remove(); if ($link.closest('.product').find('.product-image img').length) { $link.closest('.product').find('.product-image img').eq(0).clone().appendTo('.after-loading-success-message .msg-box'); } $('.after-loading-success-message').eq(0).stop().show(); if (porto_product_add_cart_timer) { clearTimeout(porto_product_add_cart_timer); } porto_product_add_cart_timer = setTimeout(function() { $('.after-loading-success-message').eq(0).hide(); }, 4000); $('.continue_shopping').click(function(){ $('.after-loading-success-message').eq(0).fadeOut(200); }); } }); }); $(document).on("click", ".variations_form .variations .filter-item-list .filter-color, .variations_form .variations .filter-item-list .filter-item", function(e) { e.preventDefault(); if ($(this).closest("ul").next("select").length < 1 || $(this).hasClass('disabled')) { return; } var value = unescape($(this).data("value")), selector = $(this).closest("ul").next("select"); if ($(this).closest("li").hasClass("active")) { $(this).closest("li").removeClass("active"); selector.children("option:selected").removeAttr("selected"); selector.val(''); } else { $(this).closest("ul").children("li").removeClass("active"); $(this).closest("li").addClass("active"); selector.children("option:selected").removeAttr("selected"); selector.children("option[value='" + value + "']").attr("selected", "selected"); selector.val(selector.children("option[value='" + value + "']").val()); } selector.change(); }); $(document).on('wc_variation_form', '.variations_form', function() { $(this).addClass('vf_init'); if ($(this).find('.filter-item-list').length < 1) { return; } $(this).find('.variations select').trigger('focusin'); }); $(document).on('updated_wc_div', function() { $('.woocommerce-cart-form .porto-lazyload').themePluginLazyLoad(); }); $(document).on('found_variation reset_data', '.variations_form', function(e, args) { // attribute description if ($(this).find('.product-attr-description').length) { if (typeof args == 'undefined') { $(this).find('.product-attr-description').removeClass('active'); } else { $(this).find('.product-attr-description').addClass('active'); $(this).find('.product-attr-description .attr-desc').removeClass('active'); $(this).find('.product-attr-description .attr-desc[data-attrid="' + $(this).find('.variations select').val() + '"]').addClass('active'); } } if ($(this).find(".filter-item-list").length < 1) { return; } $(this).find(".filter-item-list").each(function() { if ($(this).next("select").length < 1) { return; } var selector = $(this).next("select"), //html = '', $list = $(this); $list.find('li.active').removeClass('active'); $list.find('.filter-color, .filter-item').removeClass('enabled').removeClass('disabled'); selector.children("option").each(function() { /*var isColor = typeof $(this).data('color') != 'undefined' ? true : false, isImage = typeof $(this).data('image') != 'undefined' ? true : false, spanClass = isColor ? "filter-color" : ( isImage ? "filter-item filter-image" : "filter-item" );*/ if (!$(this).val()) { return; } $list.find('[data-value="' + $(this).val() + '"]').addClass('enabled'); if ($(this).val() == selector.val()) { $list.find('[data-value="' + $(this).val() + '"]').parent().addClass('active'); } /*html += '<li'; if ($(this).val() == selector.val()) { html += ' class="active"'; } html += '><a href="#" data-value="'+ escape( $(this).val() ) +'" class="' + spanClass + '"'; if (isColor) { html += ' style="background-color: #' + escape( $(this).data('color').replace('#','') ) + '"'; } if (isImage) { html += ' style="background-image:url(' + $(this).data('image') + ')"'; } html += '>'; if (!isColor) { html += $(this).text(); } html += '</a></li>';*/ }); $list.find('.filter-color:not(.enabled), .filter-item:not(.enabled)').addClass('disabled'); //$(this).html(html); }); }); // daily sale $(document).on('found_variation reset_data', '.variations_form', function(e, obj) { var $timer = $(this).closest('.product').find('.sale-product-daily-deal.for-some-variations'); if (!$timer.length) { return; } if (obj && obj.is_purchasable && typeof obj.porto_date_on_sale_to != 'undefined' && obj.porto_date_on_sale_to) { var saleTimer = $timer.find('.porto_countdown-dateAndTime'); if (saleTimer.data('terminal-date') != obj.porto_date_on_sale_to) { var newDate = new Date(obj.porto_date_on_sale_to); saleTimer.porto_countdown('option', {until: newDate}); saleTimer.data('terminal-date', obj.porto_date_on_sale_to); } $timer.slideDown(); } else { if ($timer.is(':hidden')) { $timer.hide(); } else { $timer.slideUp(); } } }); $('body').on('click', '.product-attr-description > a', function(e) { e.preventDefault(); $(this).next().stop().slideToggle(400); }); }); }).apply(this, [window.theme, jQuery]);
CSS代码:
.variations tr td { padding-top: 2px; } .filter-item-list { padding: 0; list-style: none; margin-bottom: 0; } .filter-item-list, .single_variation_wrap .variations_button, .single-product form.cart:not(.variations_form) { display: -ms-flexbox; display: flex; -ms-flex-wrap: wrap; flex-wrap: wrap; -ms-flex-align: center; align-items: center; } li, .porto-u-sub-heading, .porto-sicon-description { line-height: 24px; } .woocommerce-widget-layered-nav-list a:not(.filter-color), .filter-item-list .filter-item { padding: 0; border: 1px solid #e9e9e9; display: block; line-height: 24px; padding: 0 8px; margin: 3px 6px 3px 0; min-width: 32px; text-align: center; font-size: 11px; color: inherit; text-decoration: none; } .variations tr:last-child select { margin-bottom: 0; } ul.filter-item-list{ margin:0; } a.reset_variations{ margin-left: 0; } .single-product div.product table.variations .filter-item-list+select { visibility: hidden; width: 0; height: 0; overflow: hidden; margin: 0; padding: 0; float: right; border: none; -webkit-appearance: none; -moz-appearance: none; -ms-appearance: none; } .variations select { display: block; height: 2.625rem; font-size: .8571em; font-weight: 600; text-transform: uppercase; box-shadow: none; width: 100%; } .single-product div.product table.variations td.label{ display: table-cell; padding-right: 1em; } .variations .label { font-size: 1em; color: inherit; text-align: left; padding-left: 0; } .single-product .variations .label label { line-height: 32px; } .single-product .variations .label label { font-size: .8571em; text-transform: uppercase; line-height: 42px; white-space: nowrap; padding: 0; margin: 0; } .variations tr td label { padding-top: 10px; } .single-product .variations .label label:after { content: ":"; } .variations .reset_variations { display: inline-block; line-height: 1; padding: .4375rem .5rem; margin-top: .7em; background: #f4f4f4; color: inherit; font-size: .625rem; text-transform: uppercase; text-decoration: none; } .variations tr td { padding-top: 2px; } .label { display: inline; padding: 0.2em 0.6em 0.3em; font-size: 75%; font-weight: bold; line-height: 1; color: #fff; text-align: center; white-space: nowrap; vertical-align: baseline; border-radius: 3px; } .single-product div.product table.variations td.value { display: table-cell; } .variations tr td { padding-top: 2px; } .woocommerce-widget-layered-nav-list .chosen a:not(.filter-color), .filter-item-list .active .filter-item { background-color: #111111; color: #fff; border-color: #111111; }
暂无评论...