B2B WHOLESALE

(function() { 'use strict'; // Commonly used CSS selectors for Lightspeed / Ecwid product grids and out-of-stock indicators const GRID_SELECTOR = '.grid-product, .ec-grid, .grid__products'; const ITEM_SELECTOR = '.grid-product__wrap, .grid-product, .ec-grid__item'; // Selectors or text markers indicating out-of-stock items const OUT_OF_STOCK_SELECTOR = '.grid-product__out-of-stock, .ec-product-option--out-of-stock, .grid-product__sold-out'; let isSorting = false; function moveOutOfStockToBottom() { if (isSorting) return; const grid = document.querySelector(GRID_SELECTOR); if (!grid) return; const items = Array.from(grid.querySelectorAll(ITEM_SELECTOR)); if (items.length === 0) return; // Separate items into in-stock vs out-of-stock const inStockItems = []; const outOfStockItems = []; items.forEach(item => { // Check for out-of-stock class or "Sold Out" text within the item const hasOOSClass = item.querySelector(OUT_OF_STOCK_SELECTOR); const hasOOSText = /out of stock|sold out/i.test(item.innerText); if (hasOOSClass || hasOOSText) { outOfStockItems.push(item); } else { inStockItems.push(item); } }); // Only re-order if there are out-of-stock items mixed in if (outOfStockItems.length > 0 && inStockItems.length > 0) { isSorting = true; // Re-append items to DOM: in-stock first, then out-of-stock at the end const fragment = document.createDocumentFragment(); inStockItems.forEach(item => fragment.appendChild(item)); outOfStockItems.forEach(item => fragment.appendChild(item)); grid.appendChild(fragment); // Cooldown to prevent infinite loops triggered by MutationObserver setTimeout(() => { isSorting = false; }, 300); } } // Hook into Ecwid's native lifecycle event if (window.Ecwid) { window.Ecwid.OnPageLoaded.add(function(page) { if (page.type === "CATEGORY" || page.type === "SEARCH") { setTimeout(moveOutOfStockToBottom, 400); } }); } // DOM Observer to handle dynamic content loads (e.g., Infinite Scroll) const observer = new MutationObserver(() => { if (!isSorting) { moveOutOfStockToBottom(); } }); // Start watching document body after initial DOM ready document.addEventListener('DOMContentLoaded', () => { setTimeout(moveOutOfStockToBottom, 500); observer.observe(document.body, { childList: true, subtree: true }); }); })();