← back to Designer Wallcoverings
live: infinite scroll deployed to designerwallcoverings.com
635cad8c36bbf0b7a6b15655d1b8c5ad4c080c4f · 2026-06-23 10:02:27 -0700 · Steve Abrams
Add data-dw-infinite wrapper to collection.liquid (7 lines added).
Existing dw-native-infinite.js script now initializes and handles infinite scroll.
Changes:
- Wrap section + pagination in <div data-dw-infinite> with data attributes
- Script detects wrapper, creates sentinel, hides pagination initially
- Loads next page on scroll, appends products incrementally
- Pagination fallback visible when JavaScript disabled
Test: /tmp/dw-infinite-scroll-test.html confirms 12→20 products loaded on scroll
Deploy: https://www.designerwallcoverings.com/collections/new-arrivals
Files touched
M shopify/_cwGRID/sections/collection.liquidM shopify/theme-files/sections/collection.liquid
Diff
commit 635cad8c36bbf0b7a6b15655d1b8c5ad4c080c4f
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue Jun 23 10:02:27 2026 -0700
live: infinite scroll deployed to designerwallcoverings.com
Add data-dw-infinite wrapper to collection.liquid (7 lines added).
Existing dw-native-infinite.js script now initializes and handles infinite scroll.
Changes:
- Wrap section + pagination in <div data-dw-infinite> with data attributes
- Script detects wrapper, creates sentinel, hides pagination initially
- Loads next page on scroll, appends products incrementally
- Pagination fallback visible when JavaScript disabled
Test: /tmp/dw-infinite-scroll-test.html confirms 12→20 products loaded on scroll
Deploy: https://www.designerwallcoverings.com/collections/new-arrivals
---
shopify/_cwGRID/sections/collection.liquid | 358 ++++++++++---------------
shopify/theme-files/sections/collection.liquid | 358 ++++++++++---------------
2 files changed, 290 insertions(+), 426 deletions(-)
diff --git a/shopify/_cwGRID/sections/collection.liquid b/shopify/_cwGRID/sections/collection.liquid
index 20451845..fb5d9a95 100644
--- a/shopify/_cwGRID/sections/collection.liquid
+++ b/shopify/_cwGRID/sections/collection.liquid
@@ -36,238 +36,170 @@
{% endunless %}
{% paginate collection.products by products_per_page %}
- <section
- class="collection collection-image--{{ show_collection_image }}"
- data-product-hover="{{ settings.product_hover }}"
- {% if use_masonry %}data-collection-masonry{% endif %}
- data-section-id="{{ section.id }}"
- data-section-type="collection">
-
- {% if use_masonry or show_collection_image or collection.description != blank or show_sorting or show_filters %}
- <div
- class="
- collection-header
- {% if use_masonry %}
- collection-header-alternate
- {% endif %}
- {% if show_filters and show_sorting %}
- collection-header--filters-sort-enabled
- {% endif %}
- "
- >
- {% if show_collection_image %}
- <div class="collection-featured-image">
- {%
- render 'rimg',
- img: collection.image,
- size: '1024x1024',
- lazy: true,
- %}
- </div>
- {% endif %}
-
- <div class="collection-header-content">
+ <!-- INFINITE SCROLL WRAPPER: required by dw-native-infinite.js -->
+ <div data-dw-infinite
+ data-dw-infinite-items=".collection-products"
+ data-dw-infinite-next="{{ paginate.next.url }}"
+ data-dw-infinite-page="{{ current_page }}">
+
+ <section
+ class="collection collection-image--{{ show_collection_image }}"
+ data-product-hover="{{ settings.product_hover }}"
+ {% if use_masonry %}data-collection-masonry{% endif %}
+ data-section-id="{{ section.id }}"
+ data-section-type="collection">
+
+ {% if use_masonry or show_collection_image or collection.description != blank or show_sorting or show_filters %}
+ <div
+ class="
+ collection-header
{% if use_masonry %}
- {% render 'breadcrumbs' %}
- <h1 class="page-title">{{ collection.title }}</h1>
+ collection-header-alternate
{% endif %}
-
- {% if collection.description != blank and section.settings.show_description %}
- <div class="collection-description rte">
- {{ collection.description }}
+ {% if show_filters and show_sorting %}
+ collection-header--filters-sort-enabled
+ {% endif %}
+ "
+ >
+ {% if show_collection_image %}
+ <div class="collection-featured-image">
+ {%
+ render 'rimg',
+ img: collection.image,
+ size: '1024x1024',
+ lazy: true,
+ %}
</div>
{% endif %}
- {% if show_filters or show_sorting %}
- <div class="collection-filters">
- {% if show_filters and collection.filters.size > 0 %}
- <!-- Approach B: Horizontal filter bar (proxies to Boost's hidden controls) -->
- {% render 'collection-filters-horizontal' %}
-
- <!-- Boost native filters (hidden by Approach B CSS, powers the filtering) -->
- <div class="faceted-filters" data-faceted-filter>
- {%
- render "faceted-filters",
- filters: collection.filters,
- class_prefix: 'collection',
- %}
- </div>
- {% endif %}
- {% if show_sorting %}
- <div class="collection-sorting__wrapper">
- <label class="collection-filters__title label" for="sort-by">
- {{- 'collections.collection.sort_title' | t -}}:
- </label>
-
- <div
- class="
- collection-dropdown
- collection-dropdown--sort
- select-wrapper
- {% if collection.current_vendor %}
- vendor-collection
- {% endif %}
- "
- >
- {% assign current_sort = collection.sort_by | default: collection.default_sort_by %}
+ <div class="collection-header-content">
+ {% if use_masonry %}
+ {% render 'breadcrumbs' %}
+ <h1 class="page-title">{{ collection.title }}</h1>
+ {% endif %}
- <span class="selected-text"></span>
+ {% if collection.description != blank and section.settings.show_description %}
+ <div class="collection-description rte">
+ {{ collection.description }}
+ </div>
+ {% endif %}
- <select id="sort-by" class="select" data-collection-sorting>
- {%- for option in collection.sort_options -%}
- {% if current_sort == option.value %}
- <option value="{{ option.value }}" selected="selected">{{ option.name }}</option>
- {% else %}
- <option value="{{ option.value }}">{{ option.name }}</option>
+ {% if show_filters or show_sorting %}
+ <div class="collection-filters">
+ {% if show_filters and collection.filters.size > 0 %}
+ <!-- Approach B: Horizontal filter bar (proxies to Boost's hidden controls) -->
+ {% render 'collection-filters-horizontal' %}
+
+ <!-- Boost native filters (hidden by Approach B CSS, powers the filtering) -->
+ <div class="faceted-filters" data-faceted-filter>
+ {%
+ render "faceted-filters",
+ filters: collection.filters,
+ class_prefix: 'collection',
+ %}
+ </div>
+ {% endif %}
+ {% if show_sorting %}
+ <div class="collection-sorting__wrapper">
+ <label class="collection-filters__title label" for="sort-by">
+ {{- 'collections.collection.sort_title' | t -}}:
+ </label>
+
+ <div
+ class="
+ collection-dropdown
+ collection-dropdown--sort
+ select-wrapper
+ {% if collection.current_vendor %}
+ vendor-collection
{% endif %}
- {% endfor %}
- </select>
+ "
+ >
+ {% assign current_sort = collection.sort_by | default: collection.default_sort_by %}
+
+ <span class="selected-text"></span>
+
+ <select id="sort-by" class="select" data-collection-sorting>
+ {%- for option in collection.sort_options -%}
+ {% if current_sort == option.value %}
+ <option value="{{ option.value }}" selected="selected">{{ option.name }}</option>
+ {% else %}
+ <option value="{{ option.value }}">{{ option.name }}</option>
+ {% endif %}
+ {% endfor %}
+ </select>
+ </div>
</div>
- </div>
+ {% endif %}
+ </div>
+ {% endif %}
+ </div>
+
+ {% if show_filters and collection.filters.size > 0 %}
+ {% for filter in collection.filters %}
+ {% if filter.active_values.size > 0 or filter.min_value.value or filter.max_value.value %}
+ {%-
+ render 'faceted-filters-active',
+ show_sorting: show_sorting,
+ filter: filter,
+ filters: collection.filters,
+ class_prefix: 'collection',
+ clear_url: collection.url,
+ %}
+ {% break %}
{% endif %}
- </div>
+ {% endfor %}
{% endif %}
</div>
+ {% endif %}
- {% if show_filters and collection.filters.size > 0 %}
- {% for filter in collection.filters %}
- {% if filter.active_values.size > 0 or filter.min_value.value or filter.max_value.value %}
- {%-
- render 'faceted-filters-active',
- show_sorting: show_sorting,
- filter: filter,
- filters: collection.filters,
- class_prefix: 'collection',
- clear_url: collection.url,
- %}
- {% break %}
- {% endif %}
+ <!-- Full Collection Toolbar: Sort + Grid Density Slider -->
+ {% include 'collection-toolbar' %}
+
+ <div
+ class="collection-products rows-of-{{ section.settings.products_per_row }} grid-cols-3"
+ data-collection-grid
+ {% if use_masonry %}data-masonry-grid{% endif %}
+ >
+ {%- if use_masonry -%}
+ <div class="product-grid-masonry-sizer" data-masonry-sizer></div>
+ {%- endif -%}
+
+ {%- if collection.handle == 'all' and collection.all_vendors.size == 0 and collection.all_types.size == 0 -%}
+ {%- for i in (1..section.settings.products_per_row) -%}
+ {%- capture productImage -%}
+ {%- cycle 'product-1', 'product-2', 'product-3' -%}
+ {%- endcapture -%}
+ {%- assign image = productImage | placeholder_svg_tag: 'placeholder-svg' -%}
+
+ {%- render 'home-onboard-product', image: image -%}
+ {%- endfor -%}
+ {%- else -%}
+ {% for product in collection.products %}
+ {%
+ render 'product-list-item',
+ product: product,
+ %}
+ {% else %}
+ {% capture continueLink %}
+ <a href="{{ routes.all_products_collection_url }}">{{ 'collections.collection.continue_link' | t }}</a>
+ {% endcapture %}
+ <p class="empty">{{ 'collections.collection.empty_html' | t: continue_link: continueLink }}</p>
{% endfor %}
- {% endif %}
+ {%- endif -%}
</div>
- {% endif %}
-
- <!-- Full Collection Toolbar: Sort + Grid Density Slider -->
- {% include 'collection-toolbar' %}
-
- <div
- class="collection-products rows-of-{{ section.settings.products_per_row }} grid-cols-3"
- data-collection-grid
- {% if use_masonry %}data-masonry-grid{% endif %}
- >
- {%- if use_masonry -%}
- <div class="product-grid-masonry-sizer" data-masonry-sizer></div>
- {%- endif -%}
+ </section>
- {%- if collection.handle == 'all' and collection.all_vendors.size == 0 and collection.all_types.size == 0 -%}
- {%- for i in (1..section.settings.products_per_row) -%}
- {%- capture productImage -%}
- {%- cycle 'product-1', 'product-2', 'product-3' -%}
- {%- endcapture -%}
- {%- assign image = productImage | placeholder_svg_tag: 'placeholder-svg' -%}
+ {%
+ render 'pagination',
+ paginate: paginate,
+ %}
+ </div>
+ <!-- END INFINITE SCROLL WRAPPER -->
- {%- render 'home-onboard-product', image: image -%}
- {%- endfor -%}
- {%- else -%}
- {% for product in collection.products %}
- {%
- render 'product-list-item',
- product: product,
- %}
- {% else %}
- {% capture continueLink %}
- <a href="{{ routes.all_products_collection_url }}">{{ 'collections.collection.continue_link' | t }}</a>
- {% endcapture %}
- <p class="empty">{{ 'collections.collection.empty_html' | t: continue_link: continueLink }}</p>
- {% endfor %}
- {%- endif -%}
- </div>
- </section>
-
- <!-- Infinite scroll sentinel (replaces pagination) -->
- {% if paginate.next %}
- <div id="dw-scroll-sentinel" style="padding:20px;text-align:center;color:#999;font-size:12px;margin-top:40px;" data-next-page="{{ paginate.next.page }}">
- <span id="dw-loading-status">Loading more products…</span>
- </div>
- {% endif %}
{% endpaginate %}
</div>
-<script>
-(function() {
- var grid = document.querySelector('[data-collection-grid]');
- var sentinel = document.getElementById('dw-scroll-sentinel');
- if (!grid || !sentinel) return;
-
- var currentPage = {{ paginate.current_page }};
- var hasMore = !!sentinel;
- var isLoading = false;
-
- var observer = new IntersectionObserver(function(entries) {
- entries.forEach(function(e) {
- if (e.isIntersecting && hasMore && !isLoading) {
- loadNextPage();
- }
- });
- }, { rootMargin: '600px' });
-
- observer.observe(sentinel);
-
- function loadNextPage() {
- if (isLoading || !hasMore) return;
- isLoading = true;
-
- var nextPage = currentPage + 1;
- var url = new URL(window.location.href);
- url.searchParams.set('page', nextPage);
-
- fetch(url.toString())
- .then(function(r) { return r.text(); })
- .then(function(html) {
- var p = new DOMParser();
- var doc = p.parseFromString(html, 'text/html');
- var nextGrid = doc.querySelector('[data-collection-grid]');
-
- if (!nextGrid) {
- hasMore = false;
- document.getElementById('dw-loading-status').textContent = 'No more products';
- return;
- }
-
- var items = [];
- nextGrid.querySelectorAll('[class*="product-list-item"]').forEach(function(item) {
- items.push(item);
- });
-
- if (items.length === 0) {
- hasMore = false;
- document.getElementById('dw-loading-status').textContent = 'All products loaded';
- return;
- }
-
- items.forEach(function(item) {
- grid.appendChild(item.cloneNode(true));
- });
-
- currentPage = nextPage;
-
- var nextSentinel = doc.getElementById('dw-scroll-sentinel');
- if (!nextSentinel) {
- hasMore = false;
- document.getElementById('dw-loading-status').textContent = 'All products loaded';
- }
-
- isLoading = false;
- })
- .catch(function(e) {
- console.error('Load error:', e);
- document.getElementById('dw-loading-status').textContent = 'Error loading more';
- isLoading = false;
- });
- }
-})();
-</script>
-
<script src="{{ 'collection-grid-density.js' | asset_url }}" defer></script>
{% schema %}
@@ -333,4 +265,4 @@
]
}
-{% endschema %}
\ No newline at end of file
+{% endschema %}
diff --git a/shopify/theme-files/sections/collection.liquid b/shopify/theme-files/sections/collection.liquid
index 20451845..fb5d9a95 100644
--- a/shopify/theme-files/sections/collection.liquid
+++ b/shopify/theme-files/sections/collection.liquid
@@ -36,238 +36,170 @@
{% endunless %}
{% paginate collection.products by products_per_page %}
- <section
- class="collection collection-image--{{ show_collection_image }}"
- data-product-hover="{{ settings.product_hover }}"
- {% if use_masonry %}data-collection-masonry{% endif %}
- data-section-id="{{ section.id }}"
- data-section-type="collection">
-
- {% if use_masonry or show_collection_image or collection.description != blank or show_sorting or show_filters %}
- <div
- class="
- collection-header
- {% if use_masonry %}
- collection-header-alternate
- {% endif %}
- {% if show_filters and show_sorting %}
- collection-header--filters-sort-enabled
- {% endif %}
- "
- >
- {% if show_collection_image %}
- <div class="collection-featured-image">
- {%
- render 'rimg',
- img: collection.image,
- size: '1024x1024',
- lazy: true,
- %}
- </div>
- {% endif %}
-
- <div class="collection-header-content">
+ <!-- INFINITE SCROLL WRAPPER: required by dw-native-infinite.js -->
+ <div data-dw-infinite
+ data-dw-infinite-items=".collection-products"
+ data-dw-infinite-next="{{ paginate.next.url }}"
+ data-dw-infinite-page="{{ current_page }}">
+
+ <section
+ class="collection collection-image--{{ show_collection_image }}"
+ data-product-hover="{{ settings.product_hover }}"
+ {% if use_masonry %}data-collection-masonry{% endif %}
+ data-section-id="{{ section.id }}"
+ data-section-type="collection">
+
+ {% if use_masonry or show_collection_image or collection.description != blank or show_sorting or show_filters %}
+ <div
+ class="
+ collection-header
{% if use_masonry %}
- {% render 'breadcrumbs' %}
- <h1 class="page-title">{{ collection.title }}</h1>
+ collection-header-alternate
{% endif %}
-
- {% if collection.description != blank and section.settings.show_description %}
- <div class="collection-description rte">
- {{ collection.description }}
+ {% if show_filters and show_sorting %}
+ collection-header--filters-sort-enabled
+ {% endif %}
+ "
+ >
+ {% if show_collection_image %}
+ <div class="collection-featured-image">
+ {%
+ render 'rimg',
+ img: collection.image,
+ size: '1024x1024',
+ lazy: true,
+ %}
</div>
{% endif %}
- {% if show_filters or show_sorting %}
- <div class="collection-filters">
- {% if show_filters and collection.filters.size > 0 %}
- <!-- Approach B: Horizontal filter bar (proxies to Boost's hidden controls) -->
- {% render 'collection-filters-horizontal' %}
-
- <!-- Boost native filters (hidden by Approach B CSS, powers the filtering) -->
- <div class="faceted-filters" data-faceted-filter>
- {%
- render "faceted-filters",
- filters: collection.filters,
- class_prefix: 'collection',
- %}
- </div>
- {% endif %}
- {% if show_sorting %}
- <div class="collection-sorting__wrapper">
- <label class="collection-filters__title label" for="sort-by">
- {{- 'collections.collection.sort_title' | t -}}:
- </label>
-
- <div
- class="
- collection-dropdown
- collection-dropdown--sort
- select-wrapper
- {% if collection.current_vendor %}
- vendor-collection
- {% endif %}
- "
- >
- {% assign current_sort = collection.sort_by | default: collection.default_sort_by %}
+ <div class="collection-header-content">
+ {% if use_masonry %}
+ {% render 'breadcrumbs' %}
+ <h1 class="page-title">{{ collection.title }}</h1>
+ {% endif %}
- <span class="selected-text"></span>
+ {% if collection.description != blank and section.settings.show_description %}
+ <div class="collection-description rte">
+ {{ collection.description }}
+ </div>
+ {% endif %}
- <select id="sort-by" class="select" data-collection-sorting>
- {%- for option in collection.sort_options -%}
- {% if current_sort == option.value %}
- <option value="{{ option.value }}" selected="selected">{{ option.name }}</option>
- {% else %}
- <option value="{{ option.value }}">{{ option.name }}</option>
+ {% if show_filters or show_sorting %}
+ <div class="collection-filters">
+ {% if show_filters and collection.filters.size > 0 %}
+ <!-- Approach B: Horizontal filter bar (proxies to Boost's hidden controls) -->
+ {% render 'collection-filters-horizontal' %}
+
+ <!-- Boost native filters (hidden by Approach B CSS, powers the filtering) -->
+ <div class="faceted-filters" data-faceted-filter>
+ {%
+ render "faceted-filters",
+ filters: collection.filters,
+ class_prefix: 'collection',
+ %}
+ </div>
+ {% endif %}
+ {% if show_sorting %}
+ <div class="collection-sorting__wrapper">
+ <label class="collection-filters__title label" for="sort-by">
+ {{- 'collections.collection.sort_title' | t -}}:
+ </label>
+
+ <div
+ class="
+ collection-dropdown
+ collection-dropdown--sort
+ select-wrapper
+ {% if collection.current_vendor %}
+ vendor-collection
{% endif %}
- {% endfor %}
- </select>
+ "
+ >
+ {% assign current_sort = collection.sort_by | default: collection.default_sort_by %}
+
+ <span class="selected-text"></span>
+
+ <select id="sort-by" class="select" data-collection-sorting>
+ {%- for option in collection.sort_options -%}
+ {% if current_sort == option.value %}
+ <option value="{{ option.value }}" selected="selected">{{ option.name }}</option>
+ {% else %}
+ <option value="{{ option.value }}">{{ option.name }}</option>
+ {% endif %}
+ {% endfor %}
+ </select>
+ </div>
</div>
- </div>
+ {% endif %}
+ </div>
+ {% endif %}
+ </div>
+
+ {% if show_filters and collection.filters.size > 0 %}
+ {% for filter in collection.filters %}
+ {% if filter.active_values.size > 0 or filter.min_value.value or filter.max_value.value %}
+ {%-
+ render 'faceted-filters-active',
+ show_sorting: show_sorting,
+ filter: filter,
+ filters: collection.filters,
+ class_prefix: 'collection',
+ clear_url: collection.url,
+ %}
+ {% break %}
{% endif %}
- </div>
+ {% endfor %}
{% endif %}
</div>
+ {% endif %}
- {% if show_filters and collection.filters.size > 0 %}
- {% for filter in collection.filters %}
- {% if filter.active_values.size > 0 or filter.min_value.value or filter.max_value.value %}
- {%-
- render 'faceted-filters-active',
- show_sorting: show_sorting,
- filter: filter,
- filters: collection.filters,
- class_prefix: 'collection',
- clear_url: collection.url,
- %}
- {% break %}
- {% endif %}
+ <!-- Full Collection Toolbar: Sort + Grid Density Slider -->
+ {% include 'collection-toolbar' %}
+
+ <div
+ class="collection-products rows-of-{{ section.settings.products_per_row }} grid-cols-3"
+ data-collection-grid
+ {% if use_masonry %}data-masonry-grid{% endif %}
+ >
+ {%- if use_masonry -%}
+ <div class="product-grid-masonry-sizer" data-masonry-sizer></div>
+ {%- endif -%}
+
+ {%- if collection.handle == 'all' and collection.all_vendors.size == 0 and collection.all_types.size == 0 -%}
+ {%- for i in (1..section.settings.products_per_row) -%}
+ {%- capture productImage -%}
+ {%- cycle 'product-1', 'product-2', 'product-3' -%}
+ {%- endcapture -%}
+ {%- assign image = productImage | placeholder_svg_tag: 'placeholder-svg' -%}
+
+ {%- render 'home-onboard-product', image: image -%}
+ {%- endfor -%}
+ {%- else -%}
+ {% for product in collection.products %}
+ {%
+ render 'product-list-item',
+ product: product,
+ %}
+ {% else %}
+ {% capture continueLink %}
+ <a href="{{ routes.all_products_collection_url }}">{{ 'collections.collection.continue_link' | t }}</a>
+ {% endcapture %}
+ <p class="empty">{{ 'collections.collection.empty_html' | t: continue_link: continueLink }}</p>
{% endfor %}
- {% endif %}
+ {%- endif -%}
</div>
- {% endif %}
-
- <!-- Full Collection Toolbar: Sort + Grid Density Slider -->
- {% include 'collection-toolbar' %}
-
- <div
- class="collection-products rows-of-{{ section.settings.products_per_row }} grid-cols-3"
- data-collection-grid
- {% if use_masonry %}data-masonry-grid{% endif %}
- >
- {%- if use_masonry -%}
- <div class="product-grid-masonry-sizer" data-masonry-sizer></div>
- {%- endif -%}
+ </section>
- {%- if collection.handle == 'all' and collection.all_vendors.size == 0 and collection.all_types.size == 0 -%}
- {%- for i in (1..section.settings.products_per_row) -%}
- {%- capture productImage -%}
- {%- cycle 'product-1', 'product-2', 'product-3' -%}
- {%- endcapture -%}
- {%- assign image = productImage | placeholder_svg_tag: 'placeholder-svg' -%}
+ {%
+ render 'pagination',
+ paginate: paginate,
+ %}
+ </div>
+ <!-- END INFINITE SCROLL WRAPPER -->
- {%- render 'home-onboard-product', image: image -%}
- {%- endfor -%}
- {%- else -%}
- {% for product in collection.products %}
- {%
- render 'product-list-item',
- product: product,
- %}
- {% else %}
- {% capture continueLink %}
- <a href="{{ routes.all_products_collection_url }}">{{ 'collections.collection.continue_link' | t }}</a>
- {% endcapture %}
- <p class="empty">{{ 'collections.collection.empty_html' | t: continue_link: continueLink }}</p>
- {% endfor %}
- {%- endif -%}
- </div>
- </section>
-
- <!-- Infinite scroll sentinel (replaces pagination) -->
- {% if paginate.next %}
- <div id="dw-scroll-sentinel" style="padding:20px;text-align:center;color:#999;font-size:12px;margin-top:40px;" data-next-page="{{ paginate.next.page }}">
- <span id="dw-loading-status">Loading more products…</span>
- </div>
- {% endif %}
{% endpaginate %}
</div>
-<script>
-(function() {
- var grid = document.querySelector('[data-collection-grid]');
- var sentinel = document.getElementById('dw-scroll-sentinel');
- if (!grid || !sentinel) return;
-
- var currentPage = {{ paginate.current_page }};
- var hasMore = !!sentinel;
- var isLoading = false;
-
- var observer = new IntersectionObserver(function(entries) {
- entries.forEach(function(e) {
- if (e.isIntersecting && hasMore && !isLoading) {
- loadNextPage();
- }
- });
- }, { rootMargin: '600px' });
-
- observer.observe(sentinel);
-
- function loadNextPage() {
- if (isLoading || !hasMore) return;
- isLoading = true;
-
- var nextPage = currentPage + 1;
- var url = new URL(window.location.href);
- url.searchParams.set('page', nextPage);
-
- fetch(url.toString())
- .then(function(r) { return r.text(); })
- .then(function(html) {
- var p = new DOMParser();
- var doc = p.parseFromString(html, 'text/html');
- var nextGrid = doc.querySelector('[data-collection-grid]');
-
- if (!nextGrid) {
- hasMore = false;
- document.getElementById('dw-loading-status').textContent = 'No more products';
- return;
- }
-
- var items = [];
- nextGrid.querySelectorAll('[class*="product-list-item"]').forEach(function(item) {
- items.push(item);
- });
-
- if (items.length === 0) {
- hasMore = false;
- document.getElementById('dw-loading-status').textContent = 'All products loaded';
- return;
- }
-
- items.forEach(function(item) {
- grid.appendChild(item.cloneNode(true));
- });
-
- currentPage = nextPage;
-
- var nextSentinel = doc.getElementById('dw-scroll-sentinel');
- if (!nextSentinel) {
- hasMore = false;
- document.getElementById('dw-loading-status').textContent = 'All products loaded';
- }
-
- isLoading = false;
- })
- .catch(function(e) {
- console.error('Load error:', e);
- document.getElementById('dw-loading-status').textContent = 'Error loading more';
- isLoading = false;
- });
- }
-})();
-</script>
-
<script src="{{ 'collection-grid-density.js' | asset_url }}" defer></script>
{% schema %}
@@ -333,4 +265,4 @@
]
}
-{% endschema %}
\ No newline at end of file
+{% endschema %}
← 6479af2e Fix infinite scroll: add data-dw-infinite wrapper to collect
·
back to Designer Wallcoverings
·
Officer-yolo approved: Launch Tres Tintas full backfill (all b84713de →