Explanation of the Code:
This code snippet is part of an image gallery, with features for lazy-loading thumbnails and displaying full-size images when a thumbnail is clicked. Let’s break down the code step by step.
1. Function loadThumbnails(album)
- Stops current playback: If a slideshow or animation is running (
isPlaying
is true
), it stops it and changes the button text to '播放' (play).
- Clears the thumbnail area: It clears the
thumbnailBar
to prepare for new thumbnails to be loaded.
- Sets up the album data: It accesses the album data from
sources[album]
and initializes a few variables like thumbsLoaded
, currentAlbum
, and currentIndex
.
- Loads placeholder thumbnails: It loops through the
albumData.data
(assumed to be a list of image file names or paths) and creates a div
for each thumbnail. Initially, it adds a placeholder (a div
with text like #1
, #2
, etc.) to represent the thumbnail. Each thumbnail gets an event listener that calls displayPhoto(album, index)
when clicked.
- Displays the first photo immediately: The first photo is displayed right away by calling
displayPhoto(album, 0)
, without waiting for thumbnails to load.
- Uses the Intersection Observer for lazy loading: The function sets up an
IntersectionObserver
to observe when a thumbnail enters the viewport. When a thumbnail is about to be displayed, it loads the image and replaces the placeholder with the actual thumbnail image. It also preloads the full-size image using the preloadImage
function. After the image has been loaded, the observer stops observing that particular thumbnail.
- Starts observing all thumbnail items: The
IntersectionObserver
is set up to observe all elements with the class thumbnail
.
2. Intersection Observer:
The IntersectionObserver
is used here for lazy loading of images as they come into view. Here’s how it works in detail:
- Observer Callback: The callback function of the
IntersectionObserver
is executed whenever an observed element enters or exits the viewport.
entries.forEach(entry => {...})
: Each entry is an observed element (in this case, a thumbnail) and the entry.isIntersecting
flag indicates whether the element is currently visible in the viewport.
- When a thumbnail becomes visible (
entry.isIntersecting === true
), the corresponding full-size image URL is calculated (imgSrc
), the placeholder is replaced by the actual image, and the full image is preloaded.
- After processing the thumbnail, the observer is disconnected from it using
observer.unobserve(thumbDiv)
, meaning the image will not be lazy-loaded again.
- Observer Options:
root: thumbnailBar
: The root is set to the thumbnailBar
, which means the observer will consider the visibility of the elements relative to this container.
rootMargin: '0px 100px 0px 100px'
: This adds extra space around the viewport for triggering the lazy loading. Here, 100px is added above and below the visible area to start loading the images a little before they are fully in view.
threshold: 0.1
: The image is considered "in view" when at least 10% of it is visible within the root element.
3. Function updateActiveThumbnail(index)
- This function highlights the thumbnail corresponding to the
index
passed to it. It removes the active
class from all thumbnails and adds it to the currently selected thumbnail.
- It also ensures that the selected thumbnail is visible by scrolling it into view with
scrollIntoView
.
4. Function displayPhoto(album, index)
- This function is responsible for displaying the full-size photo when a thumbnail is clicked.
- It shows a loading indicator while the photo is being loaded.
- It updates the description for the selected photo and calls
updateActiveThumbnail
to highlight the corresponding thumbnail.
- If the image is already preloaded (stored in
imageCache
), it immediately displays the image. Otherwise, it uses preloadImage
to load the image and then displays it.
- If an error occurs while loading the image, it displays an error message.
Intersection Observer in Detail:
The Intersection Observer is a browser API that allows you to configure an observer to watch changes in the intersection of an element with its parent element or the viewport. It's particularly useful for implementing lazy loading, infinite scrolling, and animations when elements come into view.
Key Features:
-
Efficiency:
- The Intersection Observer is highly efficient because it allows you to monitor when elements enter or leave the viewport without needing to rely on scroll events or manual checks. This reduces the number of expensive calculations performed on every scroll event.
-
IntersectionObserver
constructor:
- This constructor creates a new observer. It takes a callback function and an optional options object.
-
Callback function:
- The callback function is triggered whenever any observed element enters or exits the root (viewport). It receives an array of
IntersectionObserverEntry
objects, each representing one observed element.
-
Options:
root
: The element to be used as the viewport for checking visibility. The default is the browser’s viewport.
rootMargin
: A margin around the root element that can be used to trigger the observer before the element enters the root (useful for preloading).
threshold
: A number or array that defines the percentage of the target element’s visibility required for the observer callback to be triggered.
-
Methods:
observe(target)
: Begins observing a target element.
unobserve(target)
: Stops observing a target element.
disconnect()
: Stops observing all targets.
In the provided code, the IntersectionObserver
is used to implement lazy loading for the thumbnails, meaning the images are loaded only when they are about to come into view, rather than loading all images up front. This can save bandwidth and improve performance, especially for image-heavy websites.
Summary of What the Code Does:
- Loads thumbnails with placeholder images.
- Uses an
IntersectionObserver
to lazy-load the actual thumbnails as they come into view.
- Displays the full-size image when a thumbnail is clicked.
- Updates the UI to highlight the currently active thumbnail and display the corresponding image with a description.