feat(post-content): lazy-load hi-res images with blur-up fade-in

This commit is contained in:
xfy 2026-06-22 18:00:52 +08:00
parent 1a41f8d7aa
commit 8ef9ee5621

View File

@ -48,40 +48,62 @@
} }
function initImageZoom(root) { function initImageZoom(root) {
var images = root.querySelectorAll("img"); var containers = root.querySelectorAll(".blur-img");
for (var i = 0; i < images.length; i++) { for (var i = 0; i < containers.length; i++) {
var img = images[i]; var container = containers[i];
if (img.getAttribute("data-zoom-enabled")) continue; if (container.getAttribute("data-blur-init")) continue;
var src = img.getAttribute("src") || img.src || ""; container.setAttribute("data-blur-init", "true");
if (src.indexOf("data:") === 0) continue;
img.setAttribute("data-zoom-enabled", "true"); var fullImg = container.querySelector(".blur-img-full");
if (!fullImg) continue;
var fullSrc = fullImg.getAttribute("data-src");
if (!fullSrc) continue;
var originalSrc = img.src; // 加载高清图onload 后加 is-loaded 触发 CSS opacity 淡入
var sep = originalSrc.indexOf("?") !== -1 ? "&" : "?"; fullImg.addEventListener("load", function () {
img.src = originalSrc + sep + "w=800"; this.classList.add("is-loaded");
img.classList.add("md-content-img-zoomable"); });
(function (origSrc, altText) { // 懒加载:进入视口才设 src
img.addEventListener("click", function (e) { if ("IntersectionObserver" in window) {
var io = new IntersectionObserver(
function (entries) {
entries.forEach(function (entry) {
if (entry.isIntersecting) {
fullImg.src = fullSrc;
io.unobserve(container);
}
});
},
{ rootMargin: "200px" }
);
io.observe(container);
} else {
// 不支持 IO直接加载
fullImg.src = fullSrc;
}
// 灯箱:点击用高清图 URL 放大
(function (src, altText) {
container.addEventListener("click", function (e) {
e.preventDefault(); e.preventDefault();
var overlay = document.createElement("div"); var overlay = document.createElement("div");
overlay.className = "md-image-lightbox-overlay"; overlay.className = "md-image-lightbox-overlay";
var container = document.createElement("div"); var containerEl = document.createElement("div");
container.className = "md-image-lightbox-content"; containerEl.className = "md-image-lightbox-content";
var fullImg = document.createElement("img"); var bigImg = document.createElement("img");
fullImg.src = origSrc; bigImg.src = src;
fullImg.alt = altText; bigImg.alt = altText;
var closeBtn = document.createElement("button"); var closeBtn = document.createElement("button");
closeBtn.className = "md-image-lightbox-close"; closeBtn.className = "md-image-lightbox-close";
closeBtn.textContent = "\u2715"; closeBtn.textContent = "\u2715";
container.appendChild(fullImg); containerEl.appendChild(bigImg);
container.appendChild(closeBtn); containerEl.appendChild(closeBtn);
overlay.appendChild(container); overlay.appendChild(containerEl);
document.body.appendChild(overlay); document.body.appendChild(overlay);
document.body.style.overflow = "hidden"; document.body.style.overflow = "hidden";
@ -97,7 +119,7 @@
overlay.addEventListener("click", function () { overlay.addEventListener("click", function () {
cleanup(overlay, onKey); cleanup(overlay, onKey);
}); });
container.addEventListener("click", function (ev) { containerEl.addEventListener("click", function (ev) {
ev.stopPropagation(); ev.stopPropagation();
}); });
closeBtn.addEventListener("click", function () { closeBtn.addEventListener("click", function () {
@ -105,7 +127,7 @@
}); });
document.addEventListener("keydown", onKey); document.addEventListener("keydown", onKey);
}); });
})(originalSrc, img.alt || ""); })(fullSrc, fullImg.getAttribute("alt") || "");
} }
} }