🎅(Early Christmas Sale - Save 50% OFF) Funny Cute Cat-Shaped Ball
🎅(Early Christmas Sale - Save 50% OFF) Funny Cute Cat-Shaped Ball
🎅(Early Christmas Sale - Save 50% OFF) Funny Cute Cat-Shaped Ball
🎅(Early Christmas Sale - Save 50% OFF) Funny Cute Cat-Shaped Ball
🎅(Early Christmas Sale - Save 50% OFF) Funny Cute Cat-Shaped Ball
🎅(Early Christmas Sale - Save 50% OFF) Funny Cute Cat-Shaped Ball
🎅(Early Christmas Sale - Save 50% OFF) Funny Cute Cat-Shaped Ball
1/7
🎅(Early Christmas Sale - Save 50% OFF) Funny Cute Cat-Shaped Ball
🎅(Early Christmas Sale - Save 50% OFF) Funny Cute Cat-Shaped Ball
🎅(Early Christmas Sale - Save 50% OFF) Funny Cute Cat-Shaped Ball
🎅(Early Christmas Sale - Save 50% OFF) Funny Cute Cat-Shaped Ball
🎅(Early Christmas Sale - Save 50% OFF) Funny Cute Cat-Shaped Ball
🎅(Early Christmas Sale - Save 50% OFF) Funny Cute Cat-Shaped Ball
🎅(Early Christmas Sale - Save 50% OFF) Funny Cute Cat-Shaped Ball
1/7

🎅(Early Christmas Sale - Save 50% OFF) Funny Cute Cat-Shaped Ball

The current produc does not participate any Rebate. Switch the participating product to check the design.
(This prompt will not be displayed on the client-side.)
if(window.self === window.top) { (window.disabled_exts ||=[]).push('product_detail_rebate'); } class SpzRebateComponent extends SPZ.BaseElement { constructor(element) { super(element); } xhr_ = SPZServices.xhrFor(this.win); viewport_ = this.getViewport(); action_ = null; lang = document.documentElement.lang || 'en-US'; landPage = "\/promotions\/rebate\/"; pageType = 1; cart = []; initData = null; rebateInfo = null; renderData = null; footerImage = `${this.win.SHOPLAZZA["image_domain"]}oss/operation/e8ebb03dbb710457ca3b4b6a70898ab2.svg`; isLayoutSupported(layout) { return layout == SPZCore.Layout.LOGIC; } buildCallback() { this.initData = this.getProduct(); this.action_ = SPZServices.actionServiceForDoc(this.element); this.registerAction("triggerGetRenderData", () => { const event = SPZUtils.Event.create(this.win, "triggerGetRenderData", this.renderData); this.action_.trigger(this.element, "getRenderData", event); }); this.registerAction("bindPropagation", () => { document.querySelector(".product_detail_rebate_list").addEventListener("click", e => { e.stopPropagation(); this.win.sa && this.win.sa.track("plugin_rebate_promotion_click", { plugin_timestamp: Date.now(), plugin_location: "info", product_id: this.initData.product.id, discount_id: this.rebateInfo.discount_list.map((item) => item.discount_id)[0], }); }); }); } async mountCallback() { document.addEventListener("dj.variantChange", e => { const data = e.detail; if (document.querySelector("#product-select-modal.show")) return; if (this.initData && this.initData.product && data.product && this.initData.product.id === data.product.id) { this.initData = data; this.initRebate(this.initData, true); } else { this.initData = data; this.getRebateInfo(); } }); document.addEventListener("dj.addToCart", e => { const v = e.detail; this.rebateInfo && this.win.sa && this.win.sa.track("plugin_rebate_atc", { variant_discount_id: this.getVariantDiscountId(v.variant_id).map(item => item.discount_id), discount_ids: this.rebateInfo.discount_list.map(item => item.discount_id), variant_id: v.variant_id, product_id: v.product_id, price: v.item_price, number: v.number, }); }); await this.getRebateInfo(); if (document.querySelector(".plugin-container__bottom-fixed")) { this.showDiscountPopupsInfoBar(); } else { this.win.addEventListener("extloaded", () => { this.showDiscountPopupsInfoBar(); }); } } getProduct = (() => { document.addEventListener("dj.variantChange", e => { if (!e.detail || !e.detail.product) return; const productJson = document.querySelector("#product-json"); if (productJson && productJson.textContent && JSON.parse(productJson.textContent)) { productJson.textContent = JSON.stringify(e.detail); } if (this.win.jQuery && this.win.jQuery.fn && this.win.jQuery(document).data("djproduct")) { this.win.jQuery(document).data("djproduct", e.detail); } }); return () => { let productData = null; if (this.win.jQuery && this.win.jQuery.fn) { try { let product = this.win.jQuery(document).data("djproduct"); if (product) { productData = JSON.parse(JSON.stringify(product)); } else { productData = null; } } catch (error) { productData = null; } } if (!productData) { const productJson = document.querySelector("#product-json"); productData = (productJson && productJson.textContent && JSON.parse(productJson.textContent)) || null; } return productData; }; })(); initRebate = this.win.SPZCore.Types.debounce( this.win, (async (data, variantChange) => { let discount_list = Object.assign([], this.rebateInfo.discount_list); /* 按子商品的多少对优惠信息进行排序 */ discount_list && discount_list.sort((a, b) => { return b.variant_ids.length - a.variant_ids.length; }); /* 选中子商品时 筛选子商品的优惠信息 */ if (data.selected && data.selected.id) { discount_list = this.getVariantDiscountId(data.selected.id); } /* 无满减信息 */ if (!(discount_list && discount_list.length)) { return; } const isSection = !!document.querySelector( `div[data-section-type^="shoplazza://apps/publicapp/blocks/rebate"] #rebate_custom_component` ); if ( (this.rebateInfo.rebate_type == "sku" && data && data.selected && data.selected.id) || this.rebateInfo.rebate_type == "spu" ) { let nowLandpage = this.landPage; if (discount_list[0]) { nowLandpage = this.landPage + discount_list[0].discount_id || ""; } const info = { rebate: discount_list[0], maxShowCount: this.win.innerWidth > 768 ? 3 : 1, landPage: nowLandpage, modalFooterImg: `url(${`${this.win.SHOPLAZZA["image_domain"]}oss/operation/e8ebb03dbb710457ca3b4b6a70898ab2.svg`})`, }; this.renderData = info; if(isSection) { SPZ.whenApiDefined( document.getElementById("app_rebate_section") ).then(apis => { apis.render(info, true); }); } else { // 重新渲染 抖动问题处理 this.templates_ = SPZServices.templatesForDoc(); const newTplDom = await this.templates_.renderTemplate(document.querySelector('#appRebateBlockTpl'), info) const parentDiv = document.querySelector('#app_rebate_block'); const oldDom = parentDiv.querySelector('.app_rebate_list'); if(oldDom){ parentDiv.replaceChild(newTplDom, oldDom); } else { parentDiv.appendChild(newTplDom); } } } this.insertSlideTag(this.rebateInfo.tag, variantChange); var pluginCurrencyEvent = new CustomEvent("plugin_currency_update"); document.dispatchEvent(pluginCurrencyEvent); }).bind(this), 10 ); getRebateInfo = async () => { if (this.initData && this.initData.product && this.initData.product.id) { var variant_ids = this.initData.product.variants.map(variant => variant.id); const res = await this.xhr_.fetchJson( "\/api\/discount-rebate\/product-discount", { method: "POST", body: { product_id: this.initData.product.id, product_type: this.initData.product.product_type, variant_ids: variant_ids, }, } ); if (!SPZCore.Types.isEmptyObject(res.rebate_info)) { res.rebate_info.tag = res.tag; res.rebate_info.rebate_type = res.rebate_type; this.rebateInfo = res.rebate_info; this.initRebate(this.initData); } else { if (this.win.top !== this.win.self) { const noActivity = document.getElementById("no-rebate-activity"); noActivity && (noActivity["style"].display = "block"); } } } }; getVariantDiscountId = (variant_id) => { if (!variant_id || !this.rebateInfo) return []; var rebateId = this.rebateInfo.variant_discount_map[variant_id]; return this.rebateInfo.discount_list.filter(item => item.discount_id == rebateId) || []; }; insertSlideTag = (tag, variantChange) => { setTimeout(() => { if (tag) { var tag_container; var modal = document.getElementById("product-select-modal"); if (modal && modal.classList.contains("show")) { if (!variantChange && modal.querySelector(".slider-discount-tag")) return; if ( variantChange && modal.querySelector(".slider-discount-tag:not(.rebate-tag)") ) return; tag_container = modal; } else { var product_detail_card = document.querySelector( '.page_container > [data-section-type="product_detail"], .page_container > [data-section-type="product-template"]' ); if(!product_detail_card) return; if (!variantChange && product_detail_card.querySelector(".slider-discount-tag")) return; if (variantChange && product_detail_card.querySelector(".slider-discount-tag:not(.rebate-tag)")) return; tag_container = product_detail_card; } if (tag_container.matches("#product-select-modal") && this.pageType === 13 && document.documentElement.clientWidth < 768) return; const tagDom = `<div class="slider-discount-tag dj_skin_product_title rebate-tag">${tag}</div>` if (document.querySelector(".sep-loaded-slider")) { var loadedSlider = tag_container.querySelector(".sep-loaded-slider"); loadedSlider.querySelectorAll(".slider-discount-tag").forEach(function(element) { element.remove(); }); loadedSlider.insertAdjacentHTML("beforeend", tagDom); } else { if (tag_container.querySelector(".support-slick")) { var supportSlick = tag_container.querySelectorAll(".support-slick, .sep-slider"); supportSlick.forEach((element) => { element.querySelectorAll(".slider-discount-tag").forEach((element) => { element.remove(); }); element.insertAdjacentHTML("beforeend",tagDom); }); } else { var sepSlider = tag_container.querySelector(".sep-slider"); sepSlider.querySelectorAll(".slider-discount-tag").forEach(function(element) { element.remove(); }); sepSlider.insertAdjacentHTML("beforeend",tagDom); } } if (document.documentElement.clientWidth < 768) { const sliderDiscountTagHeight = tag_container.querySelector(".slider-discount-tag").offsetHeight || 0; document.querySelector(".product-image__swiper_bullets").style.bottom = `${sliderDiscountTagHeight + 15}px`; } } }, 1000); }; fetchInfoBar = () => { let discount_ids = []; if (this.pageType === 1) { discount_ids = this.rebateInfo && this.rebateInfo.discount_list.map(item => item.discount_id); } else if (this.pageType === 38) { discount_ids = [this.win.rebateObj.rebateCollection_id] || []; } const productObj = this.getProduct(); return this.xhr_.fetchJson("\/api\/discount-rebate\/global-text", { method: "POST", body: { product_type: productObj && productObj.product && productObj.product.product_type, line_items: (this.cart.line_items || []).map(item => ({ variant_id: item.variant_id, product_id: item.product_id, quantity: item.quantity, price: item.price, selected: !item.unchecked, })), discount_ids: discount_ids, }, }); }; renderBottomBanner = res => { if (!res.tips) return; if (document.querySelector(".discount__info-bar")) return; var bar_style = `background:linear-gradient(90deg,${res.config.background_color_start},${res.config.background_color_end}); color:${res.config.color};`; let data = { tips: res.tips, landPage: this.landPage + res.id, bar_style }; const html = SPZCore.Dom.htmlFor(this.element); const banner = html([ `<a impr="1" imprevt="1" id="rebate_bottom_bar" href=${data.landPage} class="discount__info-bar text-truncate" data-activity-type="rebate" style="${data.bar_style}">${data.tips}</a>`, ]); document.querySelector(".plugin-container__bottom-fixed").appendChild(banner); const pluginCurrencyEvent = new CustomEvent("plugin_currency_update"); document.dispatchEvent(pluginCurrencyEvent); if (res.id) { var trackParams = { page: this.pageType, discount_id: res.id, product_id: this.getProduct()?.product.id, }; banner.addEventListener("click", () => { this.win.sa && this.win.sa.track("plugin_rebate_promotion_click", { plugin_timestamp: Date.now(), plugin_location: "bottom_bar", product_id: trackParams.product_id, discount_id: trackParams.discount_id, }); }); this.win.sa && this.win.sa.track("plugin_rebate_banner_pv", trackParams); } }; showDiscountPopupsInfoBar = () => { if ([13, 14, 19, 30, 31].includes(this.pageType)) return; if (document.querySelector(".plugin-container__bottom-fixed .discount__info-bar")) return; this.fetchInfoBar().then(this.renderBottomBanner); document.addEventListener("dj.cartChange", () => { this.fetchInfoBar().then(this.renderBottomBanner); }); }; } SPZ.defineElement("spz-custom-rebate", SpzRebateComponent);
$7.88
$23.64
Save $15.76
⚡Last 159 Pcs Left In Stock⚡
Please select a ⚡last 159 pcs left in stock⚡
Quantity

SPECIAL SALE: ONCE THIS PROMOTION IS OVER, WE WILL BE INCREASING THE PRICE BACK UP TO $15.76

  • 😊If you are not satisfied within 60 days, you can return it for free.
  • 🍭Fast refund>>100% Money Back Guarantee.
  • 🚢Shipping>>Worldwide Express Shipping Available.
  • 🏆Returns>> Fast refund,Money-Back Guarantee.

🎁Don't forget to buy some for your family or friends as it's an unique gift idea.❤️❤️❤️

🐱Feel stressed? This awesome toy can melt your stress away!

🤗A great stress reliever for all ages. Introducing the Funny Cute Cat-Shaped Ball!

We sell this Funny Cute Cat-Shaped Ball at only $7.88. Act fast before sale ends.

  • 😽【High-quality Material】- These Cute Cat-Shaped Balls is made of high quality of TPR, the use of special technology compared with other decompression toys, our toys are non-toxic, harmless and odor-free.

  • 😽Cute Cat Modeling-Best calming stuff and stress relief toys for teens, adults, great gadgets for autistic kids, or people with ADD or ADHD and OCD or high stress/anxiety levels, autism stim toys. By squeezing, stretching and flipping with fidget toys, can relieve anxiety well. And the same time develop the children creation, visual training, desktop fidget toys for adults.

  • 😽【Relieve Stress】- It is very therapeutic, especially for stress reduction. It’s not fun to be bored. You can vent in any shape. It feels super cute and it’s really stress-reducing and fun.

  • 😽【Multi-Scene】- The sized design is just right in the hand,Stress relief and anti-anxiety hand toys, suitable for classrooms, offices, plane, indoors, camping, restaurant, goodie bag fillers, game theme parties, fun birthday party favors, graduation parties, Christmas parties, Halloween, carnival parties, garden parties, etc.

🎁Stress relief gifts

  • The feeling of clenching and not letting go is very good,the soft material can be used in accordance with the mood.
  • Comfortable handle, Easy to use, fun and interesting, pull a pull, squeeze, pinch, press,you unconsciously forget the time pass by.
  • Safe materials, the use of special technology compared with other decompression toys, our toys are non-toxic, harmless and odor-free, With a faint smell of milk, it makes anxious patients feel more pleasant and comfortable, and easy to clean and care.
  • Four colors,with the mood to use.

Please support genuine products, The Funny Cute Cat-Shaped Balls sold in other stores are pirated products, Please look for ours.

Click on "ADD TO CARTto get yours now

🛒 HURRY! Selling out fast!

⚠️ In Stock. Ship ASAP!

 

OUR GUARANTEE

  • 📦 Insured Worldwide Shipping: Each order includes real-time tracking details and insurance coverage in the unlikely event that a package gets lost or stolen in transit.
  • 💰 Money-Back Guarantee: If your items arrive damaged or become defective within 30 days of normal usage, we will gladly issue out a replacement or refund.
  • ✉️ 24/7 Customer Support: We have a team of live reps ready to help and answer any questions you have within a 24-hour time frame, 7 days a week.

HOW TO PAY

If you want to Pay with Debit or Credit Card, please click "Buy With PayPal" first, then click "Pay with Debit or Credit Card".
Enter your Payment details, your Billing Address, and your Contact Information.

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('appzebu 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);