All application logic for the Infinity Scroll gallery lives in a single file,Documentation Index
Fetch the complete documentation index at: https://mintlify.com/ClaytonSeager/InifinityScroll/llms.txt
Use this file to discover all available pages before exploring further.
Infinity.js. It is responsible for fetching photos from the Unsplash API, building the gallery DOM, tracking load state, responding to search input, driving infinite scroll, and managing the scroll-to-top button — with no external framework dependencies.
Configuration Constants
Theseconst declarations at the top of Infinity.js control the core API behaviour. Edit them directly to change your API key or batch size.
Your Unsplash API Access Key. Obtain one by registering a developer application at https://unsplash.com/developers.
Number of images fetched per API call. Increasing this value loads more images per batch but uses more API quota.
The current search term. An empty string causes
getApiUrl() to request random photos. When the user submits a search, handleSearch() overwrites this with the input value.query is declared with let rather than const because handleSearch() reassigns it on every search submission.State Variables
These module-level variables hold live runtime state. They are read and mutated by several functions throughoutInfinity.js.
| Variable | Type | Default | Description |
|---|---|---|---|
imageContainer | HTMLElement | — | Reference to #Image__Container. Gallery <a>+<img> pairs are appended here. |
loader | HTMLElement | — | Reference to #Loader. Its hidden property is toggled to show/hide the loading overlay. |
ready | boolean | false | Gates the infinite-scroll trigger. Set to true only after all images in a batch have fired their load events. Reset to false when a new fetch begins. |
imagesLoaded | number | 0 | Count of images that have fired their load event in the current batch. Compared against totalImages to detect batch completion. |
totalImages | number | 0 | Total images in the batch currently being rendered. Set to photosArray.length at the start of displayPhotos(). |
photosArray | Array | [] | The last set of photo objects returned from the Unsplash API. |
totalLoadedImages | number | 0 | Cumulative count of every image loaded this session across all batches. Displayed in #image-counter. |
titleColumn | HTMLElement | — | Reference to .Title__Column. Receives the scrolled class when scrollY > 50. |
imageCounter | HTMLElement | — | Reference to #image-counter. Its textContent is updated to totalLoadedImages after every image load. |
scrollTopBtn | HTMLElement | — | Reference to #scrollTop. Receives the visible class when scrollY > innerHeight. |
searchInput | HTMLElement | — | Reference to #search-input. Its .value is read by handleSearch() to set query. |
searchButton | HTMLElement | — | Reference to #search-button. Has a click listener attached that calls handleSearch(). |
Functions
getApiUrl()
Constructs and returns the correct Unsplash API endpoint URL based on the current value of query.
- When
queryis empty (default / random mode), it targets the random-photos endpoint:https://api.unsplash.com/photos/random/?client_id=${KEY}&count=${count} - When
queryis set (search mode), it targets the search endpoint:https://api.unsplash.com/search/photos/?query=${query}&client_id=${KEY}&count=${count}
string — the fully-formed API URL.
getPhotos() (async)
Fetches a batch of photos from Unsplash by calling getApiUrl(), then assigns the result to photosArray and triggers displayPhotos().
The Unsplash random and search endpoints return different JSON shapes:
- Search (
/search/photos/) wraps results in aresultsproperty:data.results - Random (
/photos/random/) returns the array directly:data
getPhotos() handles this difference with a ternary on query. Errors are caught and logged to the console.
displayPhotos()
Iterates photosArray and constructs a pair of DOM elements for each photo — an <a> anchor wrapping an <img> — then appends each pair to #Image__Container.
At the start of each call it sets totalImages = photosArray.length so the batch-completion logic in imageLoaded() knows how many images to wait for. Each <img> receives a load event listener that calls imageLoaded().
Unsplash photo object fields used:
| Field | Used as |
|---|---|
photo.links.html | href on the <a> element |
photo.urls.regular | src on the <img> element |
photo.alt_description | alt and title on the <img> element |
setAttributes(element, attributes)
A lightweight utility that sets multiple HTML attributes on a DOM element in a single call by iterating over the keys of the attributes object.
Parameters:
The DOM element on which attributes will be set.
A plain object whose keys are attribute names and whose values are the corresponding attribute values. Example:
{ src: '...', alt: '...' }.imageLoaded() (async)
Called by each image’s load event listener. It increments both imagesLoaded (batch counter) and totalLoadedImages (session counter), then updates the #image-counter element’s text content.
When imagesLoaded === totalImages (i.e., every image in the current batch has loaded), it:
- Resets
imagesLoadedto0 - Sets
ready = true— enabling the next infinite-scroll trigger - Sets
loader.hidden = true— hiding the loading overlay
handleSearch()
Invoked when the user clicks #search-button or presses Enter inside #search-input. It performs a full gallery reset before fetching new results:
- Reads
searchInput.valueand assigns it toquery - Clears the gallery by setting
imageContainer.innerHTML = '' - Resets
totalLoadedImagesto0and updates the counter display - Shows the loader overlay (
loader.hidden = false) - Calls
getPhotos()to fetch the first batch for the new query
Event Listeners
Four event listeners wire up user interactions and scroll behaviour.searchButton — click
handleSearch() whenever the search button is clicked.
searchInput — keypress
handleSearch() when the user presses the Enter key while the search input is focused.
window — scroll
The scroll listener handles three separate responsibilities in a single callback:
| Responsibility | Condition | Action |
|---|---|---|
| Infinite scroll trigger | innerHeight + scrollY >= offsetHeight - 1000 and ready === true | Sets ready = false, then calls getPhotos() to load the next batch |
| Sticky header compact mode | scrollY > 50 | Adds scrolled class to .Title__Column; removes it otherwise |
| Scroll-to-top visibility | scrollY > innerHeight | Adds visible class to #scrollTop; removes it otherwise |
The infinite-scroll threshold of
1000px before the page bottom means new photos begin loading before the user reaches the very end of the feed, creating a seamless experience.scrollTopBtn — click
#scrollTop is clicked.
Initialization
At the very end ofInfinity.js, getPhotos() is called once unconditionally as the script loads. This populates the gallery with an initial batch of random photos before any user interaction.
Because
query is '' at this point, the initial call always fetches random photos from the Unsplash random endpoint. The gallery will only switch to search mode after the user submits a search term via handleSearch().