feat: replace infinite scroll with load more button for footer access

This commit is contained in:
2026-02-04 11:45:30 +01:00
parent de0f3628ce
commit 2ffbfdf3e1
4 changed files with 24 additions and 27 deletions

View File

@@ -14,7 +14,6 @@ class PageHome extends HTMLElement {
this.error = null
this.page = 1
this.hasMore = true
this.observer = null
// Filter state
this.query = ''
@@ -44,7 +43,6 @@ class PageHome extends HTMLElement {
disconnectedCallback() {
if (this.unsubscribe) this.unsubscribe()
if (this.observer) this.observer.disconnect()
window.removeEventListener('hashchange', this.handleHashChange.bind(this))
}
@@ -226,7 +224,7 @@ class PageHome extends HTMLElement {
this.loading = false
this.loadingMore = false
this.updateListingsSection()
this.setupInfiniteScroll()
this.setupLoadMoreButton()
} catch (err) {
console.error('Failed to load listings:', err)
this.error = err.message
@@ -255,27 +253,19 @@ class PageHome extends HTMLElement {
.sort((a, b) => a._distance - b._distance)
}
setupInfiniteScroll() {
if (this.observer) this.observer.disconnect()
const sentinel = this.querySelector('#scroll-sentinel')
if (!sentinel || !this.hasMore) return
this.observer = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting && !this.loadingMore && this.hasMore) {
setupLoadMoreButton() {
const btn = this.querySelector('#load-more-btn')
btn?.addEventListener('click', () => {
this.page++
this.loadListings()
}
}, { rootMargin: '100px' })
this.observer.observe(sentinel)
})
}
updateListingsSection() {
const listingsContainer = this.querySelector('#listings-container')
if (listingsContainer) {
listingsContainer.innerHTML = this.renderListings()
this.setupInfiniteScroll()
this.setupLoadMoreButton()
}
const titleEl = this.querySelector('.listings-title')
@@ -413,16 +403,20 @@ class PageHome extends HTMLElement {
`
}).join('')
const sentinelHtml = this.hasMore ? `
<div id="scroll-sentinel" class="scroll-sentinel">
const loadMoreHtml = this.hasMore ? `
<div class="load-more-container">
${this.loadingMore ? `
<div class="spinner"></div>
<p>${t('common.loading')}</p>
` : ''}
` : `
<button id="load-more-btn" class="btn btn-outline">
${t('home.loadMore')}
</button>
`}
</div>
` : ''
return listingsHtml + sentinelHtml
return listingsHtml + loadMoreHtml
}
escapeHtml(text) {
@@ -583,7 +577,7 @@ style.textContent = /* css */`
to { transform: rotate(360deg); }
}
page-home .scroll-sentinel {
page-home .load-more-container {
display: flex;
flex-direction: column;
align-items: center;
@@ -593,7 +587,7 @@ style.textContent = /* css */`
grid-column: 1 / -1;
}
page-home .scroll-sentinel .spinner {
page-home .load-more-container .spinner {
width: 30px;
height: 30px;
margin-bottom: var(--space-sm);

View File

@@ -24,7 +24,8 @@
"placeholderLocation": "Standort",
"addFavorite": "Zu Favoriten hinzufügen",
"removeFavorite": "Aus Favoriten entfernen",
"noListings": "Keine Anzeigen gefunden"
"noListings": "Keine Anzeigen gefunden",
"loadMore": "Mehr laden"
},
"common": {
"loading": "Laden...",

View File

@@ -24,7 +24,8 @@
"placeholderLocation": "Location",
"addFavorite": "Add to favorites",
"removeFavorite": "Remove from favorites",
"noListings": "No listings found"
"noListings": "No listings found",
"loadMore": "Load more"
},
"common": {
"loading": "Loading...",

View File

@@ -24,7 +24,8 @@
"placeholderLocation": "Emplacement",
"addFavorite": "Ajouter aux favoris",
"removeFavorite": "Retirer des favoris",
"noListings": "Aucune annonce trouvée"
"noListings": "Aucune annonce trouvée",
"loadMore": "Charger plus"
},
"common": {
"loading": "Chargement...",