Итак, я нашел потенциальное решение с использованием IntersectionObserver благодаря deanhume.com . Он прекрасно работает в Chrome и более новых версиях Firefox.
К сожалению, мы все еще кодируем работу нашего сайта, работая с IE 11 в качестве нашего стандарта. Я не знаю почему, но мы делаем это, я должен иметь дело с этим. Проблема в том, что это решение не работает со старой версией Firefox, которую я использую для проверки, и не работает с IE 11. Поэтому я хочу использовать полифилл.
Страница GitHub для полизаполнения говорит об использовании <script src="https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserver"></script>
для поддержки старых браузеров, но, похоже, не работает. Я также разместил на сайте файл JavaScript с полифилом и ссылался на него в заголовке страницы перед любым другим Javascript, но он также, похоже, не работает.
Как правильно загрузить файл полизаполнения?
Первая строка, ссылающаяся на него: <script src="../pathto/polyfills/intersectionobserver.js"></script>
Тогда есть несколько несвязанных вещей, прежде чем попасть на пересечениеБит наблюдателя;CSS для появления и вызова в сценарии с отложенной загрузкой:
<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>
Ниже приведен файл lazy-load.js.
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;
И на всякий случай, пример кода изображения на странице:
<img class="js-lazy-image" data-src="url/members/thumbs/ab_banff_np.jpg" alt="rockies, rocky mountains, trees, summer" aria-describedby="image_g2">