Flameless Bat Candle Holders for a Safer H – LED, Everyday Comfort, Was $44, Save 16%

$36.99
$43.99
-$7.00
/** * 优惠码组件模型类 * 处理优惠码的显示和交互逻辑 */ class SpzCustomDiscountCodeModel extends SPZ.BaseElement { constructor(element) { super(element); // 复制按钮和内容的类名 this.copyBtnClass = "discount_code_btn" this.copyClass = "discount_code_value" } isLayoutSupported(layout) { return layout == SPZCore.Layout.LOGIC; } buildCallback() { // 初始化服务 this.action_ = SPZServices.actionServiceForDoc(this.element); this.templates_ = SPZServices.templatesForDoc(this.element); this.xhr_ = SPZServices.xhrFor(this.win); } /** * 渲染优惠码组件 * @param {Object} data - 渲染数据 */ doRender_(data) { return this.templates_ .findAndRenderTemplate(this.element, Object.assign(this.getDefaultData(), data) ) .then((el) => { this.clearDom(); this.element.appendChild(el); // 绑定复制代码功能 this.copyCode(el, data); }); } /** * 获取渲染模板 * @param {Object} data - 渲染数据 */ getRenderTemplate(data) { const renderData = Object.assign(this.getDefaultData(), data); return this.templates_ .findAndRenderTemplate(this.element, renderData) .then((el) => { this.clearDom(); return el; }); } /** * 清除DOM内容 */ clearDom() { const children = this.element.querySelector('*:not(template)'); children && SPZCore.Dom.removeElement(children); } /** * 获取默认数据 * @returns {Object} 默认数据对象 */ getDefaultData() { return { isMobile: appDiscountUtils.judgeMobile(), isRTL: appDiscountUtils.judgeRTL(), image_domain: this.win.SHOPLAZZA.image_domain, copyBtnClass: this.copyBtnClass, copyClass: this.copyClass } } /** * 复制优惠码功能 * @param {Element} el - 当前元素 */ copyCode(el) { const copyBtnList = el.querySelectorAll(`.${this.copyBtnClass}`); if (copyBtnList.length > 0) { copyBtnList.forEach(item => { item.onclick = async () => { // 确保获取正确的元素和内容 const codeElement = item.querySelector(`.${this.copyClass}`); if (!codeElement) return; // 获取纯文本内容 const textToCopy = codeElement.innerText.trim(); // 尝试使用现代API,如果失败则使用备用方案 try { if (navigator.clipboard && navigator.clipboard.writeText) { await navigator.clipboard.writeText(textToCopy); } else { throw new Error('Clipboard API not available'); } // 显示复制成功提示 this.showCopySuccessToast(textToCopy, el); } catch (err) { console.error('Modern clipboard API failed, trying fallback...', err); // 使用备用复制方案 this.fallbackCopy(textToCopy, el); } const discountId = item.dataset["discountId"]; // 跳转决策: is_redirection + link(可选覆盖) const setting = { is_redirection: item.dataset["redirection"] === "true", link: item.dataset["link"], }; const landingUrl = `/promotions/discount-default/${discountId}`; const finalUrl = appDiscountUtils.resolveDiscountHref(setting, landingUrl); if (finalUrl && appDiscountUtils.inProductBody(this.element)) { this.win.open(finalUrl, '_blank', 'noopener'); } } }) } } /** * 使用 execCommand 的复制方案 * @param {string} codeText - 要复制的文本 * @param {Element} el - 当前元素 */ fallbackCopy(codeText, el) { const textarea = this.win.document.createElement('textarea'); textarea.value = codeText; // 设置样式使文本框不可见 textarea.style.position = 'fixed'; textarea.style.left = '-9999px'; textarea.style.top = '0'; // 添加 readonly 属性防止移动端虚拟键盘弹出 textarea.setAttribute('readonly', 'readonly'); this.win.document.body.appendChild(textarea); textarea.focus(); textarea.select(); try { this.win.document.execCommand('copy'); // 显示复制成功提示 this.showCopySuccessToast(codeText, el); } catch (err) { console.error('Copy failed:', err); } this.win.document.body.removeChild(textarea); } /** * 创建 Toast 元素 * @returns {Element} 创建的 Toast 元素 */ createToastEl_() { const toast = document.createElement('ljs-toast'); toast.setAttribute('layout', 'nodisplay'); toast.setAttribute('hidden', ''); toast.setAttribute('id', 'discount-code-toast'); toast.style.zIndex = '1051'; return toast; } /** * 挂载 Toast 元素到 body * @returns {Element} 挂载的 Toast 元素 */ mountToastToBody_() { const existingToast = this.win.document.getElementById('discount-code-toast'); if (existingToast) { return existingToast; } const toast = this.createToastEl_(); this.win.document.body.appendChild(toast); return toast; } /** * 复制成功的提醒 * @param {string} codeText - 要复制的文本 * @param {Element} el - 当前元素 */ showCopySuccessToast(codeText, el) { const $toast = this.mountToastToBody_(); SPZ.whenApiDefined($toast).then(toast => { toast.showToast("Discount code copied !"); this.codeCopyInSessionStorage(codeText); }); } /** * 复制优惠码成功后要存一份到本地存储中,购物车使用 * @param {string} codeText - 要复制的文本 */ codeCopyInSessionStorage(codeText) { try { sessionStorage.setItem('other-copied-coupon', codeText); } catch (error) { console.error(error) } } } // 注册自定义元素 SPZ.defineElement('spz-custom-discount-code-model', SpzCustomDiscountCodeModel);
/** * Custom discount code component that handles displaying and managing discount codes * @extends {SPZ.BaseElement} */ class SpzCustomDiscountCode extends SPZ.BaseElement { constructor(element) { super(element); // API endpoint for fetching discount codes this.getDiscountCodeApi = "\/api\/storefront\/promotion\/code\/list"; // Debounce timer for resize events this.timer = null; // Current variant ID this.variantId = "ec333d3a-765b-4c88-8075-6bb982cb06d7"; // Store discount code data this.discountCodeData = {} } /** * Check if layout is supported * @param {string} layout - Layout type * @return {boolean} */ isLayoutSupported(layout) { return layout == SPZCore.Layout.LOGIC; } /** * Initialize component after build */ buildCallback() { this.templates_ = SPZServices.templatesForDoc(); this.viewport_ = this.getViewport(); // Bind methods to maintain context this.render = this.render.bind(this); this.resize = this.resize.bind(this); this.switchVariant = this.switchVariant.bind(this); } /** * Setup component when mounted */ mountCallback() { this.getData(); // Add event listeners this.viewport_.onResize(this.resize); this.win.document.addEventListener('dj.variantChange', this.switchVariant); } /** * Cleanup when component is unmounted */ unmountCallback() { this.viewport_.removeResize(this.resize); this.win.document.removeEventListener('dj.variantChange', this.switchVariant); // 清除定时器 if (this.timer) { clearTimeout(this.timer); this.timer = null; } } /** * Handle resize events with debouncing */ resize() { if (this.timer) { clearTimeout(this.timer) this.timer = null; } this.timer = setTimeout(() => { if (appDiscountUtils.inProductBody(this.element)) { this.render(); } else { this.renderSkeleton(); } }, 200); } /** * Handle variant changes * @param {Event} event - Variant change event */ switchVariant(event) { const variant = event.detail.selected; if (variant.product_id == 'eaeabea1-2bbe-4b8b-b017-ddc6dc8dd3c4' && variant.id != this.variantId) { this.variantId = variant.id; this.getData(); } } /** * Fetch discount code data from API */ getData() { if (appDiscountUtils.inProductBody(this.element)) { const reqBody = { product_id: "eaeabea1-2bbe-4b8b-b017-ddc6dc8dd3c4", variant_id: this.variantId, product_type: "default", } if (!reqBody.product_id || !reqBody.variant_id) return; this.discountCodeData = {}; this.win.fetch(this.getDiscountCodeApi, { method: "POST", body: JSON.stringify(reqBody), headers: { "Content-Type": "application/json" } }).then(async (response) => { if (response.ok) { let data = await response.json(); if (data.list && data.list.length > 0) { data.list[0].product_setting.template_config = JSON.parse(data.list[0].product_setting.template_config); // Format timestamps to local timezone const zone = this.win.SHOPLAZZA.shop.time_zone; data.list = data.list.map(item => { if(+item.ends_at !== -1) { item.ends_at = appDiscountUtils.convertTimestampToFormat(+item.ends_at, zone); } item.starts_at = appDiscountUtils.convertTimestampToFormat(+item.starts_at, zone); return item; }); } this.discountCodeData = data; this.render(); } else { this.clearDom(); } }).catch(err => { console.error("discount_code", err) this.clearDom(); }); } else { this.renderSkeleton(); } } /** * Clear component DOM except template */ clearDom() { const children = this.element.querySelector('*:not(template)'); children && SPZCore.Dom.removeElement(children); } /** * Render discount codes with formatted dates */ render() { // Render using discount code model SPZ.whenApiDefined(document.querySelector('#spz_custom_discount_code_model')).then(renderApi => { renderApi.doRender_({ discountCodeData: this.discountCodeData }) }).catch(err => { this.clearDom(); }) } renderSkeleton() { // Render template for non-product pages this.templates_ .findAndRenderTemplate(this.element, { isMobile: appDiscountUtils.judgeMobile() }) .then((el) => { this.clearDom(); this.element.appendChild(el); }) .catch(err => { this.clearDom(); }); } } // Register custom element SPZ.defineElement('spz-custom-discount-code', SpzCustomDiscountCode);
Quantity
Free worldwide shipping
Free returns
Sustainably made
Secure payments

Description

🎃 Halloween Decor That Looks Done in Seconds

Give your table, mantel, or entryway an instant Halloween upgrade without rearranging the whole room. The bat-shaped holders, realistic flameless candle look, and warm cutout glow create a finished seasonal display that feels intentional, cozy, and photo-ready.

🛡️ Enjoy the Candle Look Without the Open Flame

Get the Halloween candle atmosphere without relying on real flames near pumpkins, fabric, leaves, or tabletop decor. The flameless LED design gives you the warm glow people love while helping reduce the everyday fire-risk concerns of traditional candles.

🌙 Set the Mood for Halloween Nights

Turn any shelf, console table, or window area into a cozy Halloween scene after dark. The soft candlelight effect and glowing bat cutouts add just enough spooky charm to make the room feel festive, without making your decor look overdone.

✨ Tiny Star Cutouts, Big Cozy Impact

The glowing star cutouts create a warm twinkling effect across the bat wings, giving the piece more visual interest than ordinary candle holders. It catches attention up close and adds a subtle Halloween glow from across the room.

🕯️ Style Your Display in Two Simple Steps

Just insert the taper candle and place it where you want the Halloween glow. No complicated setup, no messy wax, and no decorating guesswork—an easy way to make your seasonal display look polished fast.

🖤 A Sturdy Base That Keeps the Look Clean

The solid round base helps the holders sit neatly on mantels, countertops, entry tables, and shelves. It keeps the display looking balanced and intentional, so your Halloween setup feels styled instead of cluttered.

⭐ Customer Reviews

⭐⭐⭐⭐⭐ “These made my entryway look instantly ready for Halloween. The bat shape is cute but still classy, and the warm glow looks great at night.”
— Amanda R.

⭐⭐⭐⭐⭐ “I wanted Halloween candles without worrying about open flames near decorations. These give the look I wanted without the stress of real candles.”
— Kelly M.

⭐⭐⭐⭐⭐ “The little star cutouts are my favorite part. They glow softly and make the whole setup feel cozy without being too over-the-top.”
— Brian T.

⭐⭐⭐⭐⭐ “I placed them on my mantel with pumpkins and black mesh, and it looked like I actually spent time styling everything. Super easy seasonal decor.”
— Nicole S.

❓ Questions?

Q: Are these real candles with an actual flame?
A: No. They are electronic flameless candles designed to create a realistic candlelit look without an open flame.

Q: Is this safer than using traditional Halloween candles?
A: It helps reduce the worry of open flames near pumpkins, fabric, leaves, and seasonal decor. You still get the Halloween glow without lighting a real candle.

Q: What makes this good for Halloween decorating?
A: The black bat-shaped holders, bat-pattern candle look, and glowing star cutouts create an instant spooky-season display.

Q: Where can I place them?
A: They are ideal for mantels, entry tables, console tables, shelves, countertops, party tables, and Halloween home displays.

Q: Is this a set of two?
A: Yes. The set includes two bat candle holders, making it easy to create a balanced Halloween display.

Q: Do I need to assemble or install anything?
A: No complicated setup is needed. Simply place the candle into the holder and style it wherever you want a Halloween glow.

Q: Is it good for homes with kids or pets?
A: It is a more worry-free option than open-flame candles. As with any decorative item, keep it placed securely and out of reach of small children or pets.

Q: Does it look too childish or too spooky?
A: No. The bat design feels festive, while the black finish and warm glow keep it stylish enough for adult home decor.

📏 Product Specifications

Product Type: Flameless Halloween candle holder set
Theme: Halloween, bat, spooky seasonal decor
Light Style: Electronic flameless candle look
Design: Black bat-shaped holders with glowing star cutouts
Candle Look: White taper-style candles with black bat details
Display Style: Set of 2 for a balanced tabletop arrangement
Best For: Mantels, entryways, shelves, countertops, party tables, and seasonal displays
Season: Halloween and fall decor
Setup: Easy tabletop placement, no complicated installation required
Use Type: Indoor decorative use
Key Benefit: Creates a candlelit Halloween mood without an open flame

📦 What’s Included

2 Bat Candle Holders Included
2 Matching Flameless Taper-Style Candles Included