Paginate the gallery grid with 60 photos per page
Emit /page/N/ pages alongside index.html and render a pager at the bottom of each page. Ships as a plain link that navigates without JS, and an IntersectionObserver enhancement that fetches the next page and appends tiles for an infinite-scroll feel.
This commit is contained in:
+46
-1
@@ -18,7 +18,7 @@
|
||||
<div class="pinfo">
|
||||
<h1>{{.Author}}</h1>
|
||||
<p class="handle">{{.Handle}}</p>
|
||||
<p class="pcount"><strong>{{len .Photos}}</strong> posts</p>
|
||||
<p class="pcount"><strong>{{.Total}}</strong> posts</p>
|
||||
<p class="pbio">{{.Bio}}{{if .BioAlt}}<br><span class="ml">{{.BioAlt}}</span>{{end}}</p>
|
||||
<a href="/feed.xml" class="rss-a">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="currentColor" aria-hidden="true">
|
||||
@@ -41,11 +41,56 @@
|
||||
</a>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
{{if or .PrevURL .NextURL}}
|
||||
<nav class="pager">
|
||||
{{if .PrevURL}}<a class="pager-newer" href="{{.PrevURL}}">← Newer</a>{{end}}
|
||||
{{if .NextURL}}<a class="pager-older" href="{{.NextURL}}" data-load-more>Older →</a>{{end}}
|
||||
</nav>
|
||||
{{end}}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="site-footer">
|
||||
© 2000–{{.Year}} {{.Author}}. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
const btn = document.querySelector('[data-load-more]');
|
||||
if (!btn) return;
|
||||
const grid = document.querySelector('.pgrid');
|
||||
let loading = false;
|
||||
|
||||
async function loadMore(url) {
|
||||
if (loading) return;
|
||||
loading = true;
|
||||
try {
|
||||
const res = await fetch(url);
|
||||
if (!res.ok) return;
|
||||
const html = await res.text();
|
||||
const doc = new DOMParser().parseFromString(html, 'text/html');
|
||||
doc.querySelectorAll('.pgrid > a').forEach(t => grid.appendChild(t));
|
||||
const nextBtn = doc.querySelector('[data-load-more]');
|
||||
if (nextBtn) btn.href = nextBtn.getAttribute('href');
|
||||
else btn.remove();
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
btn.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
loadMore(btn.href);
|
||||
});
|
||||
|
||||
const io = new IntersectionObserver((entries) => {
|
||||
if (entries[0].isIntersecting && document.body.contains(btn)) {
|
||||
loadMore(btn.href);
|
||||
}
|
||||
}, { rootMargin: '400px' });
|
||||
io.observe(btn);
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user