Я покажу пример реализации "Ленивой загрузки" данных или как ее называют по другому "Бесконечный скролл".
Все подробности в ролике, а ниже код, который был использован в видео.
Код с разметкой и функцией для отслеживания "якоря":
HTML:
<div class="news-list" id="content"></div>
<div id="sentinel"></div>
<script>
function setObserver() {
let sentinel = document.getElementById('sentinel');
const observer = new IntersectionObserver(entries => {
if (entries[0].isIntersecting) {
<%= Scripts %>.loadItems();
}
});
observer.observe(sentinel);
}
setObserver()
<%= Scripts %>.loadItems();
</script>
<template id="newsTemplate">
<article class="news-card" aria-labelledby="title">
<header class="news-header">
<h2 class="news-title" id="title"></h2>
</header>
<figure class="news-figure">
<img class="news-image" src="" alt=""/>
</figure>
<div class="news-body">
<p></p>
</div>
<footer class="news-footer">
<p class="news-date"></p>
</footer>
</article>
</template>
<style>
.news-list {
background-color: #F0F6FB;
padding: 15px;
}
.news-card {
background-color: #ffffff;
padding: 15px;
border: 1px solid #D9D9D9;
border-radius: 5px;
margin-bottom: 15px;
}
.news-title {
margin: 0 0 12px 0;
font-size: 18px;
font-weight: 700;
}
.news-figure {
margin: 0 0 12px 0;
}
.news-image {
width: 100%;
height: auto;
display: block;
border-radius: 8px;
object-fit: cover;
}
.news-body p {
margin: 0 0 12px 0;
font-size: 14px;
color: #374151;
}
.news-footer {
margin-top: 8px;
display: flex;
justify-content: flex-end;
}
.news-date {
font-size: rem;
}
</style>
Код из вкладки "Скрипты":
Код:
declare const document: any, console: any, window: any
/** Счетчик общего кол-ва новостей на странице */
let count = 0;
/** Кол-во элементов для подгрузки */
let amount_items = 2;
let end = false
async function loadItems() {
if (Context.data.loading || end) return
Context.data.loading = true;
const items = await Namespace.app.news.search().from(count).size(amount_items).all()
if (items.length == 0) {
Context.data.loading = false;
end = true
return
}
await Promise.all(items.map(f => addNewsItem(f)))
count += amount_items
Context.data.loading = false;
}
async function addNewsItem(item: BaseApplicationItem<any, any>) {
const tpl = document.getElementById('newsTemplate');
const container = document.getElementById('content');
if (!tpl || !container) return;
const clone = tpl.content.cloneNode(true);
const titleEl = clone.querySelector('.news-title');
titleEl.textContent = item.data.__name;
const imgEl = clone.querySelector('.news-image');
if (item.data.file) {
imgEl.src = await item.data.file.getDownloadUrl()
} else {
const fig = clone.querySelector('.news-figure');
fig && fig.remove();
}
const textEl = clone.querySelector('.news-body p');
textEl.textContent = item.data.opisanie ?? '';
const timeEl = clone.querySelector('.news-date');
timeEl.textContent = item.data.__createdAt.format('DD.MM.YYYY hh:mm');
container.appendChild(clone);
}
Еще больше полезной информации в ТГ канале WhatDaELMA365