Converta a página do produto Dawn como tema de estreia com controle deslizante de produto

Convert Dawn Product Page Like Debut Theme  with Product Slider

Nota: Se você tiver o tema Dawn versão 2.5 e superior, este código não funcionará. Para código atualizado, verifique isto .

Você estreia o controle deslizante de produto do tema? Crie uma página de produto semelhante ao tema Debut.

Tenho trabalhado no controle deslizante de produto do tema Dawn e encontrei alguns problemas com ele. Uma coisa é que o contador numérico não faz sentido. Minha maneira de criar um controle deslizante de produto no tema Dawn é copiar o tema Debut.

Tenha uma página de produto de estreia em seu tema Dawn com botões de opção funcionais, zoom e controle deslizante de produto.

NOTA: Você precisa fazer login antes de ver o código.

Siga as instruções abaixo.

1. Vá para sua loja online > Temas > Ações > Editar código

2. Vá para a pasta Seção e abra main-product.liquid

3. Para simplificar as coisas, substituiremos o main-product.liquid

4. Vá para a pasta da seção e abra main-product.liquid."

5. Exclua o código dentro do arquivo, cole o código abaixo

{% comment %} theme-check-disable TemplateLength {% endcomment %}
{{ 'section-main-product.css' | asset_url | stylesheet_tag }}
{{ 'component-accordion.css' | asset_url | stylesheet_tag }}
{{ 'component-price.css' | asset_url | stylesheet_tag }}
{{ 'component-rte.css' | asset_url | stylesheet_tag }}
{{ 'product-slider.css' | asset_url | stylesheet_tag }}
{{ 'component-rating.css' | asset_url | stylesheet_tag }}
{{ 'component-loading-overlay.css' | asset_url | stylesheet_tag }}

<link rel="stylesheet" href=" {{ 'component-deferred-media.css' | asset_url }} " media="print" onload="this.media='all'">

<script src=" {{ 'product-form.js' | asset_url }} " defer="defer"></script>
<roteiro>
função novaImagemGrande(x) {
deixe clickedImage = x.dataset.thumbId;
const newImage = document.querySelector(`[data-media-id="${clickedImage}"]`);
const parentData = newImage.parentElement;

parentData.prepend(newImage);
newImage.style.display = "bloquear";

document.querySelectorAll('.slide-image')
.forEach(thumb => polegar. classList.remove('active-thumb'));
const sliderComp = document.querySelector("componente deslizante");
document.querySelector(`[data-thumb-id="${clickedImage}"] > img`).classList.add('active-thumb');
ampliação();
}
window.setTimeout(() => {zoom()});
função zoom() {
const mediaSmall = window.matchMedia( '(largura mínima: 400px)');
const imagemZoom = document.querySelector('#imagemgrande');
const zoomItem = document.querySelector("#imagemgrande > li:nth-child(1)")
imageZoom.addEventListener("mouseout", function() {
zoomItem.style.transform = 'escala(1)';
});
if (mediaSmall.matches) {
imageZoom.addEventListener("mouseover", function() {
zoomItem.style.transform = 'escala(1.8)';
});
imageZoom.addEventListener("mousemove", function(e) {
const itemWidth = zoomItem.getBoundingClientRect().width;
const itemLeft = zoomItem.getBoundingClientRect().left;
const itemHt = zoomItem.getBoundingClientRect().height;
const itemTop = zoomItem.getBoundingClientRect().top + window.scrollY;
const traduzX = Math.round((e.pageX - itemLeft) / itemWidth * 100);
const traduzY = Math.round((e.pageY - itemTop) / itemHt * 100);
zoomItem.style.transformOrigin = `${translateX}% ${translateY}%`;
});
}
}
</script>
{%- assign first_3d_model = product.media | where: "media_type", "model" | first -%}
{%- if first_3d_model -%}
{{ 'component-product-model.css' | asset_url | stylesheet_tag }}
<link id="ModelViewerStyle" rel="stylesheet" href="https://cdn.shopify.com/shopifycloud/model-viewer-ui/assets/v1.0/model-viewer-ui.css" media=" imprimir" onload="this.media='all'">
<link id="ModelViewerOverride" rel="stylesheet" href=" {{ 'component-model-viewer-ui.css' | asset_url }} " media="print" onload="this.media='all'">
{%- endif -%}

<seção class="largura da página">
<div class="product grid grid--1-col {% if product.media.size > 0 %} grid--2-col-tablet {% else %} product--no-media {% endif %} " >
<div class="grid__item produto__media-wrapper">

<div class="slider-container" >
{{ section.id }} {{ "accessibility.skip_to_product_info" | t }} </a>
<ul class="imagemgrande" id="imagemgrande" data-scale="1.6">
{%- for media in product.media -%}
<li class="item de imagem grande produto__item de mídia grid__item slider__slide
{% if media.media_type != 'image' %} hide-modal {% endif %} "
data-media-id=" {{ section.id }} - {{ media.id }} "
data-background="zoom-imagem">
{% render 'product-thumbnail', media: media, position: forloop.index, loop: section.settings.enable_video_looping, modal_id: section.id, xr_button: true %}
</li>
{%- endfor -%}
</ul>
<slider-component class="slider-wrapper">
<ul class="product-slider-box slider" role="list">
{%- assign variant_images = product.images| where: 'attached_to_variant?', true | map: 'src' -%}
{%- for media in product.media -%}
<li class="product-slider slider__slide" onclick="newLargeImage(this)" data-thumb-id=" {{ section.id }} - {{ media.id }} "
{% if section.settings.hide_variants and variant_images contains media.src %}
estilo = "display: nenhum;"
{% endif %} >
{% if media.media_type == 'video' %}
<div class="video-btn" style="display: bloco" >
<span class="product__media-icon motion-reduce v-btn" aria-hidden="true">
{%- liquid
case media.media_type
when 'video' or 'external_video'
render 'icon-play'
when 'model'
render 'icon-3d-model'
else
render 'icon-zoom'
endcase
-%}
</span>
<img class="slide-image {% if forloop.first %} active-thumb {% endif %} "
src=" {{ media.preview_image | img_url: 'large' }} "
alt=" {{ media.alt}} "
{% if section.settings.square_image == true %} style="proporção de aspecto: 1;" {% endif %} >
</div>
{% else %}
<img class="slide-image {% if forloop.first %} active-thumb {% endif %} "
src=" {{ media.preview_image | img_url: 'large' }} "
alt=" {{ media.alt }} "
{% if section.settings.square_image == true %} style="proporção de aspecto: 1;" {% endif %} >
{% endif %}
</li>
{% endfor %}
</ul>
<div class="button-wrapper {% if product.media.size < 3 %} oculto {% endif %} " >
<button type="button" class="slider-button slider-button--prev maior-slider" name="anterior" aria-label=" {{ 'accessibility.previous_slide' | t }} "> {% render 'icon-caret' %} </button>
<button type="button" class="slider-button slider-button--next large-slider" name="next" aria-label=" {{ 'accessibility.next_slide' | t }} "> {% render 'icon-caret' %} </button>
</div>
</slider-component>
</div>

{%- if first_3d_model -%}
<botão
class="botão botão--produto de largura total__xr-button"
tipo = "botão"
aria-label=" {{ 'products.product.xr_button_label' | t }} "
dados-shopify-xr
data-shopify-model3d-id=" {{ first_3d_model.id }} "
data-shopify-title=" {{ product.title | escape }} "
dados-shopify-xr-oculto
>
{% render 'icon-3d-model' %}
{{ 'products.product.xr_button' | t }}
</button>
{%- endif -%}
</div>
<div class="product__info-wrapper grid__item">
<div id="ProductInfo- {{ section.id }} " class="product__info-container {% if section.settings.enable_sticky_info %} product__info-container--sticky {% endif %} ">
{%- assign product_form_id = 'product-form-' | append: section.id -%}

{%- for block in section.blocks -%}
{%- case block.type -%}
{%- when '@app' -%}
{% render block %}
{%- when 'text' -%}
<p class="product__text {% if block.settings.text_style == 'uppercase' %} legenda com espaçamento entre letras {% elsif block.settings.text_style == 'subtitle' %} subtítulo {% endif %} " {{ block.shopify_attributes }} >
{{- block.settings.text -}}
</p>
{%- when 'title' -%}
<h1 class="product__title" {{ block.shopify_attributes }} >
{{ product.title | escape }}
</h1>
{%- when 'price' -%}
<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--large' -%}
</div>
{%- if shop.taxes_included or shop.shipping_policy.body != blank -%}
<div class="produto__tax caption rte">
{%- if shop.taxes_included -%}
{{ 'products.product.include_taxes' | t }}
{%- endif -%}
{%- if shop.shipping_policy.body != blank -%}
{{ 'products.product.shipping_policy_html' | t: link: shop.shipping_policy.url }}
{%- endif -%}
</div>
{%- endif -%}
<div {{ block.shopify_attributes }} >
{%- form 'product', product, id: 'product-form-installment', class: 'installment caption-large' -%}
<input type="hidden" name="id" value=" {{ product.selected_or_first_available_variant.id }} ">
{{ form | payment_terms }}
{%- endform -%}
</div>
{%- when 'description' -%}
{%- if product.description != blank -%}
<div class="produto__descrição rte">
{{ product.description }}
</div>
{%- endif -%}
{%- when 'custom_liquid' -%}
{{ block.settings.custom_liquid }}
{%- when 'collapsible_tab' -%}
<div class="product__accordion acordeão" {{ block.shopify_attributes }} >
<detalhes id="Detalhes- {{ block.id }} - {{ section.id }} ">
<resumo>
<div class="summary__title">
{% render 'icon-accordion', icon: block.settings.icon %}
<h2 class="h4 acordeão__title">
{{ block.settings.heading | default: block.settings.page.title }}
</h2>
</div>
{% render 'icon-caret' %}
</resumo>
<div class="accordion__content rte" id="ProductAccordion- {{ block.id }} - {{ section.id }} ">
{{ block.settings.content }}
{{ block.settings.page.content }}
</div>
</detalhes>
</div>
{%- when 'quantity_selector' -%}
<div class="product-form__input product-form__quantity" {{ block.shopify_attributes }} >
<label class="form__label" for="Quantidade- {{ section.id }} ">
{{ 'products.product.quantity.label' | t }}
</label>

<quantidade-input class="quantidade">
<button class="quantity__button no-js-hidden" name="menos" type="button">
<span class="visually-hidden"> {{ 'products.product.quantity.decrease' | t: product: product.title | escape }} </span>
{% render 'icon-minus' %}
</button>
<input class="quantidade__input"
tipo = "número"
nome = "quantidade"
id="Quantidade- {{ section.id }} "
min="1"
valor = "1"
formulário=" {{ product_form_id }} "
>
<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>
</quantidade-entrada>
</div>
{%- when 'popup' -%}
<modal-opener class="product-popup-modal__opener no-js-hidden" data-modal="#PopupModal- {{ block.id }} " {{ block.shopify_attributes }} >
<button id="ProductPopup- {{ block.id }} " class="product-popup-modal__button link" type="button" aria-haspopup="dialog"> {{ block.settings.text | default: block.settings.page.title }} </button>
</modal-opener>
{{ block.settings.page.url }} {{ block.settings.text }} </a>
{%- when 'share' -%}
<share-button id="Compartilhar- {{ section.id }} " class="share-button" {{ block.shopify_attributes }} >
<button class="share-button__button oculto">
{% render 'icon-share' %}
{{ block.settings.share_label | escape }}
</button>
<detalhes id="Detalhes- {{ block.id }} - {{ section.id }} ">
<summary class="share-button__button">
{% render 'icon-share' %}
{{ block.settings.share_label | escape }}
</resumo>
<div id="Product-share- {{ section.id }} " class="share-button__fallback motion-reduce">
<div class="campo">
<span id="ShareMessage- {{ section.id }} " class="share-button__message oculto" role="status">
</span>
<tipo de entrada = "texto"
class="campo__input"
id="url"
value=" {{ product.selected_variant.url | default: product.url | prepend: shop.url }} "
placeholder=" {{ 'general.share.share_url' | t }} "
onclick="this.select();"
somente leitura
>
<label class="field__label" for="url"> {{ 'general.share.share_url' | t }} </label>
</div>
<button class="share-button__close oculto no-js-hidden">
{% render 'icon-close' %}
<span class="visually-hidden"> {{ 'general.share.close' | t }} </span>
</button>
<button class="share-button__copy no-js-hidden">
{% render 'icon-clipboard' %}
<span class="visually-hidden"> {{ 'general.share.copy_to_clipboard' | t }} </span>
</button>
</div>
</detalhes>
</botão de compartilhamento>
<script src=" {{ 'share.js' | asset_url }} " defer="defer"></script>
{%- when 'variant_picker' -%}
{%- unless product.has_only_default_variant -%}
{%- if block.settings.picker_type == 'button' -%}
<variant-radios class="no-js-hidden" data-section=" {{ section.id }} " data-url=" {{ product.url }} " {{ block.shopify_attributes }} >
{%- for option in product.options_with_values -%}
<fieldset class="js produto-form__input">
<legend class="form__label"> {{ option.name }} </legend>
{%- for value in option.values -%}
<input type="radio" id=" {{ section.id }} - {{ option.position }} - {{ forloop.index0 }} "
nome=" {{ option.name }} "
valor=" {{ value | escape }} "
formulário=" {{ product_form_id }} "
{% if option.selected_value == value %} verificado {% endif %}
>
<label for=" {{ section.id }} - {{ option.position }} - {{ forloop.index0 }} ">
{{ value }}
</label>
{%- endfor -%}
</fieldset>
{%- endfor -%}
<script type="aplicativo/json">
{{ product.variants | json }}
</script>
</variant-radios>
{%- else -%}
<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="produto-form__input produto-form__input--dropdown">
<label class="form__label" for="Option- {{ section.id }} - {{ forloop.index0 }} ">
{{ option.name }}
</label>
<div class="selecionar">
<select id="Option- {{ section.id }} - {{ forloop.index0 }} "
class="selecionar__selecionar"
nome = "opções[ {{ option.name | escape }} ]"
formulário=" {{ product_form_id }} "
>
{%- for value in option.values -%}
<option value=" {{ value | escape }} " {% if option.selected_value == value %} selecionado="selecionado" {% endif %} >
{{ value }}
</opção>
{%- endfor -%}
</selecionar>
{% render 'icon-caret' %}
</div>
</div>
{%- endfor -%}

<script type="aplicativo/json">
{{ product.variants | json }}
</script>
</variant-selects>
{%- endif -%}
{%- endunless -%}

<noscript class="product-form__noscript-wrapper- {{ section.id }} ">
<div class="product-form__input {% if product.has_only_default_variant %} oculto {% endif %} ">
<label class="form__label" for="Variantes- {{ section.id }} "> {{ 'products.product.product_variants' | t }} </label>
<div class="selecionar">
<select name="id" id="Variantes- {{ section.id }} " class="select__select" form=" {{ product_form_id }} ">
{%- for variant in product.variants -%}
<opção
{% if variant == product.selected_or_first_available_variant %} selecionado="selecionado" {% endif %}
{% if variant.available == false %} desabilitado {% endif %}
valor=" {{ variant.id }} "
>
{{ variant.title }}
{%- if variant.available == false %} - {{ 'products.product.sold_out' | t }} {% endif %}
- {{ variant.price | money | strip_html }}
</opção>
{%- endfor -%}
</selecionar>
{% render 'icon-caret' %}
</div>
</div>
</noscript>
{%- when 'buy_buttons' -%}
<div {{ block.shopify_attributes }} >
<formulário-produto class="formulário-produto">
<div class="product-form__error-message-wrapper" role="alert" oculto>
<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" acidente vascular cerebral="branco" acidente vascular cerebral-width="2"/>
<circle cx="6.5" cy="6.5" r="5.5" fill="#EB001B" acidente vascular cerebral="#EB001B" acidente vascular cerebral-width="0.7"/>
<caminho d = "M5.87413 3.52832L5.97439 7.57216H7.02713L7.12739 3.52832H5.87413ZM6.50076 9.66091C6.88091 9.66091 7.18169 9.37267 7.18 169 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="branco"/>
<caminho 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 0,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,431 37 5,46982 9,00504C5,46982 9,57872 5,94031 10,0109 6,50076 10,0109Z" fill="branco" acidente vascular cerebral="#EB001B" largura de curso="0,7 "/>
</svg>
<span class="product-form__error-message"></span>
</div>

{%- form 'product', product, id: product_form_id, class: 'form', novalidate: 'novalidate', data-type: 'add-to-cart-form' -%}
<input type="hidden" name="id" value=" {{ product.selected_or_first_available_variant.id }} " desativado>
<div class="produto-form__buttons">
<botão
digite = "enviar"
nome = "adicionar"
class="product-form__submit button button--largura total {% if block.settings.show_dynamic_checkout and product.selling_plan_groups == empty %} botão--secundário {% else %} botão--primário {% endif %} "
{% if product.selected_or_first_available_variant.available == false %} desativado {% 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 oculto">
<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>
{%- if block.settings.show_dynamic_checkout -%}
{{ form | payment_button }}
{%- endif -%}
</div>
{%- endform -%}
</formulário-produto>

{{ 'component-pickup-availability.css' | asset_url | stylesheet_tag }}

{%- assign pick_up_availabilities = product.selected_or_first_available_variant.store_availabilities | where: 'pick_up_enabled', true -%}

<pickup-availability class="produto__pickup-availabilities no-js-hidden"
{% if product.selected_or_first_available_variant.available and pick_up_availabilities.size > 0 %} disponível {% endif %}
data-root-url=" {{ routes.root_url }} "
data-variant-id=" {{ product.selected_or_first_available_variant.id }} "
data-has-only-default-variant=" {{ product.has_only_default_variant }} "
>
<modelo>
<pickup-availability-preview class="pickup-availability-preview">
{% render 'icon-unavailable' %}
<div class="pickup-availability-info">
<p class="caption-large"> {{ 'products.product.pickup_availability.unavailable' | t }} </p>
<button class="link do botão de disponibilidade de coleta link--texto sublinhado-link"> {{ 'products.product.pickup_availability.refresh' | t }} </button>
</div>
</pickup-availability-preview>
</template>
</pickup-availability>
</div>

<script src=" {{ 'pickup-availability.js' | asset_url }} " defer="defer"></script>
{%- when 'rating' -%}
{%- if product.metafields.reviews.rating.value != blank -%}
{% liquid
assign rating_decimal = 0
assign decimal = product.metafields.reviews.rating.value.rating | modulo: 1
if decimal >= 0.3 and decimal <= 0.7
assign rating_decimal = 0.5
elsif decimal > 0.7
assign rating_decimal = 1
endif
%}
<div class="rating" role="img" aria-label=" {{ 'accessibility.star_reviews_info' | t: rating_value: product.metafields.reviews.rating.value, rating_max: product.metafields.reviews.rating.value.scale_max }} ">
<span aria-hidden="true" class="rating-star color-icon- {{ settings.accent_icons }} " style="--rating: {{ product.metafields.reviews.rating.value.rating | floor }} ; --rating-max: {{ product.metafields.reviews.rating.value.scale_max }} ; --rating-decimal: {{ rating_decimal }} ;"></span>
</div>
<p class="rating-text caption">
<span aria-hidden="true"> {{ product.metafields.reviews.rating.value }} / {{ product.metafields.reviews.rating.value.scale_max }} </span>
</p>
<p class="rating-count caption">
<span aria-hidden="true">( {{ product.metafields.reviews.rating_count }} )</span>
<span class="visually-hidden"> {{ product.metafields.reviews.rating_count }} {{ "accessibility.total_reviews" | t }} </span>
</p>
{%- endif -%}
{%- endcase -%}
{%- endfor -%}
</div>
</div>
</div>

<produto-modal id="ProductModal- {{ section.id }} " class="produto-media-modal media-modal">
<div class="product-media-modal__dialog" role="dialog" aria-label=" {{ 'products.modal.label' | t }} " aria-modal="true" tabindex="-1">
<button id="ModalClose- {{ section.id }} " type="button" class="product-media-modal__toggle" aria-label=" {{ 'accessibility.close' | t }} "> {% render 'icon-close' %} </button>

<div class="product-media-modal__content" role="document" aria-label=" {{ 'products.modal.label' | t }} " tabindex="0">
{%- liquid
if product.selected_or_first_available_variant.featured_media != null
assign media = product.selected_or_first_available_variant.featured_media
render 'product-media', media: media, loop: section.settings.enable_video_looping, variant_image: section.settings.hide_variants
endif
-%}

{%- for media in product.media -%}
{%- liquid
if section.settings.hide_variants and variant_images contains media.src
assign variant_image = true
else
assign variant_image = false
endif

unless media.id == product.selected_or_first_available_variant.featured_media.id
render 'product-media', media: media, loop: section.settings.enable_video_looping, variant_image: variant_image
endunless
-%}
{%- endfor -%}
</div>
</div>
</produto-modal>

{% assign popups = section.blocks | where: "type", "popup" %}
{%- for block in popups -%}
<modal-dialog id="PopupModal- {{ block.id }} " class="product-popup-modal" {{ block.shopify_attributes }} >
<div role="dialog" aria-label=" {{ block.settings.text }} " aria-modal="true" class="product-popup-modal__content" tabindex="-1">
<button id="ModalClose- {{ block.id }} " type="button" class="product-popup-modal__toggle" aria-label=" {{ 'accessibility.close' | t }} "> {% render 'icon-close' %} </button>
<div class="produto-popup-modal__content-info">
<h1 class="h2"> {{ block.settings.page.title }} </h1>
{{ block.settings.page.content }}
</div>
</div>
</modal-dialog>
{%- endfor -%}
</seção>

{% javascript %}
classe ProductModal estende ModalDialog {
construtor() {
super();
}

esconder() {
super.ocultar();
}

mostrar(abridor) {
super.show(abridor);
this.showActiveMedia();
}

mostrarActiveMedia() {
this.querySelectorAll(`[data-media-id]:not([data-media-id="${this.openedBy.getAttribute("data-media-id")}"])`).forEach((elemento ) => {
element.classList.remove('ativo');
}
)
const activeMedia = this.querySelector(`[data-media-id="${this.openedBy.getAttribute("data-media-id")}"]`);
const activeMediaTemplate = activeMedia.querySelector('template');
const activeMediaContent = activeMediaTemplate? activeMediaTemplate.content: nulo;
activeMedia.classList.add('ativo');
activeMedia.scrollIntoView();

const container = this.querySelector('[role="document"]');
container.scrollLeft = (activeMedia.width - container.clientWidth) / 2;

if (activeMedia.nodeName == 'DEFERRED-MEDIA' && activeMediaContent && activeMediaContent.querySelector('.js-youtube'))
activeMedia.loadContent();
}
}

customElements.define('produto-modal', ProductModal);
{% endjavascript %}

<roteiro>
document.addEventListener('DOMContentLoaded', function() {
função éIE() {
const ua = window.navigator.userAgent;
const msie = ua.indexOf('MSIE ');
const tridente = ua.indexOf('Trident/');

return (msie > 0 || tridente > 0);
}

se (!isIE()) retornar;
const hiddenInput = document.querySelector('# {{ product_form_id }} input[name="id"]');
const noScriptInputWrapper = document.createElement('div');
const varianteSwitcher = document.querySelector('variant-radios[data-section=" {{ section.id }} "]') || document.querySelector('variant-selects[data-section=" {{ section.id }} "]');
noScriptInputWrapper.innerHTML = document.querySelector('.product-form__noscript-wrapper- {{ section.id }} ').textContent;
varianteSwitcher.outerHTML = noScriptInputWrapper.outerHTML;

document.querySelector('#Variantes- {{ section.id }} ').addEventListener('mudança', função(evento) {
HiddenInput.value = event.currentTarget.value;
});
});
</script>

{%- if first_3d_model -%}
<script type="application/json" id="ProductJSON- {{ product.id }} ">
{{ product.media | where: 'media_type', 'model' | json }}
</script>

<script src=" {{ 'product-model.js' | asset_url }} " defer></script>
{%- endif -%}

{%- liquid
if product.selected_or_first_available_variant.featured_media
assign seo_media = product.selected_or_first_available_variant.featured_media
outro
atribuir seo_media = produto.featured_media
fim se
-%}

<script type="application/ld+json">
{
"@contexto": "http://schema.org/",
"@type": "Produto",
"nome": {{ product.title | json }} ,
"url": {{ shop.url | append: product.url | json }} ,
{% if seo_media -%}
{%- assign media_size = seo_media.preview_image.width | append: 'x' -%}
"imagem": [
{{ seo_media | img_url: media_size | prepend: "https:" | json }}
],
{%- endif %}
"descrição": {{ product.description | strip_html | json }} ,
{% if product.selected_or_first_available_variant.sku != blank -%}
"sku": {{ product.selected_or_first_available_variant.sku | json }} ,
{%- endif %}
"marca": {
"@type": "Coisa",
"nome": {{ product.vendor | json }}
},
"ofertas": [
{%- for variant in product.variants -%}
{
"@type" : "Oferta",
{%- if variant.sku != blank -%}
"sku": {{ variant.sku | json }} ,
{%- endif -%}
"availability": "http://schema.org/ {% if variant.available %} InStock {% else %} OutOfStock {% endif %} ",
"preço": {{ variant.price | divided_by: 100.00 | json }} ,
"preçoMoeda": {{ cart.currency.iso_code | json }} ,
"url": {{ shop.url | append: variant.url | json }}
} {% unless forloop.last %} , {% endunless %}
{%- endfor -%}
]
}
</script>

{% schema %}
{
"nome": "t:seções.produto principal.nome",
"tag": "seção",
"class": "seção espaçada da seção do produto",
"blocos": [
{
"tipo": "@aplicativo"
},
{
"tipo": "texto",
"nome": "t:seções.produto principal.blocos.texto.nome",
"configurações": [
{
"tipo": "texto",
"id": "texto",
"default": "Bloco de texto",
"label": "t:sections.main-product.blocks.text.settings.text.label"
},
{
"tipo": "selecionar",
"id": "estilo_texto",
"opções": [
{
"valor": "corpo",
"label": "t:sections.main-product.blocks.text.settings.text_style.options__1.label"
},
{
"valor": "legenda",
"label": "t:sections.main-product.blocks.text.settings.text_style.options__2.label"
},
{
"valor": "maiúsculas",
"label": "t:sections.main-product.blocks.text.settings.text_style.options__3.label"
}
],
"padrão": "corpo",
"label": "t:sections.main-product.blocks.text.settings.text_style.label"
}
]
},
{
"tipo": "título",
"nome": "t:seções.produto principal.blocos.título.nome",
"limite": 1
},
{
"tipo": "preço",
"nome": "t:seções.produto principal.blocos.preço.nome",
"limite": 1
},
{
"tipo": "seletor_quantidade",
"nome": "t:seções.produto principal.blocks.quantity_selector.name",
"limite": 1
},
{
"tipo": "variant_picker",
"nome": "t:sections.main-product.blocks.variant_picker.name",
"limite": 1,
"configurações": [
{
"tipo": "selecionar",
"id": "picker_type",
"opções": [
{
"valor": "lista suspensa",
"label": "t:sections.main-product.blocks.variant_picker.settings.picker_type.options__1.label"
},
{
"valor": "botão",
"label": "t:sections.main-product.blocks.variant_picker.settings.picker_type.options__2.label"
}
],
"padrão": "botão",
"label": "t:sections.main-product.blocks.variant_picker.settings.picker_type.label"
}
]
},
{
"type": "buy_buttons",
"nome": "t:seções.produto principal.blocks.buy_buttons.name",
"limite": 1,
"configurações": [
{
"tipo": "caixa de seleção",
"id": "show_dynamic_checkout",
"padrão": verdadeiro,
"label": "t:sections.main-product.blocks.buy_buttons.settings.show_dynamic_checkout.label",
"info": "t:sections.main-product.blocks.buy_buttons.settings.show_dynamic_checkout.info"
}
]
},
{
"tipo": "descrição",
"nome": "t:seções.produto principal.blocos.descrição.nome",
"limite": 1
},
{
"tipo": "compartilhar",
"nome": "t:seções.produto principal.blocks.share.name",
"limite": 1,
"configurações": [
{
"tipo": "texto",
"id": "share_label",
"label": "t:sections.main-product.blocks.share.settings.text.label",
"default": "Compartilhar"
},
{
"tipo": "parágrafo",
"content": "t:sections.main-product.blocks.share.settings.featured_image_info.content"
},
{
"tipo": "parágrafo",
"content": "t:sections.main-product.blocks.share.settings.title_info.content"
}
]
},
{
"tipo": "custom_liquid",
"nome": "t:sections.main-product.blocks.custom_liquid.name",
"configurações": [
{
"tipo": "líquido",
"id": "custom_liquid",
"label": "t:sections.main-product.blocks.custom_liquid.settings.custom_liquid.label",
"info": "t:sections.main-product.blocks.custom_liquid.settings.custom_liquid.info"
}
]
},
{
"tipo": "tab_collapsível",
"nome": "t:sections.main-product.blocks.collapsible_tab.name",
"configurações": [
{
"tipo": "texto",
"id": "título",
"default": "Guia recolhível",
"info": "t:sections.main-product.blocks.collapsible_tab.settings.heading.info",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.heading.label"
},
{
"tipo": "texto rico",
"id": "conteúdo",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.content.label"
},
{
"tipo": "página",
"id": "página",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.page.label"
},
{
"tipo": "selecionar",
"id": "ícone",
"opções": [
{
"valor": "nenhum",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__1.label"
},
{
"valor": "caixa",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__2.label"
},
{
"valor": "chat_bubble",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__3.label"
},
{
"valor": "marca_de_verificação",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__4.label"
},
{
"valor": "secador",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__5.label"
},
{
"valor": "olho",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__6.label"
},
{
"valor": "coração",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__7.label"
},
{
"valor": "ferro",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__8.label"
},
{
"valor": "folha",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__9.label"
},
{
"valor": "couro",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__10.label"
},
{
"valor": "bloqueio",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__11.label"
},
{
"valor": "map_pin",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__12.label"
},
{
"valor": "calças",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__13.label"
},
{
"valor": "avião",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__14.label"
},
{
"valor": "etiqueta_preço",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__15.label"
},
{
"valor": "ponto de interrogação",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__16.label"
},
{
"valor": "retorno",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__17.label"
},
{
"valor": "régua",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__18.label"
},
{
"valor": "camisa",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__19.label"
},
{
"valor": "sapato",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__20.label"
},
{
"valor": "silhueta",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__21.label"
},
{
"valor": "estrela",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__22.label"
},
{
"valor": "caminhão",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__23.label"
},
{
"valor": "lavagem",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__24.label"
}
],
"padrão": "marca_de_verificação",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.label"
}
]
},
{
"tipo": "pop-up",
"nome": "t:seções.produto principal.blocks.popup.nome",
"configurações": [
{
"tipo": "texto",
"id": "texto",
"default": "Texto do link pop-up",
"label": "t:sections.main-product.blocks.popup.settings.link_label.label"
},
{
"id": "página",
"tipo": "página",
"label": "t:sections.main-product.blocks.popup.settings.page.label"
}
]
},
{
"tipo": "classificação",
"nome": "t:seções.produto principal.blocks.rating.nome",
"limite": 1,
"configurações": [
{
"tipo": "parágrafo",
"content": "t:sections.main-product.blocks.rating.settings.paragraph.content"
}
]
}
],
"configurações": [
{
"tipo": "caixa de seleção",
"id": "enable_sticky_info",
"padrão": verdadeiro,
"label": "t:sections.main-product.settings.enable_sticky_info.label"
},
{
"tipo": "cabeçalho",
"content": "t:sections.main-product.settings.header.content",
"info": "t:sections.main-product.settings.header.info"
},
{
"tipo": "caixa de seleção",
"id": "hide_variants",
"padrão": falso,
"label": "t:sections.main-product.settings.hide_variants.label"
},
{
"tipo": "caixa de seleção",
"id": "enable_video_looping",
"padrão": falso,
"label": "t:sections.main-product.settings.enable_video_looping.label"
},

{
"tipo": "caixa de seleção",
"id": "imagem_quadrada",
"padrão": falso,
"label": "Tornar as imagens em miniatura quadradas"
}
]
}
{% endschema %}

6. Em seguida, precisamos criar um novo arquivo de ativos. Vá para a pasta Ativos e clique em “Adicionar um novo ativo”. Certifique-se de que seja um arquivo CSS. Chame-o de "controle deslizante de produto"

7. Abra o arquivo e cole o código abaixo e clique em SALVAR

.slider-container {
margem: 0 automático;
largura: 90%;
exibição: flexível;
flex-flow: quebra de coluna;
alinhar itens: centro;
posição: relativa;
}

.imagem grande {
largura: 100%;
altura: 100%;
posição: relativa;
estouro: oculto;
}

.item de imagem grande {
largura máxima: 100%;
largura mínima: 50%;
altura máxima: 100%;
preenchimento: 0;
posição: relativa;
margem: 0 automático;
}

.xoomImage {
posição: absoluta;
superior: 0;
esquerda: 0;
}

.item de imagem grande:not(:primeiro-filho){
exibição: nenhum !importante;
}

você {
padding-inline-start: 0px! Importante;
}

componente deslizante {
posição: relativa;
exibição: bloco;
largura:100%;
}

.slider-wrapper {
exibição: flexível;
justificar-conteúdo: centro;
}

.slider__slide {
scroll-snap-align: iniciar;
flex-encolher: 0;
}

.product-slider-box {
flex-wrap: herdar;
estouro-x: automático;
scroll-snap-type: x obrigatório;
comportamento de rolagem: suave;
-webkit-overflow-scrolling: toque;
margem inferior: 1rem;
largura: 85%;
exibição: flexível;
índice z: 1;
}

.product-slider {
altura: 100%;
largura: 31,5%;
preenchimento: 10px;
display: bloco embutido;
}

.product-slider:not(:first-child){
margem esquerda: 1rem;
}

.slide-imagem {
largura: 100%;
ajuste ao objeto: capa;
}

.slider{
cor da barra de rolagem: rgb(var(--color-foreground)) rgba(var(--color-foreground), 0,04);
-ms-estilo overflow: nenhum;
largura da barra de rolagem: nenhuma;
}

.slider::-webkit-barra de rolagem {
altura: 0,4rem;
largura: 0,4rem;
Mostrar nenhum;
}

.no-js.slider {
-ms-estilo overflow: automático;
largura da barra de rolagem: automático;
}

.no-js .slider::-webkit-scrollbar {
exibição: inicial;
}

.slider::-webkit-scrollbar-thumb {
cor de fundo: rgb(var(--color-foreground));
raio da borda: 0,4rem;
borda: 0;
}

.slider::-webkit-scrollbar-track {
plano de fundo: rgba(var(--color-foreground), 0,04);
raio da borda: 0,4rem;
}


/*=== botões === */
.button-wrapper {
altura: 100%;
largura: 105%;
posição: absoluta;
exibição: flexível;
justificar-conteúdo: espaço entre;
alinhar itens: centro;
}

.slider-container::-webkit-scrollbar {
Mostrar nenhum;
}

.botões deslizantes {
exibição: flexível;
alinhar itens: centro;
justificar-conteúdo: centro;
}

.botão deslizante {
cor: rgba(var(--cor-foreground), 0,75);
fundo: transparente;
fronteira: nenhuma;
cursor: ponteiro;
largura: 44px;
altura: 44px;
}

.botão deslizante: não ([desativado]): passar o mouse {
cor: rgb(var(--color-foreground));
}

.botão deslizante .icon {
altura: 1,2rem;
}

.botão deslizante[desativado] .icon {
cor: rgba(var(--color-foreground), 0,3);
}

.botão deslizante--próximo .icon {
margem direita: -0,2rem;
transformar: girar (-90 graus) traduzirX (0,15rem);
}

.botão deslizante--anterior .icon {
margem esquerda: -0,2rem;
transformar: girar (90 graus) traduzirX (-0,15rem);
}

.botão deslizante--próximo:não([desativado]):hover .icon {
transformar: girar (-90 graus) traduzirX (0,15rem) escala (1,07);
}

.botão deslizante--prev:not([desativado]):hover .icon {
transformar: girar (90 graus) traduzirX (-0,15rem) escala (1,07);
}

/* botão de vídeo quando a imagem é do tipo vídeo */
.video-btn {
largura: 100%;
altura: 100%;
posição: relativa;
}

.v-btn {
topo: 2% !importante;
esquerda: 2% !importante;
}

.ativo-thumb {
borda: 3px branco sólido;
contorno: 2px preto sólido;
}

/* ==== códigos personalizados na edição da página do produto ==== */
@media screen e (largura mínima: 750px) {
.largura personalizada {
preenchimento: 0 10% !importante;
}
}

@media screen e (largura mínima: 990px) {
.produto__media-wrapper {
largura máxima: 50% !importante;
largura: calc(50% - 1rem/2);
}

.produto__info-wrapper {
preenchimento à esquerda: 5rem !importante;
largura máxima: 50% !importante;
largura: calc(50% - 1rem/2);
}
}

/* ocultar modal */
#large-image > li:nth-child(1) > modal-opener > span {
exibição: nenhum !importante;
}

#imagemgrande > li:nth-child(1) > abridor modal > botão {
exibição: nenhum !importante;
}

#imagemgrande > li > abridor modal > div {
preenchimento superior: 0 !importante;
}

#imagemgrande > li > abridor modal > div > img {
estouro: oculto;
posição: relativo! Importante;
}

8. Em seguida, precisamos ajustar o arquivo global.js na pasta Asset.

9. Ajustaremos o controle deslizante primeiro. Encontre o componente deslizante. Após " this.nextButton = this.querySelector('button[name="next"]');", cole o código abaixo. Veja a imagem e o vídeo para referência.

this.productSlider = this.querySelector('.product-slider-box');

O código deve ficar assim:

Imagem do controle deslizante do produto

10. Em seguida, precisamos encontrar e substituir a função onButtonClick(event) pelo código abaixo. Por favor, certifique-se de verificar o vídeo sobre isso para não excluir outras coisas.

onButtonClick(evento) {
event.preventDefault();

if (este.produtoSlider) {
const slideScrollPosition = event.currentTarget.name === 'próximo'? this.slider.scrollLeft + (this.slider.clientWidth): this.slider.scrollLeft - (this.slider.clientWidth);
this.slider.scrollTo({
esquerda: Math.floor(slideScrollPosition)
});

this.currSlide = Math.round(slideScrollPosition / this.slider.clientWidth);
if (this.currSlide === 0) {
this.prevButton.setAttribute('desativado', verdadeiro);
} outro {
this.prevButton.removeAttribute('desativado');
}
if (this.currSlide === this.totalPages / 3 ) {
this.nextButton.setAttribute('desativado', verdadeiro);
} outro {
this.nextButton.removeAttribute('desativado');
}
} outro {
const slideScrollPosition = event.currentTarget.name === 'próximo'? this.slider.scrollLeft + this.sliderLastItem.clientWidth: this.slider.scrollLeft - this.sliderLastItem.clientWidth;
this.slider.scrollTo({
esquerda: Math.floor(slideScrollPosition)
});
}
}

O código deve ficar assim:

Dawn estreia imagem da página do produto

12. Último. Encontre VariantSelects e adicione o código em updateMedia(), antes de "window.setTimeout(()". Veja a imagem abaixo e o vídeo para obter instruções.

const novoId = newMedia.dataset.mediaId;
const newThumb = document.querySelector(`[data-thumb-id="${newId}"]`);
const thumbLocate = newThumb["offsetLeft"];

document.querySelectorAll('.slide-image').forEach(thumb => polegar. classList.remove('active-thumb'));
document.querySelector(`[data-thumb-id="${newId}"] > img`).classList.add('active-thumb');
const sliderBox = document.querySelector(".product-slider-box");
sliderBox.scrollTo({esquerda: polegarLocate});
ampliação();

Dawn estreia a imagem do arquivo global.js da página do produto

É isso! Espero que não tenha sido muito difícil. Se sim, siga o vídeo. (",)

Atualização 08/11/21: Corrija o problema no Mozilla com a exibição da barra de rolagem. Acabei de excluir o CSS overflow no contêiner deslizante. Adicionado código para ocultar os botões sempre que as imagens variantes forem menores que três.

12 comentários

@NUNYA BIDNESS
Please be aware that this does not work on Dawn version 2.5 or higher as mentioned above. We have encountered that error before this due to the app installed. Please check your app that interfer with the cart.

Made4uo

This ruined add to cart option on my product page, now when i try to add to cart i get:
Required parameter missing or invalid: items
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!————-
DON’T USE IF YOU HAVE DAWN THEME
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!————-

nunya bidness

THIS IS A LIFE-SAVER!! So happy I came across your tutorial

Dym

If you replace the OnButtonClick coding with yours, the mobile menu button becomes disabled…i had to revert to the original….

Ed

For me the image doesn’t switch when I select a different color in the variant selector?

Daniël Staples

Please also make a video on how to make thumbnail sliders vertical on the side of product

muhammad asad ullah baig

your code on this page is not showing correctly, this tutorial is not useful like this.

kristof

Hi,
@KEVIN MCCULLAGH. Sorry, you need to explain more on your problem.
@SIMONE You might have done the steps wrong.
@Laura I think you need to elaborate also.

I hope you guys are doing well. Take note though, this code is good for a new DAWN theme. If you made alterations to the code or added an app, this code might not be the best for you, since those codes may alter the cart code and the code provided above is not made to accommodate with the changes you’ve made.

Made4Uo

Hi, when I “Add media from URL” it shows up on product slider with an image on the top, then with the video down below it directly. This doesn’t occur with the actual Debut theme. Do you have any idea how to resolve. It only happens when on mobile display also.

Kevin McCullagh

I have a problem with the variants when I select them the photo does not change by itself and also the arrows to change the photo do not work

Simone
1 2 Próximo »

Deixe um comentário