Reputation: 89
EDIT: I have half answered my own question, but still need assistance. Please see Dynamically load HTML from other files onto page as you scroll below.
Original post: I am working on revamping a site for members that contains an image gallery of photos that can be used for marketing purposes. Previously each category was split into sub-categories, resulting in a couple hundred pages and some pages with one image only. I've ditched the sub-categories and contained all the images on each category page. When you click on a thumbnail it the full size image opens in a lightbox with additional info
This is fine for most categories, but some categories are large and contain a couple hundred images. The problem is that on these pages, most of the time not all the thumbnails will load. Instead of using pagination to separate these large categories into multiple pages I want to have more content load dynamically as you scroll down. I do not know how to do this.
The code snippet on jQuery load more data on scroll looks like it could work, but is there a way to replace
html += '<p class="dynamic">Dynamic Data : This is test data.<br />Next line.</p>';
with something that will put the contents of file1.html
in its place, followed by file2.html
, and so on?
If not, is there some way of creating some sort of file that would have the thumbnail locations that could be referred to and loaded as a user scrolls down?
This YouTube video seemed like a good starting point, but it requires an AJAX call or some other call. I am not sure what this means and where it's calling to.
Upvotes: 2
Views: 1266
Reputation: 89
So I found a potential solution using IntersectionObserver thanks to deanhume.com. It works beautifully in Chrome and newer versions of Firefox.
Sadly, we still code our site work work with IE 11 as our standard. I don't know why, but we do so I have to deal with that. The problem is this solution does not work with an older version of Firefox I use for validation nor does it work with IE 11. So I want to use a polyfill.
The GitHub page for the polyfill talks about using <script src="https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserver"></script>
for older browser support, but it does not seem to work. I also placed the polyfill JavaScript file on the site and referenced it in the page head before any other Javascript, but it also does not seem to work.
What is the proper way to load a polyfill file?
The first line referencing it is: <script src="../pathto/polyfills/intersectionobserver.js"></script>
Then there is some unrelated stuff before getting to the Intersection Observer bit; CSS for the fade in and calling in the lazy-load script:
<style>
.fade-in {
animation-name: fadeIn;
animation-duration: 1.3s;
animation-timing-function: cubic-bezier(0, 0, 0.4, 1);
animation-fill-mode: forwards;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.centered {
display:block;
margin:0 auto;
}
</style>
<script type="module">
import LazyLoad from "../pathto/lazy-load.js";
LazyLoad.init();
</script>
Below is the lazy-load.js file.
const defaults = {
imageLoadedClass: 'js-lazy-image--handled',
imageSelector: '.js-lazy-image',
// If the image gets within 100px in the Y axis, start the download.
rootMargin: '100px 0px',
threshold: 0.01
};
let config,
images,
imageCount,
observer;
/**
* Fetches the image for the given URL
* @param {string} url
*/
function fetchImage(url) {
return new Promise((resolve, reject) => {
const image = new Image();
image.src = url;
image.onload = resolve;
image.onerror = reject;
});
}
/**
* Preloads the image
* @param {object} image
*/
function preloadImage(image) {
const src = image.dataset.src;
if (!src) {
return;
}
return fetchImage(src).then(() => { applyImage(image, src); });
}
/**
* Load all of the images immediately
* @param {NodeListOf<Element>} images
*/
function loadImagesImmediately(images) {
// foreach() is not supported in IE
for (let i = 0; i < images.length; i++) {
let image = images[i];
preloadImage(image);
}
}
/**
* Disconnect the observer
*/
function disconnect() {
if (!observer) {
return;
}
observer.disconnect();
}
/**
* On intersection
* @param {array} entries
*/
function onIntersection(entries) {
// Disconnect if we've already loaded all of the images
if (imageCount === 0) {
disconnect();
return;
}
// Loop through the entries
for (let i = 0; i < entries.length; i++) {
let entry = entries[i];
// Are we in viewport?
if (entry.intersectionRatio > 0) {
imageCount--;
// Stop watching and load the image
observer.unobserve(entry.target);
preloadImage(entry.target);
}
}
}
/**
* Apply the image
* @param {object} img
* @param {string} src
*/
function applyImage(img, src) {
// Prevent this from being lazy loaded a second time.
img.classList.add(config.imageLoadedClass);
img.src = src;
}
let LazyLoad = {
init: (options) => {
config = {...defaults, ...options};
images = document.querySelectorAll(config.imageSelector);
imageCount = images.length;
// If we don't have support for intersection observer, loads the images immediately
if (!('IntersectionObserver' in window)) {
loadImagesImmediately(images);
} else {
// It is supported, load the images
observer = new IntersectionObserver(onIntersection, config);
// foreach() is not supported in IE
for (let i = 0; i < images.length; i++) {
let image = images[i];
if (image.classList.contains(config.imageLoadedClass)) {
continue;
}
observer.observe(image);
}
}
}
};
export default LazyLoad;
And just in case it's needed, a sample of the image code on the page:
<img class="js-lazy-image" data-src="url/members/thumbs/ab_banff_np.jpg" alt="rockies, rocky mountains, trees, summer" aria-describedby="image_g2">
Upvotes: 1
Reputation: 96
To load more content in Javascript (and using jQuery), you can use the following:
$.ajax("path/to/your/file/file1.html")
.done((data) => {
$('body').append(data);
});
What this does:
file1.html
More info:
Upvotes: 0
Reputation: 847
Now you can do lazy loading native on html using tag loading="lazy"
Example:
<img src="image.png" loading="lazy" width="200" height="200">
More information: https://css-tricks.com/native-lazy-loading/
Upvotes: 0