如何为 Shopify 创建粘性“添加到购物车”按钮?
我正在使用该应用程序,但它增加了我的网站加载时间。
所以我正在寻找粘性添加到购物车按钮的自定义代码
这个答案适用于基于 Dawn 的主题。 在 main-product.liquid 中添加一个新的部分设置
{
"type": "checkbox",
"id": "show_sticky_cart_button",
"label": "Show sticky add to cart button to the bottom of the page",
"default": true
},
将此代码添加到产品模式标签上方
{%- if section.settings.show_sticky_cart_button-%}
{% render 'product-sticky-form', product: product %}
{%- endif -%}
创建片段product-sticky-form.liquid并添加以下内容
{{ 'product-sticky-form.css' | asset_url | stylesheet_tag }}
<script src="{{ 'product-sticky-form.js' | asset_url }}" defer="defer"></script>
{%- assign sticky_product_form_id = 'product-form-' | append: section.id -%}
<sticky-product-form class="product--sticky-form product--sticky-form__inactive">
<product-form>
{%- form 'product', product, id: sticky_product_form_id, class: 'form', novalidate: 'novalidate', data-type: 'add-to-cart-form' -%}
<div class="product--sticky-form-info">
<input
type="hidden"
name="id"
value="{{ product.selected_or_first_available_variant.id }}"
disabled
>
<span class="h2">{{ product.title | escape }}</span>
<div class="no-js-hidden" id="price-{{ section.id }}" role="status" {{ block.shopify_attributes }}>
{%- render 'price', product: product, use_variant: true, show_badges: true, price_class: 'price--end' -%}
</div>
</div>
<div class="product--sticky-form__quantity product-form__quantity{% if settings.inputs_shadow_vertical_offset != 0 and settings.inputs_shadow_vertical_offset < 0 %} product-form__quantity-top{% endif %}">
<quantity-input class="quantity">
<button class="quantity__button no-js-hidden" name="minus" type="button">
<span class="visually-hidden">
{{- 'products.product.quantity.decrease' | t: product: product.title | escape -}}
</span>
{% render 'icon-minus' %}
</button>
<input
class="quantity__input"
type="number"
name="quantity"
id="Quantity-{{ section.id }}"
min="1"
value="1"
>
<button class="quantity__button no-js-hidden" name="plus" type="button">
<span class="visually-hidden">
{{- 'products.product.quantity.increase' | t: product: product.title | escape -}}
</span>
{% render 'icon-plus' %}
</button>
</quantity-input>
</div>
{%- unless product.has_only_default_variant -%}
<div class="product--sticky-form__variants">
<variant-selects
class="no-js-hidden"
data-section="{{ section.id }}"
data-url="{{ product.url }}"
{{ block.shopify_attributes }}
>
{%- for option in product.options_with_values -%}
<div class="product-form__input product-form__input--dropdown">
<div class="select">
<select
id="Option-{{ section.id }}-{{ forloop.index0 }}"
class="select__select"
name="options[{{ option.name | escape }}]"
form="{{ sticky_product_form_id }}"
>
{%- for value in option.values -%}
<option
value="{{ value | escape }}"
{% if option.selected_value == value %}
selected="selected"
{% endif %}
>
{{ value }}
</option>
{%- endfor -%}
</select>
{% render 'icon-caret' %}
</div>
</div>
{%- endfor -%}
<script type="application/json">
{{ product.variants | json }}
</script>
</variant-selects>
<noscript class="product-form__noscript-wrapper-{{ section.id }}">
<div class="product-form__input{% if product.has_only_default_variant %} hidden{% endif %}">
<div class="select">
<select
name="id"
id="Variants-{{ section.id }}"
class="select__select"
form="{{ sticky_product_form_id }}"
>
{%- for variant in product.variants -%}
<option
{% if variant == product.selected_or_first_available_variant %}
selected="selected"
{% endif %}
{% if variant.available == false %}
disabled
{% endif %}
value="{{ variant.id }}"
>
{{ variant.title }}
{%- if variant.available == false %} - {{ 'products.product.sold_out' | t }}{% endif %}
- {{ variant.price | money | strip_html }}
</option>
{%- endfor -%}
</select>
{% render 'icon-caret' %}
</div>
</div>
</noscript>
</div>
{% endunless %}
<div class="product--sticky-form__buttons">
<div class="product-form__error-message-wrapper" role="alert" hidden>
<svg
aria-hidden="true"
focusable="false"
role="presentation"
class="icon icon-error"
viewBox="0 0 13 13"
>
<circle cx="6.5" cy="6.50049" r="5.5" stroke="white" stroke-width="2"/>
<circle cx="6.5" cy="6.5" r="5.5" fill="#EB001B" stroke="#EB001B" stroke-width="0.7"/>
<path d="M5.87413 3.52832L5.97439 7.57216H7.02713L7.12739 3.52832H5.87413ZM6.50076 9.66091C6.88091 9.66091 7.18169 9.37267 7.18169 9.00504C7.18169 8.63742 6.88091 8.34917 6.50076 8.34917C6.12061 8.34917 5.81982 8.63742 5.81982 9.00504C5.81982 9.37267 6.12061 9.66091 6.50076 9.66091Z" fill="white"/>
<path d="M5.87413 3.17832H5.51535L5.52424 3.537L5.6245 7.58083L5.63296 7.92216H5.97439H7.02713H7.36856L7.37702 7.58083L7.47728 3.537L7.48617 3.17832H7.12739H5.87413ZM6.50076 10.0109C7.06121 10.0109 7.5317 9.57872 7.5317 9.00504C7.5317 8.43137 7.06121 7.99918 6.50076 7.99918C5.94031 7.99918 5.46982 8.43137 5.46982 9.00504C5.46982 9.57872 5.94031 10.0109 6.50076 10.0109Z" fill="white" stroke="#EB001B" stroke-width="0.7">
</svg>
<span class="product-form__error-message"></span>
</div>
<input
type="hidden"
name="id"
value="{{ product.selected_or_first_available_variant.id }}"
disabled
>
<div class="product-form__buttons">
<button
type="submit"
name="add"
class="product-form__submit button button--full-width button--primary"
{% if product.selected_or_first_available_variant.available == false %}
disabled
{% endif %}
>
<span>
{%- if product.selected_or_first_available_variant.available -%}
{{ 'products.product.add_to_cart' | t }}
{%- else -%}
{{ 'products.product.sold_out' | t }}
{%- endif -%}
</span>
<div class="loading-overlay__spinner hidden">
<svg
aria-hidden="true"
focusable="false"
role="presentation"
class="spinner"
viewBox="0 0 66 66"
xmlns="http://www.w3.org/2000/svg"
>
<circle class="path" fill="none" stroke-width="6" cx="33" cy="33" r="30"></circle>
</svg>
</div>
</button>
</div>
</div>
{%- endform -%}
</product-form>
</sticky-product-form>
创建资产product-sticky-form.js并添加以下内容
customElements.define('sticky-product-form', class StickyProductForm extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
this.productForm = document.querySelector('product-form');
this.productStickyForm = document.querySelector('.product--sticky-form');
this.productFormBounds = {};
this.onScrollHandler = this.onScroll.bind(this);
window.addEventListener('scroll', this.onScrollHandler, false);
this.createObserver();
}
disconnectedCallback() {
window.removeEventListener('scroll', this.onScrollHandler);
}
createObserver() {
let observer = new IntersectionObserver((entries, observer) => {
this.productFormBounds = entries[0].isIntersecting;
});
observer.observe(this.productForm);
}
onScroll() {
this.productFormBounds ? requestAnimationFrame(this.hide.bind(this)) : requestAnimationFrame(this.reveal.bind(this));
}
hide() {
if(this.productStickyForm.classList.contains('product--sticky-form__active')) {
this.productStickyForm.classList.remove('product--sticky-form__active');
this.productStickyForm.classList.add('product--sticky-form__inactive');
}
}
reveal() {
if(this.productStickyForm.classList.contains('product--sticky-form__inactive')) {
this.productStickyForm.classList.add('product--sticky-form__active');
this.productStickyForm.classList.remove('product--sticky-form__inactive');
}
}
});
创建资产product-sticky-form.css并添加以下内容
.product--sticky-form {
position: fixed;
bottom: 0;
left: 0;
width: 100vw;
z-index: 2;
background-color:rgba(243,243,243,0.5);
}
.product--sticky-form__inactive {
visibility: hidden;
opacity: 0;
transition: visibility 1.15s ease-out, opacity 1.15s ease-out;
}
.product--sticky-form__active {
visibility: visible;
opacity: 1;
transition: opacity 1.15s ease-out;
}
.product--sticky-form form{
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-evenly;
padding: 0 10px;
}
.product--sticky-form-info {
font-size: clamp(0.75rem, 2vw, calc(var(--font-heading-scale) * 4rem));
line-height: 1;
text-align: right;
padding-right: 10px;
}
.product--sticky-form .price {
margin-top: -5px;
}
.product--sticky-form__buttons {
width: 100%;
max-width: 438px;
height: 47px;
padding-left: 10px;
}
.product--sticky-form__variants,
.product--sticky-form__quantity {
display: none;
}
@media screen and (min-width: 990px) {
.product--sticky-form__variants,
.product--sticky-form__quantity {
height: 47px;
display: block;
}
}
.quick-add-modal .product--sticky-form {
display: none;
}