Files
momo/templates/index.2.html
2025-06-13 22:40:00 +08:00

203 lines
4.4 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-hans">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Momo</title>
<style>
.waterfall-container {
position: relative;
width: 100%;
}
.waterfall-item {
position: absolute;
width: calc(33.33% - 20px);
/* 三列布局,考虑间距 */
margin: 10px;
transition: all 0.3s ease;
}
.waterfall-item img {
width: 100%;
height: auto;
display: block;
border-radius: 4px;
}
/* 懒加载时的占位样式 */
.lazy {
background-color: #f5f5f5;
min-height: 200px;
/* 根据你的设计调整 */
}
img {
transition: all 0.5s;
}
img:hover {
transform: scale(1.3);
/*图片放大1.1倍*/
margin-top: 30px;
/*鼠标悬停时上移30px*/
margin-top: 0px;
box-shadow: 0 0 20px 2px #918f8f;
/*盒子阴影*/
transition: all 0.5s;
/*持续时间*/
}
.waterfall-item.loading {
opacity: 0.8;
}
/* 响应式调整 */
@media (min-width: 1200px) {
.waterfall-item {
width: calc(25% - 20px);
}
}
@media (max-width: 768px) {
.waterfall-item {
width: calc(50% - 200px);
/* 两列布局 */
}
}
@media (max-width: 480px) {
.waterfall-item {
width: calc(100% - 20px);
/* 单列布局 */
}
}
</style>
</head>
<body>
<div class="waterfall-container">
{% for img in imgs %}
<div class="waterfall-item">
<img class="lazy" data-src="{{img.path}}" alt="">
</div>
{% endfor %}
</div>
</body>
<script>
const column_width = {{column_width}};
function get_column_count(width) {
return parseInt(width/column_width)
}
// 使用防抖函数优化性能
function debounce(func, wait) {
let timeout;
return function () {
const context = this, args = arguments;
clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(context, args);
}, wait);
};
}
function layoutWaterfall() {
const container = document.querySelector('.waterfall-container');
const items = document.querySelectorAll('.waterfall-item:not(.loading)'); // 排除正在加载的项
const columnCount = get_column_count(window.innerWidth); // 响应式列数
// const columnCount = window.innerWidth < 768 ? 2 : 3; // 响应式列数
const gap = 20;
const containerWidth = container.offsetWidth;
const columnWidth = (containerWidth - gap * (columnCount - 1)) / columnCount;
const columnHeights = new Array(columnCount).fill(0);
items.forEach(item => {
item.style.width = `${columnWidth}px`;
const minHeight = Math.min(...columnHeights);
const columnIndex = columnHeights.indexOf(minHeight);
const left = columnIndex * (columnWidth + gap);
const top = minHeight;
item.style.left = `${left}px`;
item.style.top = `${top}px`;
columnHeights[columnIndex] += item.offsetHeight + gap;
});
container.style.height = `${Math.max(...columnHeights)}px`;
}
// 增强版的懒加载函数
function lazyLoadImages() {
const lazyImages = document.querySelectorAll('img.lazy');
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
const item = img.closest('.waterfall-item');
// 标记为正在加载
item.classList.add('loading');
// 创建新的Image对象预加载
const tempImg = new Image();
tempImg.src = img.dataset.src;
tempImg.onload = function () {
img.src = img.dataset.src;
img.classList.remove('lazy');
item.classList.remove('loading');
// 图片加载完成后重新布局
layoutWaterfall();
};
tempImg.onerror = function () {
item.classList.remove('loading');
// 可以在这里添加错误处理
};
observer.unobserve(img);
}
});
}, {
rootMargin: '200px 0px' // 提前200px开始加载
});
lazyImages.forEach(img => {
observer.observe(img);
});
}
// 初始化并添加事件监听
function initWaterfall() {
layoutWaterfall();
lazyLoadImages();
// 使用防抖函数优化resize性能
window.addEventListener('resize', debounce(() => {
layoutWaterfall();
}, 200));
// 监听DOM变化如果有动态加载的内容
const observer = new MutationObserver(debounce(() => {
layoutWaterfall();
lazyLoadImages();
}, 100));
observer.observe(document.body, {
subtree: true,
childList: true,
attributes: true
});
}
document.addEventListener('DOMContentLoaded', initWaterfall);
</script>
</html>