Files
trpic/web/scripts/load.js

108 lines
2.6 KiB
JavaScript

let gallery;
let sentinel;
let sortInfo;
let observer;
let offset;
let loading = false;
let hasMore = true;
const targetHeight = window.innerWidth > 1600 ? 280 : 220;
const limit = window.innerWidth > 1600 ? 50 : 20;
const urlParams = new URLSearchParams(window.location.search);
const sort = urlParams.get("sort") || "name";
async function loadMoreImages() {
if (loading || !hasMore) return;
// 加载期间先取消观察
observer.unobserve(sentinel);
loading = true;
try {
const res = await fetch(
`/api/images?offset=${offset}&limit=${limit}&height=${targetHeight}&sort=${sort}`
);
if (!res.ok) throw new Error("Network error");
const data = await res.json();
appendImages(data.images);
hasMore = data.offset + data.images.length < data.total;
offset += data.images.length;
} catch (err) {
console.error(err);
} finally {
loading = false;
// 加载完成下一帧重新观察,强制刷新交叉状态
requestAnimationFrame(() => {
observer.observe(sentinel);
});
sortInfo.textContent = sort;
}
}
function appendImages(items) {
const fragment = document.createDocumentFragment();
for (const item of items) {
const wrapper = document.createElement("div");
wrapper.style.width = item.j_width + "px";
wrapper.style.flexGrow = item.j_width;
const i = document.createElement("i");
i.style.paddingBottom = item.j_padding + "%";
const span = document.createElement("span");
const p = document.createElement("p");
p.textContent = `${item.long}px | ${item.size}`;
span.appendChild(p);
i.appendChild(span);
wrapper.appendChild(i);
const img = document.createElement("img");
img.name = item.file_name;
img.alt = `${item.width}*${item.height} | ${item.size} | ${item.format} `;
img.loading = "lazy";
img.decoding = "async";
if (item.preview_url) {
img.src = item.preview_url;
img.dataset.highres = item.url;
} else {
img.src = item.url;
}
wrapper.appendChild(img);
fragment.appendChild(wrapper);
}
gallery.appendChild(fragment);
// gallery.insertBefore(fragment, sentinel);
}
document.addEventListener("DOMContentLoaded", () => {
gallery = document.getElementById("gallery");
sentinel = document.getElementById("sentinel");
sortInfo = document.getElementById("sort-info");
offset = gallery.childElementCount - 1;
observer = new IntersectionObserver(
(entries) => {
if (entries[0].isIntersecting) {
loadMoreImages();
}
},
{
root: null,
rootMargin: "800px", // 提前 800px 加载
threshold: 0,
}
);
observer.observe(sentinel);
});