Deferred fragments that load when revealed can implement infinite scrolling without custom JavaScript.
<div id="pages">
<div class="page">items for page 1</div>
</div>
<a id="next-page" href="/items?page=2" up-defer="reveal" up-target="#next-page, #pages:after">
load next page
</div>
Note the following:
#pages
).[up-defer]
placeholder that loads content when it enters the viewport
#next-pages
) and the list of pages (#pages
), using an [up-target]
attribute.When the user scrolls to the "load next page" button, Unpoly automatically makes a request:
GET /items?page=2 HTTP/1.1
X-Up-Target: #next-page, #pages
The server is now expected to respond with HTML containing both targeted elements.
Note how the response only contains items for page 2, and a link to page 3:
<div id="pages">
<div class="page">items for page 2</div> <!-- mark-line -->
</div>
<a id="next-page" href="/items?page=3" up-defer="reveal" up-target="#next-page, #pages:after"> <!-- mark-phrase "/items?page=3" -->
load next page
</div>
Unpoly renders the response, resulting in the following page:
<div id="pages">
<div class="page">items for page 1</div>
<div class="page">items for page 2</div> <!-- mark-line -->
</div>
<a id="next-page" href="/items?page=3" up-defer="reveal" up-target="#next-page, #pages:after"> <!-- mark-phrase "/items?page=3" -->
load next page
</div>
Note
We're using standard links to allow sharing of pages and also to follow Google's recommendation.
On the last page render we can render an empty (or text-only) #next-page
container to remove the link:
<div id="pages">
<div class="page">items for last page</div>
</div>
<div id="next-page">You've reached the end.</div>