Laque moelleuse et volumineuse
Laque moelleuse et volumineuse
Laque moelleuse et volumineuse
Laque moelleuse et volumineuse
Laque moelleuse et volumineuse
Laque moelleuse et volumineuse
Laque moelleuse et volumineuse
Laque moelleuse et volumineuse
Laque moelleuse et volumineuse
Laque moelleuse et volumineuse
Laque moelleuse et volumineuse
Laque moelleuse et volumineuse
10 / 12
Laque moelleuse et volumineuse
Laque moelleuse et volumineuse
Laque moelleuse et volumineuse
Laque moelleuse et volumineuse
Laque moelleuse et volumineuse
Laque moelleuse et volumineuse
Laque moelleuse et volumineuse
Laque moelleuse et volumineuse
Laque moelleuse et volumineuse
Laque moelleuse et volumineuse
Laque moelleuse et volumineuse
Laque moelleuse et volumineuse
51% OFF
Épargnez €19.82
countdiss

Laque moelleuse et volumineuse

€18.98 €38.80
0 ventes
spécification
Quantité

Erhalten Sie dickeres Haar in 60 Sekunden!Flauschiges, voluminöses Haarspray ist ein von Stylisten empfohlenes Haarprodukt für Frauen und Männer.

Se vaporise facilement et donne un fini texturisé multicouche et une tenue légère qui est superbe et dure toute la journée. Notre formule super légère ne laisse pas de résidus collants ou de dépôts comme une mousse ou un spray au sel de mer pour boîte à cheveux, ce qui signifie qu'elle n'alourdit pas les boucles comme d'autres produits !

Parfait pour une utilisation en tant que pré-styler, car il apporte une tenue légère, une définition naturelle et une finition sans effort, ce spray volumineux + épaississant pour cheveux est suffisamment polyvalent pour convenir à tous les types et longueurs de cheveux !

PROPRIÉTÉS :

  • Vaporisateur de volume + de texture - Se vaporise facilement pour donner un fini stratifié et texturisé et offre une tenue légère qui est superbe et dure toute la journée. Les meilleurs sprays volumateurs pour cheveux pour un volume sain et un cuir chevelu propre et heureux !

  • Formule unique non collante - Notre formule super légère ne laisse pas de résidus collants ou de dépôts comme une mousse ou un spray au sel de mer pour boîte à cheveux, ce qui signifie qu'elle n'alourdit pas les boucles comme d'autres produits !

  • Tenue longue durée - Un spray structurant pour cheveux + un spray volumisant sans résidus collants, ce tonique épaississant + structurant pour cheveux se lave proprement et facilement.

  • Facilite le coiffage des cheveux - Parfait pour une utilisation en tant que pré-styliseur, car il apporte une tenue légère, une définition naturelle et une finition sans effort. Ce spray volumateur + épaississant pour cheveux est suffisamment polyvalent pour convenir à tous les types et longueurs de cheveux !

    Superbe pour tous les types de cheveux - Ce spray capillaire premium pour femmes et hommes est l'arme secrète des stylistes professionnels pour obtenir des styles superbes et faciles à utiliser !

 

COMMENT UTILISER ?

  • Laver et soigner les cheveux
  • Appliquer Fluffy Volumizing Hair Spray sur des cheveux LÉGÈREMENT HUMIDES et travailler avec les doigts ou un peigne.
  • Séchez à l'air libre pour un volume naturel - ou au sèche-cheveux pour un essorage maximal et un volume 3 fois plus important !

SPÉCIFICATIONS :

  • capacité : 30ml / 100ml

  • durée de vie : 1 an




LE PAQUET CONTIENT :

1 bouteille de laque moelleuse et volumineuse

    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);