JavaScript实现瀑布流动态加载图片主要涉及到以下几个方面的内容:
- 获取图片数据
- 动态创建图片元素
- 计算图片位置
- 监听滚动事件
- 懒加载图片
下面我们一一讲解。
获取图片数据
瀑布流需要加载大量的图片,首先需要获取图片的数据。需要注意的是,为了实现动态加载,我们要考虑异步加载。
示例代码:
function getImagesData(callback) {
fetch('http://example.com/images') // 发送请求获取图片数据
.then(response => response.json()) // 将返回结果解析为JSON格式
.then(data => callback(data)) // 将解析后的数据通过回调函数传回
.catch(error => console.error(error)); // 处理错误
}
通过上面的代码,我们可以从服务器获取到图片的数据并进行处理。但是如果图片数据很多,这样一次性获取所有图片的数据会占用很多网络带宽和资源,从而影响页面加载速度。因此,我们需要动态地去生成图片元素,而不是一次性地获取所有图片的数据。
动态创建图片元素
我们可以通过document.createElement
方法动态地创建图片元素,并将图片数据中的图片地址赋值给img
元素的src
属性。
示例代码:
function createImageElement(data) {
const img = document.createElement('img');
img.src = data.url;
// 此处可以设置图片的其他属性
return img;
}
上述代码首先创建了一个img
元素,并将图片URL赋值给img
的src
属性,然后可以根据需要为该元素设置其他属性。
计算图片位置
计算图片的位置是瀑布流实现的核心,下面我们来解释一下具体实现思路。
首先,我们需要设计一个对象,来保存各列的高度,方便我们对之后的图片进行定位。
示例代码:
const columns = [
{ height: 0, elem: document.querySelector('.col1') },
{ height: 0, elem: document.querySelector('.col2') },
// ...
];
对象数组columns
中,每个对象分别保存了列的高度以及对应的DOM元素。
然后在每次添加图片的时候,我们就可以通过计算高度最小的那一列的高度,来定位新加入的图片。
示例代码:
function getPosition() {
let minHeight = columns[0].height;
let minColumn = 0;
for (let i = 1; i < columns.length; i++) {
if (columns[i].height < minHeight) {
minHeight = columns[i].height;
minColumn = i;
}
}
return minColumn;
}
function setLocation(img) {
const minIndex = getPosition();
const { height } = columns[minIndex];
const width = img.offsetWidth;
const left = minIndex * (width + 10);
const top = height + 10;
img.style.cssText = `left:${left}px;top:${top}px;`;
columns[minIndex].height += img.offsetHeight + 10;
}
在getPosition
函数中,我们计算出高度最小的列的索引。在setLocation
函数中,我们通过该索引计算出图片的位置信息,并通过cssText
设置img
的样式属性。
监听滚动事件
在页面加载或者滚动时,需要检查是否需要加载新的图片。这里我们考虑在页面滚动到底部或者接近底部时,加载新的图片。
示例代码:
let isLoading = false; // 判断是否正在加载的标识
function lazyLoad() {
if (isLoading) return; // 当前正在进行加载则退出
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 + 300 >= scrollHeight) {
isLoading = true; // 标记为正在加载
getImagesData(data => {
data.forEach(item => {
const img = createImageElement(item);
setLocation(img);
document.body.appendChild(img);
});
isLoading = false; // 标记为加载完成
});
}
}
window.addEventListener('scroll', lazyLoad);
在lazyLoad
函数中,首先获取滚动条滚动的高度、可视区域的高度以及文档的高度,然后计算是否已经滚动到页面底部或接近底部,在此情况下,我们就可以执行图片加载操作。
值得注意的是,在getImagesData
函数执行之前,需要将isLoading
标识设置为true
,表示正在加载。在回调函数中,当所有图片加载完成之后,需要将该标识重置为false
。
懒加载图片
为了提高页面加载速度,我们还需要使用懒加载技术。图片的懒加载可以使用Intersection Observer
实现。
示例代码:
const observer = new IntersectionObserver(entries => {
// 如果进入视窗的元素是图片,则将其加载
entries.forEach(entry => {
if (entry.isIntersecting && entry.target.tagName.toLowerCase() === 'img') {
const img = entry.target;
img.src = img.dataset.src;
observer.unobserve(img); // 停止观察已经加载的图片
}
});
});
function lazyLoadByObserver() {
const imgs = document.querySelectorAll('img[data-src]');
imgs.forEach(img => observer.observe(img));
}
上述代码首先创建了一个IntersectionObserver
观察器,并通过observe
方法观察所有具有data-src
属性的图片。当某个图片进入视窗时,观察器就会调用回调函数,这时我们就可以将img
元素的data-src
属性赋值给src
属性,从而加载图片。
最后,我们需要在页面加载完成之后进行一次图片的懒加载:
window.addEventListener('load', lazyLoadByObserver);
至此,我们就完成了JavaScript实现瀑布流动态加载图片的完整攻略。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:javascript实现瀑布流动态加载图片原理 - Python技术站