108 lines
2.6 KiB
JavaScript
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);
|
|
});
|