下面是关于 "javascript瀑布流式图片懒加载实例" 的完整攻略:
概述
本文将讲述如何使用 JavaScript 实现瀑布流式图片懒加载,以及如何实现懒加载动画效果。瀑布流是一种瀑布般的布局方式,能够有效节省页面空间,而懒加载则是一种优化网站性能的常用方法,能够有效减少页面初次加载的时间。
实现步骤
- 首先,需要在 HTML 文件中添加一个装载图片的容器,通常使用
div
标签。如下所示:
<div id="imageContainer">
<!--图片显示区域-->
</div>
- 在 JavaScript 中获取该容器并创建需要的变量。
const imageContainer = document.getElementById('imageContainer');
let images = [];
let current = 0;
let limit = 20; // 一次加载几张图片
let imageWidth = 200; //图片的宽度
let imageHeight = 0; //图片的高度
let columnCount = 3; //瀑布流的列数
let loading = false; //加载完成标志
- 创建一个获取图片信息的函数,获取图片的宽度和高度信息。
function getImageInfo(image) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => {
// 返回图片的宽、高。
resolve({
width: img.width,
height: img.height
});
};
img.onerror = reject;
img.src = image.src;
});
}
- 创建一个函数,用于按瀑布流式布局展示图片。
function waterfall() {
// 计算容器的宽度和每列的宽度
const containerWidth = imageContainer.offsetWidth;
const columnWidth = parseInt(containerWidth / columnCount);
//高度数组,记录每列的高度
const heightArr = new Array(columnCount).fill(0);
for (let i = current; i < current + limit; i++) {
//判断是否已经全部加载完毕
if (i >= images.length) {
loading = false;
return;
}
// 创建图片所在的容器
const imageItem = document.createElement('div');
imageItem.className = 'image-item';
imageItem.style.width = imageWidth + 'px';
//创建图片标签
const image = document.createElement('img');
image.src = images[i].src;
image.dataset.index = i;
//计算下载完成后的图片的高度
getImageInfo(image).then((result) => {
imageHeight = parseInt(imageWidth * result.height / result.width);
//根据高度和高度数组,计算图片位置
const idx = getMinHeightIndex(heightArr);
const left = idx * columnWidth;
const top = heightArr[idx];
//设置图片样式和属性
image.style.width = imageWidth + 'px';
image.style.height = imageHeight + 'px';
image.style.left = left + 'px';
image.style.top = top + 'px';
//记录该列的高度
heightArr[idx] += imageHeight;
//绑定图片点击事件
image.addEventListener('click', function () {
console.log('你点击了第' + this.dataset.index + '张图片。');
});
//把该图片添加到容器中
imageItem.append(image);
imageContainer.append(imageItem);
});
}
// 根据总高度调整容器高度
const containerHeight = Math.max.apply(null, heightArr);
imageContainer.style.height = containerHeight + 'px';
//增加计数器
current += limit;
}
- 创建一个函数,用于获取当前高度最小的列序号。
function getMinHeightIndex(arr) {
let index = 0;
let minHeight = arr[0];
for (let i = 1; i < arr.length; i++) {
if (arr[i] < minHeight) {
minHeight = arr[i];
index = i;
}
}
return index;
}
- 创建一个触发懒加载的函数。
function checkScroll() {
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
const clientHeight = document.documentElement.clientHeight || document.body.clientHeight;
const scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
if (scrollTop + clientHeight >= scrollHeight - 50 && !loading) {
loading = true;
//进行瀑布流式布局展示图片
waterfall();
}
}
- 监听滚动事件,当滚动到页面底部时,进行懒加载。
window.addEventListener('scroll', function () {
checkScroll();
});
- 最后,在 CSS 中添加样式。
#imageContainer {
position: relative;
}
.image-item {
position: absolute;
transition: opacity 0.5s;
}
示例1
假设我们有一组图片 image1.jpg
~ image30.jpg
,这些图片的宽度和高度不一,我们希望按照瀑布流式布局展示图片,同时采用懒加载方式加载图片,还想通过添加动画效果来使图片加载更加流畅。
<!--html-->
<div id="imageContainer"></div>
<!--css-->
<style>
#imageContainer {
position: relative;
}
.image-item {
position: absolute;
transition: opacity 0.5s;
}
</style>
<!--javascript-->
<script>
const imageContainer = document.getElementById('imageContainer');
let images = [];
let current = 0;
let limit = 20;
let imageWidth = 200;
let imageHeight = 0;
let columnCount = 3;
let loading = false;
//获取图片信息函数
function getImageInfo(image) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => {
resolve({
width: img.width,
height: img.height
});
};
img.onerror = reject;
img.src = image.src;
});
}
//瀑布流式布局函数
function waterfall() {
const containerWidth = imageContainer.offsetWidth;
const columnWidth = parseInt(containerWidth / columnCount);
const heightArr = new Array(columnCount).fill(0);
for (let i = current; i < current + limit; i++) {
if (i >= images.length) {
loading = false;
return;
}
const imageItem = document.createElement('div');
imageItem.className = 'image-item';
imageItem.style.width = imageWidth + 'px';
const image = document.createElement('img');
image.src = images[i].src;
image.dataset.index = i;
getImageInfo(image).then((result) => {
imageHeight = parseInt(imageWidth * result.height / result.width);
const idx = getMinHeightIndex(heightArr);
const left = idx * columnWidth;
const top = heightArr[idx];
image.style.width = imageWidth + 'px';
image.style.height = imageHeight + 'px';
image.style.left = left + 'px';
image.style.top = top + 'px';
heightArr[idx] += imageHeight;
image.addEventListener('click', function () {
console.log('你点击了第' + this.dataset.index + '张图片。');
});
imageItem.append(image);
imageContainer.append(imageItem);
imageItem.style.opacity = 1;
});
}
const containerHeight = Math.max.apply(null, heightArr);
imageContainer.style.height = containerHeight + 'px';
current += limit;
}
//获取当前高度最小的列数
function getMinHeightIndex(arr) {
let index = 0;
let minHeight = arr[0];
for (let i = 1; i < arr.length; i++) {
if (arr[i] < minHeight) {
minHeight = arr[i];
index = i;
}
}
return index;
}
//触发懒加载
function checkScroll() {
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
const clientHeight = document.documentElement.clientHeight || document.body.clientHeight;
const scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
if (scrollTop + clientHeight >= scrollHeight - 50 && !loading) {
loading = true;
waterfall();
}
}
//监听页面滚动事件
window.addEventListener('scroll', function () {
checkScroll();
});
//加载图片
for (let i = 1; i <= 30; i++) {
images.push({
src: 'image' + i + '.jpg'
});
}
</script>
示例2
接下来,我们添加一个懒加载动画效果,让图片加载更显流畅。
<!--html-->
<div id="imageContainer"></div>
<!--css-->
<style>
#imageContainer {
position: relative;
}
.image-item {
position: absolute;
transition: opacity 0.5s;
}
.loader {
width: 30px;
height: 30px;
border: 5px solid #f3f3f3;
border-top-color: #3498db;
border-radius: 50%;
animation: spin 2s linear infinite;
position: absolute;
left: 50%;
top: 50%;
margin-left: -15px;
margin-top: -15px;
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
</style>
<!--javascript-->
<script>
const imageContainer = document.getElementById('imageContainer');
let images = [];
let current = 0;
let limit = 20;
let imageWidth = 200;
let imageHeight = 0;
let columnCount = 3;
let loading = false;
//获取图片信息函数
function getImageInfo(image) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => {
resolve({
width: img.width,
height: img.height
});
};
img.onerror = reject;
img.src = image.src;
});
}
//瀑布流式布局函数
function waterfall() {
const containerWidth = imageContainer.offsetWidth;
const columnWidth = parseInt(containerWidth / columnCount);
const heightArr = new Array(columnCount).fill(0);
for (let i = current; i < current + limit; i++) {
if (i >= images.length) {
loading = false;
return;
}
const imageItem = document.createElement('div');
imageItem.className = 'image-item';
imageItem.style.width = imageWidth + 'px';
const image = document.createElement('img');
image.src = images[i].src;
image.dataset.index = i;
//添加加载动画
const loader = document.createElement('div');
loader.className = 'loader';
imageItem.append(loader);
getImageInfo(image).then((result) => {
imageHeight = parseInt(imageWidth * result.height / result.width);
const idx = getMinHeightIndex(heightArr);
const left = idx * columnWidth;
const top = heightArr[idx];
image.style.width = imageWidth + 'px';
image.style.height = imageHeight + 'px';
image.style.left = left + 'px';
image.style.top = top + 'px';
heightArr[idx] += imageHeight;
image.addEventListener('click', function () {
console.log('你点击了第' + this.dataset.index + '张图片。');
});
imageItem.append(image);
imageContainer.append(imageItem);
imageItem.style.opacity = 1;
//移除加载动画
imageItem.removeChild(loader);
});
}
const containerHeight = Math.max.apply(null, heightArr);
imageContainer.style.height = containerHeight + 'px';
current += limit;
}
//获取当前高度最小的列数
function getMinHeightIndex(arr) {
let index = 0;
let minHeight = arr[0];
for (let i = 1; i < arr.length; i++) {
if (arr[i] < minHeight) {
minHeight = arr[i];
index = i;
}
}
return index;
}
//触发懒加载
function checkScroll() {
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
const clientHeight = document.documentElement.clientHeight || document.body.clientHeight;
const scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
if (scrollTop + clientHeight >= scrollHeight - 50 && !loading) {
loading = true;
waterfall();
}
}
//监听页面滚动事件
window.addEventListener('scroll', function () {
checkScroll();
});
//加载图片
for (let i = 1; i <= 30; i++) {
images.push({
src: 'image' + i + '.jpg'
});
}
</script>
这就是实现 "javascript瀑布流式图片懒加载实例" 的完整攻略。相信在这份攻略的指引下,您可以轻松地实现瀑布流式图片懒加载的效果,并增加一些流畅的动画效果。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:javascript瀑布流式图片懒加载实例 - Python技术站