2024 leggings à fond de laine d\'agneau très épaisse (coupe ajustée)
2024 leggings à fond de laine d\'agneau très épaisse (coupe ajustée)
2024 leggings à fond de laine d\'agneau très épaisse (coupe ajustée)
2024 leggings à fond de laine d\'agneau très épaisse (coupe ajustée)
2024 leggings à fond de laine d\'agneau très épaisse (coupe ajustée)
2024 leggings à fond de laine d\'agneau très épaisse (coupe ajustée)
2024 leggings à fond de laine d\'agneau très épaisse (coupe ajustée)
2024 leggings à fond de laine d\'agneau très épaisse (coupe ajustée)
2024 leggings à fond de laine d\'agneau très épaisse (coupe ajustée)
2024 leggings à fond de laine d\'agneau très épaisse (coupe ajustée)
2024 leggings à fond de laine d\'agneau très épaisse (coupe ajustée)
2024 leggings à fond de laine d\'agneau très épaisse (coupe ajustée)
2024 leggings à fond de laine d\'agneau très épaisse (coupe ajustée)
1 / 13
2024 leggings à fond de laine d\'agneau très épaisse (coupe ajustée)
2024 leggings à fond de laine d\'agneau très épaisse (coupe ajustée)
2024 leggings à fond de laine d\'agneau très épaisse (coupe ajustée)
2024 leggings à fond de laine d\'agneau très épaisse (coupe ajustée)
2024 leggings à fond de laine d\'agneau très épaisse (coupe ajustée)
2024 leggings à fond de laine d\'agneau très épaisse (coupe ajustée)
2024 leggings à fond de laine d\'agneau très épaisse (coupe ajustée)
2024 leggings à fond de laine d\'agneau très épaisse (coupe ajustée)
2024 leggings à fond de laine d\'agneau très épaisse (coupe ajustée)
2024 leggings à fond de laine d\'agneau très épaisse (coupe ajustée)
2024 leggings à fond de laine d\'agneau très épaisse (coupe ajustée)
2024 leggings à fond de laine d\'agneau très épaisse (coupe ajustée)
2024 leggings à fond de laine d\'agneau très épaisse (coupe ajustée)
0% OFF
Épargnez €-29.99
comenem

2024 leggings à fond de laine d\'agneau très épaisse (coupe ajustée)

€29.99
1 ventes
Couleur
Taille
Quantité

ÉVÉNEMENT SPÉCIAL DE CETTE SEMAINE
Sélectionnez au hasard 100 clients chanceux pour obtenir le double du produit de la commande. Nous vous enverrons un e-mail, n'oubliez pas de vérifier, merci pour votre soutien.

Le prix est limité ! Obtenez le vôtre en tant que promotion limitée disponible !

⏰ Délai de traitement >> Expédier plus rapidement après paiement.
Expédition>> Expédition express dans le monde entier disponible
Paiements via PayPal et carte de crédit
93,76 % des clients recommandent ce produit.
100% de satisfaction garantie avec chaque commande
Si vous n'êtes pas satisfait des marchandises reçues, veuillez nous contacter dans les 15 jours suivant la réception et nous vous fournirons la meilleure aide ! S'il vous plaît ne vous inquiétez pas !
Garantie de remboursement rapide >> Remboursement partiel ou total selon la situation.

Ressemble à votre legging préféré, mais une fois que vous le porterez, vous ressentirez une chaleur et un confort extrêmes avec un look plus mince ! 
undefined
Notre legging est innovant.  Rempli de peluche chaude à l'intérieur,Toucher la peau, c'est comme toucher un nuage.
undefined
Il est à la mode et s'accorde avec toutes les tenues. Il est doté d'un design taille haute offrant un excellent modelage du ventre.
undefined
La couche intérieure en peluche(400g) est douce et confortable. qui est douce, confortable et vous garde au chaud pendant les saisons froides sans être encombrante. Vous pouvez sentir le doux duvet qui ressemble à la peau d'un bébé. Il est capable de vous garder au chaud même à -10°C. 

undefinedundefinedIl est suffisamment extensible pour tenir le coup et vous permettre de bouger sans restriction. Restez au chaud sans exercer de pression sur votre corps.
undefined

Il s'adapte parfaitement à toutes vos tenues préférées ! Ajoutez ce legging en peluche chaude à votre collection de vêtements d'hiver à la mode ! undefined

Produit inclus 

  • 1 x leggings à fond de laine d'agneau très épaisse

Conseils Chaleureux

  • Cher client En raison des mesures manuelles, veuillez accepter de légers écarts de mesure.
  • En raison des différences entre les moniteurs et des effets de lumière, la couleur réelle de l'article peut différer légèrement de la couleur indiquée sur les photographies, mais la différence globale n'est pas significative.Merci de votre compréhension ! Joyeuses fêtes à vous !

1. Dois-je avoir un compte pour commander ?
Non, vous pouvez également passer une commande en tant qu'invité. Mais vous bénéficiez de certains avantages si vous avez un compte chez nous :

Processus de paiement rapide
Visualisez facilement l'état et l'historique de votre commande.
Recevez des mises à jour détaillant nos nouveautés et nos promotions spéciales.


2. Quels modes de paiement acceptez-vous ?
Nous acceptons toutes les principales cartes de crédit (VISA, Mastercard, Discover, AMEX) et les paiements PayPal.



3. Ma commande en ligne est-elle sécurisée ?
Lorsque vous achetez en ligne en utilisant votre carte de crédit, toutes vos informations sont saisies sur une page Web sécurisée par SSL. Vos informations sont ensuite cryptées par SSL et envoyées directement au réseau de notre fournisseur de carte de crédit, où votre carte et la transaction sont autorisées et approuvées. Les informations relatives à votre carte de crédit ne sont pas stockées sur nos serveurs.



4. Y a-t-il des taux de change ?
Toutes nos transactions sont basées sur l'euro. Si votre carte de crédit est libellée dans une autre devise, le total de votre commande sera calculé sur la base du taux de change quotidien à partir de la date à laquelle l'émetteur de votre carte traite la transaction.



5. comment définir mon adresse de livraison ?
Notre site et nos services étant basés sur le français, toutes les informations que vous saisissez doivent l'être en français, y compris la ponctuation. Si certaines des lettres de votre adresse contiennent des lettres non françaises, nous vous recommandons de les remplacer par des lettres françaises similaires. Par exemple, vous pouvez remplacer la lettre " ?". pour "c"



6. Puis-je modifier mon adresse de livraison après avoir passé une commande ?
Nous vous informons que votre adresse de livraison ne peut pas être modifiée après le traitement ou l'expédition de la commande. Veuillez mettre à jour votre adresse de livraison à votre adresse résidentielle plutôt qu'à votre adresse de vacances, car nous ne savons pas combien de temps le service des douanes du pays de destination gardera le colis en attente.



7. combien de temps dure la livraison et comment puis-je suivre mon colis ?
Le délai de livraison dépend de l'option d'expédition que vous avez choisie. Une fois la commande expédiée, nous vous enverrons par courriel votre numéro de suivi et le site Web de suivi. Nous ne sommes pas responsables des retards causés par le service des douanes de votre pays.



8. Que dois-je faire si des articles manquent dans ma commande ?
Si un article est toujours manquant, veuillez nous contacter immédiatement à service@bonusvogue.com.



Si vous avez encore des questions, veuillez nous contacter directement à l'adresse e-mail service@bonusvogue.com

87.3% des clients ont également acheté Je n'aime pas ça?
/** @private {string} */ class SpzCustomAnchorScroll extends SPZ.BaseElement { static deferredMount() { return false; } constructor(element) { super(element); /** @private {Element} */ this.scrollableContainer_ = null; } isLayoutSupported(layout) { return layout == SPZCore.Layout.LOGIC; } buildCallback() { this.viewport_ = this.getViewport(); this.initActions_(); } setTarget(containerId, targetId) { this.containerId = '#' + containerId; this.targetId = '#' + targetId; } scrollToTarget() { const container = document.querySelector(this.containerId); const target = container.querySelector(this.targetId); const {scrollTop} = container; const eleOffsetTop = this.getOffsetTop_(target, container); this.viewport_ .interpolateScrollIntoView_( container, scrollTop, scrollTop + eleOffsetTop ); } initActions_() { this.registerAction( 'scrollToTarget', (invocation) => this.scrollToTarget(invocation?.caller) ); this.registerAction( 'setTarget', (invocation) => this.setTarget(invocation?.args?.containerId, invocation?.args?.targetId) ); } /** * @param {Element} element * @param {Element} container * @return {number} * @private */ getOffsetTop_(element, container) { if (!element./*OK*/ getClientRects().length) { return 0; } const rect = element./*OK*/ getBoundingClientRect(); if (rect.width || rect.height) { return rect.top - container./*OK*/ getBoundingClientRect().top; } return rect.top; } } SPZ.defineElement('spz-custom-anchor-scroll', SpzCustomAnchorScroll); const STRENGTHEN_TRUST_URL = "/api/strengthen_trust/settings"; class SpzCustomStrengthenTrust extends SPZ.BaseElement { constructor(element) { super(element); this.renderElement_ = null; } isLayoutSupported(layout) { return layout == SPZCore.Layout.CONTAINER; } buildCallback() { this.xhr_ = SPZServices.xhrFor(this.win); const renderId = this.element.getAttribute('render-id'); SPZCore.Dom.waitForChild( document.body, () => !!document.getElementById(renderId), () => { this.renderElement_ = SPZCore.Dom.scopedQuerySelector( document.body, `#${renderId}` ); if (this.renderElement_) { this.render_(); } this.registerAction('track', (invocation) => { this.track_(invocation.args); }); } ); } render_() { this.fetchData_().then((data) => { if (!data) { return; } SPZ.whenApiDefined(this.renderElement_).then((apis) => { apis?.render(data); document.querySelector('#strengthen-trust-render-1710495796818').addEventListener('click',(event)=>{ if(event.target.nodeName == 'A'){ this.track_({type: 'trust_content_click'}); } }) }); }); } track_(data = {}) { const track = window.sa && window.sa.track; if (!track) { return; } track('trust_enhancement_event', data); } parseJSON_(string) { let result = {}; try { result = JSON.parse(string); } catch (e) {} return result; } fetchData_() { return this.xhr_ .fetchJson(STRENGTHEN_TRUST_URL) .then((responseData) => { if (!responseData || !responseData.data) { return null; } const data = responseData.data; const moduleSettings = (data.module_settings || []).reduce((result, moduleSetting) => { return result.concat(Object.assign(moduleSetting, { logos: (moduleSetting.logos || []).map((item) => { return moduleSetting.logos_type == 'custom' ? this.parseJSON_(item) : item; }) })); }, []); return Object.assign(data, { module_settings: moduleSettings, isEditor: window.self !== window.top, }); }); } } SPZ.defineElement('spz-custom-strengthen-trust', SpzCustomStrengthenTrust);

émettre un commentaire
Commentaire de clients
tu as atteint le fond
Le plus récent
Le plus aimé
Meilleures notes
Notes les plus basses
×
class SpzCustomFileUpload extends SPZ.BaseElement { constructor(element) { super(element); this.uploadCount_ = 0; this.fileList_ = []; } buildCallback() { this.action = SPZServices.actionServiceForDoc(this.element); this.registerAction('upload', (data) => { this.handleFileUpload_(data.event?.detail?.data || []); }); this.registerAction('delete', (data) => { this.handleFileDelete_(data?.args?.data); }); this.registerAction('preview', (data) => { this.handleFilePreview_(data?.args?.data); }); this.registerAction('limit', (data) => { this.handleFileLimit_(); }); this.registerAction('sizeLimit', (data) => { this.handleFileSizeLimit_(); }); } isLayoutSupported(layout) { return layout == SPZCore.Layout.LOGIC; } setData_(count, file) { this.uploadCount_ = count; this.fileList_ = file; } handleFileUpload_(data) { data.forEach(i => { if(this.fileList_.some(j => j.url === i.url)) return; this.fileList_.push(i); }) this.uploadCount_++; sessionStorage.setItem('fileList', JSON.stringify(this.fileList_)); this.triggerEvent_("handleFileUpload", { count: this.uploadCount_, files: this.fileList_}); if(this.fileList_.length >= 5){ document.querySelector('#review_upload').style.display = 'none'; } if(this.fileList_.length > 0){ document.querySelector('.apps-reviews-write-anonymous-box').style.marginTop = '8px'; } } handleFileDelete_(index) { this.fileList_.splice(index, 1); this.uploadCount_--; sessionStorage.setItem('fileList', JSON.stringify(this.fileList_)); this.triggerEvent_("handleFileDelete", { count: this.uploadCount_, files: this.fileList_}); document.querySelector('#review_upload').style.display = 'block'; if(this.fileList_?.length === 0){ document.querySelector('.apps-reviews-write-anonymous-box').style.marginTop = '132px'; } } handleFilePreview_(index) { const finalPreviewData = this.fileList_[index]; const filePreviewModal = document.getElementById('filePreviewModal'); const fullScreenVideo = document.getElementById('fullScreenVideo'); const fullScreenImage = document.getElementById('fullScreenImage'); const previewModalClose = document.getElementById('previewModalClose'); const previewLoading = document.getElementById('previewLoading'); filePreviewModal.style.display = 'block'; previewLoading.style.display = 'flex'; if(finalPreviewData?.type === 'video'){ const media = this.mediaParse_(this.fileList_[index]?.url); fullScreenVideo.addEventListener('canplaythrough', function() { previewLoading.style.display = 'none'; }); fullScreenImage.src = ''; fullScreenImage.style.display = 'none'; fullScreenVideo.style.display = 'block'; fullScreenVideo.src = media.mp4 || ''; } else { fullScreenImage.onload = function() { previewLoading.style.display = 'none'; }; fullScreenVideo.src = ''; fullScreenVideo.style.display = 'none'; fullScreenImage.style.display = 'block'; fullScreenImage.src = finalPreviewData.url; } previewModalClose.addEventListener('click', function() { filePreviewModal.style.display = 'none'; }); } handleFileLimit_() { alert(window.AppReviewsLocale.comment_file_limit || 'please do not upload files more than 5'); this.triggerEvent_("handleFileLimit"); } handleFileSizeLimit_() { alert(window.AppReviewsLocale.comment_file_size_limit || 'File size does not exceed 10M'); } clear(){ this.fileList_ = []; this.uploadCount_ = 0; sessionStorage.setItem('fileList', JSON.stringify(this.fileList_)); this.triggerEvent_("handleClear", { count: this.uploadCount_, files: this.fileList_}); document.querySelector('#review_upload').style.display = 'block'; } mediaParse_(url) { var result = {}; try { url.replace(/[?&]+([^=&]+)=([^&]*)/gi, function (str, key, value) { try { result[key] = decodeURIComponent(value); } catch (e) { result[key] = value; } }); result.preview_image = url.split('?')[0]; } catch (e) {}; return result; } triggerEvent_(name, data) { const event = SPZUtils.Event.create(this.win, name, data); this.action.trigger(this.element, name, event); } } SPZ.defineElement('spz-custom-file-upload', SpzCustomFileUpload);
The review would not show in product details on storefront since it does not support to.
class SpzSmartBlockComponent extends SPZ.BaseElement { constructor(element) { super(element); this.templates_ = null; this.container_ = null; this.i18n_ = {}; this.config_ = {}; this.show_type_ = 3; this.product_resource_id_ = ''; this.collection_resource_id_ = ''; this.cart_items_ = []; this.customer_id_ = ''; this.order_id_ = ''; } static deferredMount() { return false; } isLayoutSupported(layout) { return layout == SPZCore.Layout.CONTAINER; } buildCallback() { const template_type = window.SHOPLAZZA.meta.page.template_type; if (template_type === 1) { this.show_type_ = 3; this.product_resource_id_ = window.SHOPLAZZA.meta.page.resource_id; } else if (template_type === 2) { this.show_type_ = 4; this.collection_resource_id_ = window.SHOPLAZZA.meta.page.resource_id; } else if (template_type === 15){ this.show_type_ = 5; } else if (template_type === 13){ this.show_type_ = 6; } else if (template_type === 20){ this.show_type_ = 7; this.customer_id_ = window.SHOPLAZZA.customer.customer_id; } else if (template_type === 35){ this.show_type_ = 8; this.order_id_ = window.location.pathname.split('/').pop(); } this.templates_ = SPZServices.templatesForDoc(this.element); this.setAction_(); } mountCallback() { console.log('smart mounted'); const that = this; const themeName = window.SHOPLAZZA.theme.merchant_theme_name; const isGeek = /Geek/.test(themeName); this.fetchRules().then((res) => { if (res && res.rules && res.rules.length) { const blockEl = document.getElementById('smart_recommend_block'); SPZ.whenApiDefined(blockEl).then((api) => { api.render({data: res}, true).then(() => { if (isGeek && that.show_type_ === 6) { blockEl.querySelector('.plugin_container_wrpper').style.padding = '30px 0'; } const recommendStyle = document.createElement('style'); recommendStyle.innerHTML = ` .plugin__recommend_container,.app-recommend-card { display: none !important; } `; document.head.appendChild(recommendStyle); const fetchList = []; res.rules.forEach((rule) => { fetchList.push(this.fetchRuleProductList(rule.id)); }); const fetchAll = Promise.all(fetchList); fetchAll.then((p_res) => { res.rules.forEach((rule, index) => { rule.products = p_res[index] && p_res[index].products; const ruleEl = document.getElementById('smart_recommend_rule_' + rule.id); SPZ.whenApiDefined(ruleEl).then((api) => { api.render({data: rule}, true).then(() => { that.impressListen(`#smart_recommend_rule_ul_${rule.id}`, function(){ that.trackRuleImpress(rule); }); const btnElList = document.querySelectorAll(`#smart_recommend_rule_ul_${rule.id} button`); btnElList.forEach((btnEl) => { if (btnEl && rule.config && rule.config.quick_shop_button_bg_color && rule.config.quick_shop_button_text_color) { btnEl.style.backgroundColor = rule.config.quick_shop_button_bg_color; btnEl.style.color = rule.config.quick_shop_button_text_color; } }) }); }); }); }); }) }) } else { if (window.top !== window.self) { const template_type = window.SHOPLAZZA.meta.page.template_type; const holderEl = document.getElementById('smart_recommend_preview_no_data_placeholder'); SPZ.whenApiDefined(holderEl).then((api) => { api.render({data: { isCart: template_type === 13, isCollection: template_type === 2, isProduct: template_type === 1, isIndex: template_type === 15 }}, true); }); } } }); } setAction_() { this.registerAction('quickShop', (data) => { const that = this; const product_id = data.args.product_id; const productIndex = data.args.productIndex; const rule_id = data.args.rule_id; const ssp = data.args.ssp; const scm = data.args.scm; const cfb = data.args.cfb; const ifb = data.args.ifb; const modalRender = document.getElementById('smart_recommend_product_modal_render'); if (product_id) { this.fetchProductData(product_id).then((res) => { const product = res.products && res.products.length && res.products[0] || {}; product.cfb = cfb; product.ifb = ifb; SPZ.whenApiDefined(modalRender).then((api) => { api.render({product: product, productIndex: productIndex, rule_id: rule_id, ssp: ssp, scm: scm, show_type: that.show_type_}, true).then(() => { const modalEl = document.getElementById('smart_recommend_product_modal'); SPZ.whenApiDefined(modalEl).then((modal) => { that.impressListen('#smart_recommend_product_modal', function(){ that.trackQuickShop({ rule_id: rule_id, product_id: product_id }); }); modal.open(); }); const formEl = document.getElementById('smart_recommend_product_form'); SPZ.whenApiDefined(formEl).then((form) => { form.setProduct(product); }); const variantEl = document.getElementById('smart_recommend_product_variants'); SPZ.whenApiDefined(variantEl).then((variant) => { variant.handleRender(product); }); }); }) }); } }); this.registerAction('handleScroll', (data) => { this.directTo(data.args.rule_id, data.args.direction); }); this.registerAction('handleProductChange', (data) => { const variant = data.args.data.variant; const product = data.args.data.product; const imageRenderEl = document.getElementById('smart_recommend_product_image'); SPZ.whenApiDefined(imageRenderEl).then((api) => { api.render({ variant: variant, product: product }, true); }); }); this.registerAction('handleAtcSuccess', (detail) => { const data = detail.args; data.data.product = data.data.product || {}; data.data.variant = data.data.variant || {}; const product_id = data.data.product.id; const product_title = data.data.product.title; const variant_id = data.data.variant.id; const price = data.data.variant.price; const rule_id = data.rule_id; const aid = `smart_recommend.${this.show_type_}.${rule_id}`; const ifb = data.data.product.ifb; const cfb = data.data.product.cfb; const ssp = data.ssp; const scm = data.scm; const spm = `smart_recommend_${this.show_type_}.${data.spmIndex}`; const params = { id: product_id, product_id: product_id, number: 1, name: product_title, variant_id: variant_id, childrenId: variant_id, item_price: price, source: 'add_to_cart', _extra: { aid: aid, ifb: ifb, cfb: cfb, scm: scm, spm: `..${window.SHOPLAZZA.meta.page.template_name}.${spm}`, ssp: ssp, } }; this.tranckAddToCart(params); }); this.registerAction('addATCHook', (data) => { const params = data.args; const spm = `smart_recommend_${this.show_type_}.${params.spmIndex}`; this.myInterceptor_ = window.djInterceptors && window.djInterceptors.track.use({ event: 'dj.addToCart', params: { aid: `smart_recommend.${this.show_type_}.` + params.rule_id, ssp: params.ssp, scm: params.scm, cfb: params.cfb, spm: `..${window.SHOPLAZZA.meta.page.template_name}.${spm}`, }, once: true }); }); } tranckAddToCart(detail) { if (window.$) { window.$(document.body).trigger('dj.addToCart', detail); } } fetchRules() { const payload = { show_type: this.show_type_, }; let that = this; if (this.show_type_ === 6) { let line_items = []; return this.fetchCart().then((res) => { if (res && res.cart && res.cart.line_items) { line_items = res.cart.line_items.map((item) => { return { product_id: item.product_id, variant_id: item.variant_id, quantity: item.quantity, price: item.price } }); } payload.line_items = line_items; that.cart_items_ = line_items; return that.fetchRulesRequest(payload); }); } else { if (this.show_type_ === 3) { payload.line_items = [{ product_id: this.product_resource_id_ }]; } else if (this.show_type_ === 4) { payload.collection_id = this.collection_resource_id_; } else if (this.show_type_ === 7) { payload.customer_id = this.customer_id_; } else if (this.show_type_ === 8) { payload.order_id = this.order_id_; } return this.fetchRulesRequest(payload); } } fetchRulesRequest(payload) { return fetch(window.SHOPLAZZA.routes.root + "/api/possum/recommend_query", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload) }).then(function(res){ if(res.ok){ return res.json(); } }); } fetchCart() { return fetch(`/api/cart/cart-select?r=${Math.random().toString(36).slice(-4)}`) .then((res) => { if (res.ok) { return res.json(); } }); } fetchRuleProductList(rule_id) { const payload = { page: 1, limit: 100, fields: ["title", "url", "image", "min_price_variant.price", "min_price_variant.compare_at_price"], rule_id: rule_id, }; if (this.show_type_ === 3) { payload.line_items = [{ product_id: this.product_resource_id_ }]; } else if (this.show_type_ === 4) { payload.collection_id = this.collection_resource_id_; } else if (this.show_type_ === 6) { payload.line_items = this.cart_items_; } else if (this.show_type_ === 7) { payload.customer_id = this.customer_id_; } else if (this.show_type_ === 8) { payload.order_id = this.order_id_; } return fetch(window.SHOPLAZZA.routes.root + "/api/possum/recommend_products", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload) }).then(function(res){ if(res.ok){ return res.json(); } }).catch(function(err){ console.log(err); }); } fetchProductData(product_id) { return fetch(window.SHOPLAZZA.routes.root + "/api/possum/products", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ product_ids: [product_id], fields: [ "images", "options", "min_price_variant", "variants"] }) }).then(function(res){ if(res.ok){ return res.json(); } }).catch(function(err){ console.log(err); const loadingEl = document.getElementById('smart_recommend_loading'); if (loadingEl) { loadingEl.style.display = 'none'; } }); } getStyle(ele, style) { if (!ele) return; if (window.getComputedStyle) { return window.getComputedStyle(ele)[style]; } return ele.currentStyle[style]; } directTo(id, direction) { const scrollElement = document.getElementById(`smart_recommend_rule_ul_${id}`); const blockWidth = parseInt(this.getStyle(scrollElement, 'width')); const scrollLength = (blockWidth * 0.19 - 12) * 5; const scrollPoint = scrollElement.scrollWidth - scrollElement.clientWidth; if (!scrollElement) return; if (direction === 'left') { if (document.dir === 'rtl') { scrollElement.scrollTo({ left: Math.abs(scrollElement.scrollLeft) >= scrollPoint - 100 ? 0 : scrollElement.scrollLeft - scrollLength, behavior: 'smooth' }); return; } scrollElement.scrollTo({ left: Math.max(scrollElement.scrollLeft - scrollLength, 0), behavior: 'smooth' }); } else { if (document.dir === 'rtl') { scrollElement.scrollTo({ left: Math.abs(scrollElement.scrollLeft) >= scrollPoint + 100 ? 0 : scrollElement.scrollLeft + scrollLength, behavior: 'smooth' }); return; } scrollElement.scrollTo({ left: scrollElement.scrollLeft >= scrollPoint - 100 ? 0 : scrollElement.scrollLeft + scrollLength, behavior: 'smooth' }); } } trackRuleImpress(rule) { if (window.sa && window.sa.track) { window.sa.track("plugin_common", { plugin_name: "upsell", event_type: "impressions", rule_id: rule.id, ssp: rule.ssp, scm: rule.scm, show_type: this.show_type_, support_app_block: window.SHOPLAZZA.theme.support_app_block }); window.sa.track("module_impressions", { aid: `smart_recommend.${this.show_type_}.${rule.id}`, support_app_block: window.SHOPLAZZA.theme.support_app_block }); } } trackQuickShop(data) { window.sa && sa.track && sa.track("plugin_common", { plugin_name: "upsell", event_type: "quick_shop", rule_id: data.rule_id, product_id: data.product_id, show_type: this.show_type_, }); } impressListen(selector, cb) { const el = document.querySelector(selector); const onImpress = (e) => { if (e) { e.stopPropagation(); } cb(); }; if (el && !el.getAttribute('imprsd')) { el.addEventListener('impress', onImpress) } else if (el) { onImpress(); } } } SPZ.defineElement('spz-custom-smart-block', SpzSmartBlockComponent);
const TAG = 'spz-custom-painter-button-animation'; const MAX_ITERATION_COUNT = 99999999; const SITE = (window.C_SETTINGS && window.C_SETTINGS.routes && window.C_SETTINGS.routes.root) || ''; const ADD_TO_CART_ANIMATION_SETTING = `${SITE}/api/marketing_atmosphere_app/add_to_cart_btn_animation/setting`; class SpzCustomPainterButtonAnimation extends SPZ.BaseElement { /**@override */ static deferredMount() { return false; } /** @param {!SpzElement} element */ constructor(element) { super(element); /** @private {!../../src/service/xhr-impl.Xhr} */ this.xhr_ = SPZServices.xhrFor(this.win); /** @private {Object} */ this.data_ = null; /** @private {Element} */ this.addToCartButton_ = null; /** @private {boolean} */ this.productAvailable_ = true; /** @private {number} */ this.timerId_ = null; /** @private {number} */ this.animationExecutionCount_ = 0; /** @private {boolean} */ this.selectedVariantAvailable_ = true; /** @private {number} */ this.delay_ = 5000; /** @private {number} */ this.iterationCount_ = 5; /** @private {string} */ this.animationClass_ = ''; } /** @override */ isLayoutSupported(layout) { return layout == SPZCore.Layout.LOGIC; } /** @override */ buildCallback() { this.productAvailable_ = this.element.hasAttribute('product-available'); this.selectedVariantAvailable_ = this.element.hasAttribute('selected-variant-available'); } /** @override */ mountCallback() { this.render_(); } /** @private */ render_() { if (!this.productAvailable_) { return; } this.fetch_().then((data) => { if (!data) { return; } this.data_ = data; this.animationClass_ = `painter-${data.animation_name}-animation`; this.iterationCount_ = data.animation_iteration_count === 'infinite' ? MAX_ITERATION_COUNT : data.animation_iteration_count; const animationDuration = 1; const animationDelay = data.animation_delay || 5; this.delay_ = (animationDuration + animationDelay) * 1000; this.handleButtonEffect_(); }); } /** * @param {JsonObject} data * @return {(null|Object)} * @private */ parseJson_(data) { try { return JSON.parse(data); } catch (e) { return null; } } /** * @return {Promise} * @private */ fetch_() { return this.xhr_.fetchJson(ADD_TO_CART_ANIMATION_SETTING).then((data) => { if (!data || !data.enabled) { return null; } return this.parseJson_(data.detail); }); } /** @private */ getAddToCartButton_() { this.addToCartButton_ = SPZCore.Dom.scopedQuerySelector( document.body, '[data-section-type="product"] [role="addToCart"], [data-section-type="product_detail"] [role="addToCart"], [data-section-type="product_detail"] [data-click="addToCart"], [data-section-type="product"] [data-click="addToCart"]' ); } /** @private */ restartAnimation_() { this.addToCartButton_.classList.remove(this.animationClass_); this.addToCartButton_./* OK */ offsetWidth; this.addToCartButton_.classList.add(this.animationClass_); this.animationExecutionCount_++; } /** @private */ clearTimer_() { this.win.clearInterval(this.timerId_); this.timerId_ = null; } /** @private */ setupTimer_() { this.timerId_ = this.win.setInterval(() => { this.restartAnimation_(); if (this.animationExecutionCount_ >= this.iterationCount_) { this.removeAnimationClass_(); this.clearTimer_(); } }, this.delay_); } /** @private */ restartTimer_() { if (this.animationExecutionCount_ >= this.iterationCount_) { this.removeAnimationClass_(); return; } this.setupTimer_(); } /** @private */ listenVariantChange_() { SPZUtils.Event.listen(self.document, 'dj.variantChange', (e) => { const selectedVariant = e.detail && e.detail.selected; if (!selectedVariant) { return; } const {available} = selectedVariant; if (this.selectedVariantAvailable_ !== available) { this.selectedVariantAvailable_ = available; this.clearTimer_(); if (available) { this.restartTimer_(); } } }); } /** @private */ removeAnimationClass_() { this.win.setTimeout(() => { this.addToCartButton_.classList.remove(this.animationClass_); }, 1000); } /** @private */ handleButtonEffect_() { this.getAddToCartButton_(); if (!this.addToCartButton_) { return; } if (this.selectedVariantAvailable_) { ++this.animationExecutionCount_; this.addToCartButton_.classList.add(this.animationClass_); if (this.iterationCount_ === 1) { this.removeAnimationClass_(); return; } this.setupTimer_(); } this.listenVariantChange_(); } } SPZ.defineElement(TAG, SpzCustomPainterButtonAnimation);