Я реализовал плагин flexslider на следующей странице: mylink
- Он отлично работает на рабочем столе, но не работает, когда я тестирую его на своем мобильном телефоне. Когда я выбираю вариант цвета на мобильном телефоне , соответствующий слайд не движется.
- Когда я использую chromedevtool, если страница загружается сразу с включенной панелью инструментов устройства, я не могу нажать кнопку или выбрать вариант, если я настаиваю, чтобы он даже вылетал. Я предполагаю, что обе проблемы связаны.
- В chromedevtool, если я загружаю страницу без включения и запуска панели инструментов устройства, она работает нормально.
Это должно быть связано с flexslider, потому что когда я удаляю код (в шаблоне продукта см. ниже), я больше не получаю ошибку в chromedevtool.
Я понятия не имею, где искать, я занимался этим уже несколько дней, Я просто sh кто-то может дать мне подсказку, где искать. Это как я инициализирую flexslider? Почему я не получаю проблему на мобильном телефоне, так как при изменении размера окна у меня нет проблем?
Мой код на shopify, я выкладываю его на всякий случай:
theme .liquid:
{% if
request.page_type == 'blog'
or request.page_type == 'collection'
or request.page_type == 'list-collections'
or request.page_type == 'search'
%}
{%- assign hide_footer = true -%}
{% endif %}
<!doctype html>
<html class="supports-no-js {% if hide_footer %} site-footer--hidden{% endif %}" lang="{{ shop.locale }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="theme-color" content="{{ settings.color_primary }}">
<link rel="canonical" href="{{ canonical_url }}">
{% if settings.favicon != blank %}
<link rel="shortcut icon" href="{{ settings.favicon | img_url: '32x32' }}" type="image/png">
{% endif %}
<title>
{{ page_title }}{% if current_tags %}{% assign meta_tags = current_tags | join: ', ' %} – {{ 'general.meta.tags' | t: tags: meta_tags }}{% endif %}{% if current_page != 1 %} – {{ 'general.meta.page' | t: page: current_page }}{% endif %}{% unless page_title contains shop.name %} – {{ shop.name }}{% endunless %}
</title>
{% if page_description %}
<meta name="description" content="{{ page_description | escape }}">
{% endif %}
{% include 'social-meta-tags' %}
{{ content_for_header }}
{% include 'critical-css' %}
{% include 'load-css' %}
<!-- slick slider css sheets-->
{%comment%}{{ 'slick.scss.css' | asset_url | stylesheet_tag }}
{{ 'slick-theme.scss.css' | asset_url | stylesheet_tag }}{%endcomment%}
<script>
var theme = {
stylesheet: "{{ 'theme.scss.css' | asset_url }}",
strings: {
addToCart: {{ 'products.product.add_to_cart' | t | json }},
soldOut: {{ 'products.product.sold_out' | t | json }},
unavailable: {{ 'products.product.unavailable' | t | json }},
addItemSuccess: {{ 'products.product.item_added_to_cart' | t | json }},
viewCart: {{ 'products.product.view_cart' | t | json }},
cartError: {{ 'cart.general.cart_error' | t | json }},
cartQuantityError: {{ 'cart.general.cart_quantity_error_html' | t: quantity: "[quantity]", title: "[title]" | json }},
regularPrice: {{ 'products.product.regular_price' | t | json }},
salePrice: {{ 'products.product.sale_price' | t | json }},
unitPrice: {{ 'products.product.unit_price' | t | json }},
unitPriceSeparator: {{ 'general.accessibility.unit_price_separator' | t | json }},
newsletter: {
blankError: {{ 'general.newsletter_form.blank_error' | t | json }},
invalidError: {{ 'general.newsletter_form.invalid_error' | t | json }}
},
map: {
zeroResults: {{ 'sections.map.address_no_results' | t | json }},
overQueryLimit: {{ 'sections.map.address_query_limit_html' | t | json }},
authError: {{ 'sections.map.auth_error_html' | t | json }},
addressError: {{ 'sections.map.address_error' | t | json }}
},
slideshow: {
loadSlideA11yString: {{ 'sections.slider.load_slide' | t: slide_number: '[slide_number]' | json }},
activeSlideA11yString: {{ 'sections.slider.active_slide' | t: slide_number: '[slide_number]' | json }}
}
},
isOnline: true,
moneyFormat: {{ shop.money_format | json }},
mediaQuerySmall: 750,
mediaQueryMedium: 990
};
{% if request.page_type contains 'customers/' %}
theme.countryOptionTags = {{ all_country_option_tags | json}};
{% endif %}
document.documentElement.className = document.documentElement.className.replace('supports-no-js', '');
</script>
<script src="{{ 'lazysizes.min.js' | asset_url }}" async="async"></script>
<script src="{{ 'vendor.min.js' | asset_url }}" defer="defer"></script>
<script src="{{ 'theme.js' | asset_url }}" defer="defer"></script>
<script src="{{ 'custom.js' | asset_url }}" defer="defer"></script>
<!-- flexslider -->
{{ '//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js' | script_tag }}
<script src="{{ 'jquery.flexslider-min.js' | asset_url }}" defer="defer"></script>
{{ 'flexslider.scss.css' | asset_url | stylesheet_tag }}
{{ shop.metafields.loox["global_html_head"] }}
</head>
<body id="{{ page_title | handle }}" class="{% if customer %}customer-logged-in {% endif %}template-{% if request.page_type != blank %}{{ request.page_type | handle }}{% else %}none{% endif %} data-animations">
<a class="visually-hidden skip-link" href="#MainContent">{{ 'general.accessibility.skip_to_content' | t }}</a>
{% section 'header' %}
<div class="main-content{% if request.page_type == blank %} main-content--no-template{% endif %}" data-drawer-push>
<div class="main-content__wrapper">
<main class="content-for-layout" id="MainContent" role="main">
{{ content_for_layout }}
<!-- Début du code - Pre footer badges de confiance -->
<style>
#gd-pre-footer { overflow:hidden; clear:both; margin-top:35px; margin-bottom:10px; padding-bottom:0; }
#gd-pre-footer .col-item { padding:15px 25px; text-align:center; list-style:none; }
@media screen and (min-width: 768px) {
#gd-pre-footer .col-item {
width:25%;
text-align:center;
float:left;
padding:5px 30px;
}
}
</style>
<div id="gd-pre-footer" class="pre_footer index-section home-section">
<div class="wrapper">
<div>
<ul class="footer-badges-list" style="padding:0px;">
<li class="col-item">
<div class="text-center">
<img src="https://cdn.shopify.com/s/files/1/0303/7636/2121/files/badge-confiance-shopify-1.png?v=1579089911" style="height: 50px;">
<h3 class="h5">Livraison en Europe</h3>
</div>
<p></p><center> Nous vous livrons votre masseur EMS à l'international <strong>sans frais supplémentaire !</strong> </center><p></p>
</li>
<li class="col-item">
<div class="text-center">
<img class="" src="https://cdn.shopify.com/s/files/1/0303/7636/2121/files/badge-confiance-shopify-2.png?v=1579089917" style="height: 50px;">
<h3 class="h5">Satisfait ou Remboursé</h3>
</div>
<p></p><center> Quelque chose ne va pas ? Ça tombe bien vous avez <strong>14 jours pour changer d'avis</strong> </center><p></p>
</li>
<li class="col-item">
<div class="text-center">
<img class="img90" src="https://cdn.shopify.com/s/files/1/0303/7636/2121/files/badge-confiance-shopify-3.png?v=1579089923" style="height: 50px;">
<h3 class="h5">Paiement sécurisé</h3>
</div>
<p></p><center> Nous utilisons le cryptage SSL pour des <strong>paiements en toute sécurité</strong> </center><p></p>
</li>
<li class="col-item">
<div class="text-center">
<img class="img90" src="https://cdn.shopify.com/s/files/1/0303/7636/2121/files/badge-confiance-shopify-4.png?v=1579089930" style="height: 50px;">
<h3 class="h5">Service Après Vente</h3>
</div>
<p></p><center> <strong>Besoin d'aide ?</strong> Nous sommes à votre service pour toute question à <strong>support@maccaa.com</strong> </center><p></p>
</li>
</ul>
</div>
</div>
</div>
<!-- Fin du code - Pre footer badges de confiance -->
</main>
{% section 'footer' %}
</div>
</div>
{% include 'cart-drawer' %}
<ul hidden>
<li id="a11y-refresh-page-message">{{ 'general.accessibility.refresh_page' | t }}</li>
<li id="a11y-selection-message">{{ 'general.accessibility.selection_help' | t }}</li>
</ul>
{{ shop.metafields.loox["global_html_body"] }}
</body>
</html>
Часть моего обновленного шаблона продукта, инициализация flexslider в начале и слайдер в конце:
{%- assign current_variant = product.selected_or_first_available_variant -%}
{%- assign current_variant_sale = false -%}
{% if current_variant.compare_at_price > current_variant.price %}
{%- assign current_variant_sale = true -%}
{% endif %}
<!-- flex slider initialisation -->
<script type="text/javascript">
$(window).load(function() {
$('.flexslider').flexslider({
directionNav: true,
slideshow: false
});
});
</script>
<div class="product-template" data-section-id="{{ section.id }}" data-section-type="product-template" data-variant-id="{{ current_variant.id }}" itemscope itemtype="http://schema.org/Product">
{% if product.metafields.loox.num_reviews %}
<div itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating">
<meta itemprop="ratingValue" content="{{ product.metafields.loox.avg_rating }}"/>
<meta itemprop="reviewCount" content="{{ product.metafields.loox.num_reviews }}"/>
</div>
{% endif %}
<meta itemprop="name" content="{{ product.title }}">
<meta itemprop="url" content="{{ shop.url }}{{ product.url }}">
<meta itemprop="image" content="{{ product.featured_image.src | img_url: 'grande' }}">
<div class="product__content product__content2 page-width page-width--large">
{% comment %}
------------------------------------------------------------------------------
Product Featured Image
------------------------------------------------------------------------------
{% endcomment %}
{% assign featured_image = current_variant.featured_image | default: product.featured_image %}
{% assign max_height = 650 %}
{% assign max_width = 980 %}
{% assign max_aspect_ratio = 1.50769 %}
{% if featured_image.aspect_ratio < max_aspect_ratio%}
{% if featured_image.height < max_height %}
{% assign max_width = featured_image.width | times: featured_image.aspect_ratio | round %}
{% else %}
{% assign max_width = max_height | times: featured_image.aspect_ratio | round %}
{% endif %}
{% else %}
{% if featured_image.width < max_width %}
{% assign max_width = featured_image.width %}
{% endif %}
{% endif %}
<div class="grid">
<div class="grid__item medium-up--one-half">
<div class="page-width page-width--no-gutter product__featured-container" >
<div class="flexslider" style="max-width: {{ max_width }}px; " id="flexslider-variante-id">
<ul class="slides" style="padding-bottom: {{featured_image.aspect_ratio | times: 100.0}}%;" >
{% for image in product.images %}
<li data-id="{{ image.id }}" data-variant-image-flexslider>
{% assign img_url = image | img_url: '1x1' | replace: '_1x1.', '_{width}x.' %}
<img class="flexslider__image lazyload"
{% if featured_image == image %}src="{{ image | img_url: '300x'}}"{% endif %}
data-src="{{ img_url }}"
data-widths="[360, 540, 720, 900, 1080, 1296, 1512, 1728, 2048]"
data-aspectratio="{{ image.aspect_ratio }}"
data-sizes="auto"
alt="{{ image.alt | escape }}"
data-variant-image>
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
Обновленный js код в теме. js
var selectors$12 = {
variantImageFlexslider: '[data-variant-image-flexslider]',
};
this._toggleVariantImageFlexslider(variant, $container);
_toggleVariantImageFlexslider: function(variant, $container) {
if (!variant.featured_image && !this.product.featured_image) return;
var image = variant.featured_image || this.product.featured_image.id;
var id = image && image.id;
var $images = $(selectors$12.variantImageFlexslider, $container);
var $active = $images.filter('[data-id="' + id + '"]');
var index = $active.index();
$('#flexslider-variante-id').flexslider(index);
},
, который входит в
var classes$11 = {
productPriceSale: 'product__price--sale',
productPriceUnitUnavailable: 'product-price-unit--unavailable',
productNotificationSuccess: 'product__notification--success',
productNotificationError: 'product__notification--error',
buttonTransition: 'btn--to-secondary-transitioned',
ajaxCartToggle: 'ajax-cart__toggle',
hide: 'hide',
lazyPreload: 'lazypreload'
};
var selectors$12 = {
productForm: '.product-form',
selectorWrapper: '.product-form__item',
ajaxCartToggle: '.ajax-cart__toggle',
shopifyPaymentButton: '.shopify-payment-button',
productJSON: '[data-product-json]',
optionInputs: '[data-option-input]',
masterSelect: '[data-master-select]',
variantImage: '[data-variant-image]',
variantImageToggleHide: '[data-variant-image-toggle-hide]',
variantImageFlexslider: '[data-variant-image-flexslider]',
variantImageSrc: '[data-variant-image-src]',
productPrice: '[data-product-price]',
regularPrice: '[data-regular-price]',
compareAtPrice: '[data-compare-price]',
unitPrice: '[data-unit-price]',
unitPriceBaseUnit: '[data-unit-price-base-unit]',
unitPriceContainer: '[data-unit-price-container]',
submitButton: '[data-cart-submit]',
submitButtonPrimaryText: '[data-cart-primary-submit-text]',
submitButtonSecondaryText: '[data-cart-secondary-submit-text]',
notification: '[data-cart-notification]'
};
var productDisplay = {
init: function() {
var $productJSON = $(selectors$12.productJSON, this.container);
if ($productJSON.length === 0) return;
this.product = JSON.parse($productJSON.html());
this.variant = product.getVariant(
this.product,
this.$container.data('variant-id')
);
this._formatVariantSelectors();
this.on('submit', selectors$12.productForm, this._addItemToCart.bind(this));
this.one(
'focus',
selectors$12.optionInputs,
this._preloadVariantImages.bind(this)
);
this.on(
'change.variantController',
selectors$12.optionInputs,
this.update.bind(this)
);
this.document().on(
'click',
selectors$12.ajaxCartToggle,
this._resetAddToCartButton.bind(this)
);
this.window().on('online', this._updateOnlineStatus);
this.window().on('offline', this._updateOfflineStatus);
},
update: function() {
var $inputs = $(selectors$12.optionInputs, this.$container);
var options = $inputs.serializeArray();
var variant = product.getVariant(this.product, options);
// If the variant we tried to find with the selected options does not exist
// then modify and clone the currently selected variant and transform it
// to an 'unavailable' product variant object.
if (typeof variant === 'undefined') {
this.trigger('variant_change_undefined', [this.product, options]);
variant = $.extend({}, this.variant); // Clone variant because we are going to edit it
variant.isUndefined = true;
variant.available = false;
variant.options = product.optionArrayFromOptionCollection(
this.product,
options
);
} else {
this.trigger('variant_change_successful', [this.product, variant]);
}
this.variant = variant;
// MorphDOM - Here is the old container, and the new container, only update
// the DOM with things that have changed.
morphdom(this.$container[0], this._updatedContainer(this.variant));
this.trigger('variant_change', [this.product, variant]);
},
_preloadVariantImages: function() {
$(selectors$12.variantImage, this.$container).addClass(classes$11.lazyPreload);
},
// The padding on the left side of the variant select's needs to be set
// to the same width as the option label. This can only be done when the main
// stylesheet has been downloaded, so we use utils.promiseStylesheet()
_formatVariantSelectors: function() {
utils.promiseStylesheet().then(
function() {
$(selectors$12.selectorWrapper, this.$container).each(function() {
var $wrapper = $(this);
var $label = $wrapper.find('label');
var $input = $wrapper.find('select, input');
$input.css({
'padding-left': $label.outerWidth(),
opacity: 1
});
});
}.bind(this)
);
},
// Clone the current version of the container and update elements with jQuery
// according to the new variant values. This is an alternative to having a
// duplicate Handlebars template that you would pass the cart object to
// generate the updated container.
_updatedContainer: function(variant) {
var $container = this.$container.clone();
$(selectors$12.masterSelect, $container).val(variant.id);
this._updateInputValues(variant, $container);
this._updateProductPrices(variant, $container);
this._updateVariantImage(variant, $container);
this._toggleVariantImageHide(variant, $container);
this._toggleVariantImageFlexslider(variant, $container);
this._updateCartButtonState(variant, $container);
return $container[0];
},
_updateInputValues: function(variant, $container) {
$(selectors$12.optionInputs, $container).each(function(index) {
$(this).val(variant.options[index]);
});
},
_updateCartButtonState: function(variant, $container) {
var text;
if (variant.isUndefined) {
text = theme.strings.unavailable;
} else {
text = variant.available
? theme.strings.addToCart
: theme.strings.soldOut;
}
this._resetAddToCartButton($container);
if (variant.available) {
$(selectors$12.shopifyPaymentButton, $container).show();
} else {
$(selectors$12.shopifyPaymentButton, $container).hide();
}
$(selectors$12.submitButton, $container)
.prop('disabled', !variant.available)
.attr('aria-label', text);
$(selectors$12.submitButtonPrimaryText, $container).text(text);
},
_updateProductPrices: function(variant, $container) {
var productPrice = variant.price;
var comparePrice = variant.compare_at_price;
$(selectors$12.regularPrice, $container).html(
currency.formatMoney(productPrice, theme.moneyFormat)
);
$(selectors$12.compareAtPrice, $container).html(
currency.formatMoney(comparePrice, theme.moneyFormat)
);
$(selectors$12.productPrice, $container).toggleClass(
classes$11.productPriceSale,
comparePrice > productPrice
);
$(selectors$12.unitPriceContainer, $container).addClass(
classes$11.productPriceUnitUnavailable
);
if (variant.unit_price_measurement) {
$(selectors$12.unitPrice, $container).html(
currency.formatMoney(variant.unit_price, theme.moneyFormat)
);
$(selectors$12.unitPriceBaseUnit, $container).html(
this.getBaseUnit(variant)
);
$(selectors$12.unitPriceContainer, $container).removeClass(
classes$11.productPriceUnitUnavailable
);
}
},
_updateVariantImage: function(variant, $container) {
var src =
(variant.featured_image && variant.featured_image.src) ||
this.product.featured_image;
var $variantImage = $(selectors$12.variantImageSrc, $container);
var size = images.imageSize($variantImage.attr('src'));
var sizedImgUrl = images.getSizedImageUrl(src, size);
$variantImage.attr('src', sizedImgUrl);
},
_toggleVariantImageHide: function(variant, $container) {
if (!variant.featured_image && !this.product.featured_image) return;
var image = variant.featured_image || this.product.featured_image.id;
var id = image && image.id;
var $images = $(selectors$12.variantImageToggleHide, $container);
var $active = $images.filter('[data-id="' + id + '"]');
$active
.removeClass(classes$11.hide)
.siblings()
.addClass(classes$11.hide);
},
// Ajoute pour switcher d'image quand on selectionne une variante
_toggleVariantImageFlexslider: function(variant, $container) {
if (!variant.featured_image && !this.product.featured_image) return;
var image = variant.featured_image || this.product.featured_image.id;
var id = image && image.id;
var $images = $(selectors$12.variantImageFlexslider, $container);
var $active = $images.filter('[data-id="' + id + '"]');
var index = $active.index();
$('#flexslider-variante-id').flexslider(index);
},
_addItemToCart: function(evt) {
if (!sections.isInstance('cart-drawer')) return;
evt.preventDefault();
var $button = $(selectors$12.submitButton, this.$container);
var data = new FormData(evt.target);
if ($button.hasClass(classes$11.ajaxCartToggle)) return;
cart
.addItemFromForm(data)
.then(this._transitionAddToCartButton.bind(this, data))
.catch(this._onAddItemFail.bind(this))
.always(
function() {
this.trigger('variant_add_to_cart', [
this.product,
this.variant,
data
]);
}.bind(this)
);
},
_onAddItemFail: function(response) {
var $notification = $(selectors$12.notification, this.$container);
var responseText = response && response.responseText;
if (responseText) {
responseText = JSON.parse(responseText).description;
} else {
responseText = theme.strings.cartError;
}
$notification
.addClass(classes$11.productNotificationError)
.removeClass(classes$11.productNotificationSuccess)
.html(responseText)
.attr('role', 'alert');
this.trigger('variant_add_to_cart_fail', [
this.product,
this.variant,
responseText
]);
return utils.promiseTransitionEnd($notification);
},
_transitionAddToCartButton: function(data) {
var $notification = $(selectors$12.notification, this.$container);
var $button = $(selectors$12.submitButton, this.$container);
var $primaryButtonText = $(selectors$12.submitButtonPrimaryText, $button);
var $secondaryButtonText = $(selectors$12.submitButtonSecondaryText, $button);
$button
.addClass([classes$11.buttonTransition, classes$11.ajaxCartToggle].join(' '))
.attr('aria-label', theme.strings.viewCart);
$primaryButtonText.attr('aria-hidden', true);
$secondaryButtonText.attr('aria-hidden', false);
$notification
.removeClass(classes$11.productNotificationError)
.addClass(classes$11.productNotificationSuccess)
.text(theme.strings.addItemSuccess)
.attr('role', 'alert');
this.trigger('variant_add_to_cart_successful', [
this.product,
this.variant,
data
]);
return utils.promiseTransitionEnd($notification);
},
_resetAddToCartButton: function($container) {
$container = $container.length ? $container : this.$container;
var $notification = $(selectors$12.notification, $container);
var $button = $(selectors$12.submitButton, $container);
var $primaryButtonText = $(selectors$12.submitButtonPrimaryText, $button);
var $secondaryButtonText = $(selectors$12.submitButtonSecondaryText, $button);
$button
.removeClass([classes$11.buttonTransition, classes$11.ajaxCartToggle].join(' '))
.attr('aria-label', theme.strings.addToCart);
$primaryButtonText.attr('aria-hidden', false);
$secondaryButtonText.attr('aria-hidden', true);
$notification
.removeClass(classes$11.productNotificationError)
.removeClass(classes$11.productNotificationSuccess)
.text('')
.attr('role', '');
},
_updateOnlineStatus: function() {
theme.isOnline = true;
},
_updateOfflineStatus: function() {
theme.isOnline = false;
},
getBaseUnit: function(variant) {
return variant.unit_price_measurement.reference_value === 1
? variant.unit_price_measurement.reference_unit
: variant.unit_price_measurement.reference_value +
variant.unit_price_measurement.reference_unit;
}
};