糖心传媒

Skip to content

Your cart is empty

Continue shopping

Have an account?

Log in to check out faster.

Your cart

Loading...

Estimated total

$0.00

Taxes, discounts and shipping calculated at checkout.
View Cart

There was an error while updating your cart. Please try again.

Up to 30% Off BridalSHOP NOW

Find a Store Financing
Web Support: 1-888-402-3475
    Web Support1-888-402-3475
    Find a Store Financing
    Log in
    Riddle's Jewelry
      Log in Cart
      00 items

      STORE INFORMATION

      • sales@riddlesjewelry.com
      • 1-888-402-3475
      • Contact
      • Store locator

      MY ACCOUNT

      • Wishlist
      • Manage Your Privacy Choices

      OUR COMPANY

      • About Us
      • Careers
      • Diamond Guarantee
      • Jewelry Warranty
      • Watch Warranty
      • Theft Plan
      • Legal Notice

      FAQS

      • Financing Options
      • Returns & Exchanges
      • Repairs & Inspections
      • Shipping information
      • Diamond knowledge
      • Ring size chart
      Riddle's Jewelry
      Get exclusive offers in your inbox
      Riddle's Jewelry
      ? 2021-2026 BY RIDDLE'S GROUP INC. ?PRIVACY POLICY ?SITEMAP
      • Choosing a selection results in a full page refresh.
      • Opens in a new window.
      — those keep /

      糖心传媒

      pinned at // `overflow:hidden`, so window.scrollY never changes and the icon would be // stuck at its default color forever. `scrollEl` tracks whichever element // actually receives scroll events; falls back to window when nothing else does. var scrollEl = null; function currentScrollTop() { // Never trust scrollEl exclusively — if it was ever mis-detected (a // transient element present only at page-load) its scrollTop stays stuck // at 0 forever and would otherwise permanently override a perfectly good // window.scrollY reading on themes where the window itself scrolls // normally. Taking whichever is larger means a wrong guess can never // suppress the real value, on any theme. var winTop = window.scrollY || document.documentElement.scrollTop || document.body.scrollTop || 0; var elTop = scrollEl ? scrollEl.scrollTop : 0; return Math.max(winTop, elTop); } // Best-effort seed in case the page loads already scrolled inside a // non-window container — the capture-phase listener below self-corrects // for everything after the first real scroll, this just avoids a flash // of the wrong color before that happens. function detectScrollContainer() { var all = document.body.querySelectorAll('*'); for (var i = 0; i < all.length; i++) { var el = all[i]; var cs = getComputedStyle(el); if (cs.overflowY !== 'auto' && cs.overflowY !== 'scroll') continue; if (el.scrollHeight <= el.clientHeight + 50) continue; if (el.clientHeight <= window.innerHeight * 0.5) continue; // Reject hidden/off-canvas elements (e.g. a closed mobile nav submenu) — // they can satisfy the size checks above while never actually being the // thing the shopper scrolls, and unlike a mis-detected *visible* element // they never self-correct via a real scroll event either. if (cs.visibility === 'hidden' || cs.display === 'none') continue; var r = el.getBoundingClientRect(); if (r.right <= 0 || r.left >= window.innerWidth || r.bottom <= 0 || r.top >= window.innerHeight) continue; return el; } return null; } function isHomePage() { // Set server-side from Liquid's request.page_type — reliable regardless of // locale-prefixed URLs (e.g. /en, /fr) where pathname/body-class checks fail. if (root.dataset.isHomePage) return root.dataset.isHomePage === 'true'; if (window.Shopify && window.Shopify.template) return window.Shopify.template === 'index'; if (document.body.classList.contains('template-index')) return true; var p = window.location.pathname; return p === '/' || p === ''; } function isMenuOpen() { // Many themes force the header to a solid background while a nav // dropdown/mega-menu is open (via CSS reacting to aria-expanded), // independent of actual scroll position — without this check the icon // is left in its transparent-header color, invisible against the // now-solid backdrop. return !!document.querySelector('header [aria-expanded="true"], nav [aria-expanded="true"], [role="navigation"] [aria-expanded="true"]'); } function updateScrollState() { // Non-home pages: only pin to the static otherPagesColor choice when the // merchant restricted scroll-based switching to the home page. if (scrollHomePageOnly && !isHomePage()) { root.classList.toggle('wh-scrolled', otherPagesColor === 'scrolled'); return; } // Otherwise (home page, or homePageOnly is off): switch based on real scroll position. var scrolled = currentScrollTop() > scrollThreshold || isMenuOpen(); root.classList.toggle('wh-scrolled', scrolled); } function handleScroll(e) { // Scroll events don't bubble, but capturing on document catches them from // any descendant scroll container too — that's how we learn which element // (if any besides window) is the one actually scrolling on this theme. // Requiring genuine vertical overflow (not just a numeric scrollTop) is // essential here — horizontal-only widgets (image carousels, trust-badge // strips, etc.) have scrollHeight === clientHeight but still fire real // 'scroll' events as they auto-scroll sideways. Without this check any of // them can hijack scrollEl away from the real page container and pin it // at scrollTop 0 forever, permanently stranding the icon in its // not-scrolled color no matter how far the page itself has scrolled. var target = e && e.target; if (target && target !== document && target !== window && target !== document.documentElement && target !== document.body && typeof target.scrollTop === 'number' && target.scrollHeight > target.clientHeight + 50) { scrollEl = target; } updateScrollState(); } if (scrollColorsEnabled) { scrollEl = detectScrollContainer(); window.addEventListener('scroll', handleScroll, { passive: true }); document.addEventListener('scroll', handleScroll, { passive: true, capture: true }); updateScrollState(); // Re-check when any nav item's expanded state changes (mega-menu open/close) new MutationObserver(updateScrollState).observe(document.body, { attributes: true, attributeFilter: ['aria-expanded'], subtree: true, }); } // ── INIT ───────────────────────────────────────────────────────────────── // Launch mode is confirmed by Liquid server-side (wh_launch_mode == 'Header'), // so no API fetch or async mode check is needed here. function init() { root.style.display = ''; fetchCount(); // True once the icon has been relocated into its header slot. function isPlaced() { var slot = root.closest('[data-wl-slot]'); return !!(slot && document.contains(root)); } // Safe to call repeatedly — relocateIcon() no-ops once we're already placed. function place() { if (!isPlaced()) relocateIcon(); if (scrollColorsEnabled) updateScrollState(); } // Fast attempts, plus later backstops. On slow devices/networks the theme // header (e.g. Prestige's custom element) may not be laid out // until well after 2.5s. Without the later retries the icon is stranded at // the bottom of

      糖心传媒

      and never appears in the header — which is why it // showed up on some phones but not others. function scheduleAttempts() { place(); [400, 1000, 2500, 4000, 8000, 15000].forEach(function (ms) { setTimeout(place, ms); }); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', scheduleAttempts); } else { scheduleAttempts(); } // Resilient watcher: // ? re-inject if the theme removes our icon (SPA nav / header re-render), and // ? keep hunting for the cart icon until we are actually placed — this is what // makes the header icon appear reliably regardless of how slowly the device // renders the header. var debounce = null; var stopHuntAt = Date.now() + 20000; // stop actively hunting after 20s new MutationObserver(function () { if (!document.contains(root)) { // Icon was removed by a theme re-render — put it back. clearTimeout(debounce); debounce = setTimeout(place, 100); } else if (!isPlaced() && Date.now() < stopHuntAt) { // Still stranded (cart wasn't ready during the timed attempts) — retry as // the header mutates its way into existence. clearTimeout(debounce); debounce = setTimeout(place, 120); } }).observe(document.body, { childList: true, subtree: true }); } init(); })();