Самый простой способ ленивой загрузки элементов DOM на странице.
Я представил, как динамически загружать изображение с помощью Angular, Динамическая загрузка изображения с помощью Angular. На этот раз я не буду использовать Angular или какой-либо другой фреймворк, а буду использовать только веб-стандарты, особенно пользовательские элементы и шаблоны.
Предположим, что на вашей странице более 100 изображений, и вы видите только два или три из них при загрузке страницы. Тогда почему браузеры загружают 100 изображений при инициализации страницы?
Невозможно не загрузить изображение, пока в вашем html есть теги ‹img›. Это означает, что вы должны изменить html, чтобы не было тегов изображения, и изменить html динамически, чтобы избежать начальной загрузки изображения. Однако динамическое изменение html — непростая задача, требующая большого количества сценариев.
На самом деле приведенное выше утверждение неверно. Когда ваш тег <img>
находится в теге <template>
, он не отображается. Я собираюсь использовать эту технику, и это шаги, которым я собираюсь следовать.
- Напишите HTML в
<template>
. - Проверьте, находится ли элемент в окне просмотра.
- Визуализируйте шаблон, когда он находится в области просмотра.
1. Напишите HTML в <template>
<my-el> <-- This is the custom element --> <template> <div>This image is only rendered when this is in viewport.</div> <img src="https://picsum.photos/800/400/?image=10" /> </template> </my-el> <my-el> <template> <div>This image is only rendered when this is in viewport.</div> <img src="https://picsum.photos/800/400/?image=20" /> </template> </my-el> ...
Без написания собственного пользовательского элемента, если вы запустите html-код, вы ничего не увидите, потому что template
не отображается и изображение не будет загружено.
2. Проверьте, находится ли элемент в окне просмотра
Как указано в Документе IntersectionObserver MDN, мы можем определить, находится ли ваш элемент в области просмотра или нет.
Intersection Observer API предоставляет способ асинхронного наблюдения за изменениями в пересечении целевого элемента с элементом-предком или с областью просмотра документа верхнего уровня.
Это очень простой код для IntersectionObserver.
var observer = new IntersectionObserver(handler, options); observer.observe(myEl);
handler
: функция обратного вызова, которая будет запущена, когда наблюдаемый элемент находится в окне просмотра.
3. Визуализируйте шаблон, когда он находится в окне просмотра
Хотя вы можете многое сделать с помощью шаблона HTML5, в этой статье мы сосредоточимся только на template.content
и document.importNode
.
const templateEl = this.querySelector('template'); const clonedEl = document.importNode(templateEl.content, true); myEl.appendChild(clonedEl);
Вышеупомянутое действие клонирует содержимое элемента шаблона и добавляет его в ваш элемент.
Вот и все. Вы получили все необходимые знания для динамической загрузки.
Для тех, кто хочет выполнять более настраиваемые действия, когда элемент находится в области просмотра или вне ее, вы можете запустить свое собственное событие. Как сказано в № 2, вы можете определить свой собственный обработчик, внутри которого вы можете запустить событие inview
или outview
следующим образом.
myIntersectionHandler(entries, observer) { entries.forEach(entry => { if (entry.isIntersecting) { this.activateTemplate(); #3 action this.dispatchEvent(new CustomEvent('inview')); } else { this.dispatchEvent(new CustomEvent('outview')); } }); }
Чтобы собрать все вместе, ниже приведен код пользовательского элемента my-inview
. Фактически этот код является упрощенной версией Inview class of MCE.
class Inview extends HTMLElement { connectedCallback() { this.templateActivated = false; this.observer = new IntersectionObserver(this.handleIntersect.bind(this)); this.observer.observe(this); } handleIntersect(entries, observer) { entries.forEach(entry => { if (entry.isIntersecting) { this.activateTemplate(); this.dispatchEvent(new CustomEvent('inview')); } else { this.dispatchEvent(new CustomEvent('outview')); } }); } activateTemplate() { if (this.templateActivated) return; const templateEl = this.querySelector('template'); const clonedEl = document.importNode(templateEl.content, true); this.appendChild(clonedEl); this.templateActivated = true; } } customElements.define('my-inview', Inview);
Резюме
- Чтобы увидеть демо, посетите демонстрационный сайт MCE.
- Чтобы увидеть полный код, посетите github.
- Если вам нужно использовать Angular, смотрите эту статью.
Удачного кодирования. :)
18 мая 2018 г.
Аллен Ким
Считаете ли вы это полезным? Если да, пожалуйста;
* Хлопните кнопку 👏ниже️, чтобы другие тоже это увидели.
* Подпишитесь на Аллена в Твиттере( @allenhwkim)!