原因:
使用图片懒加载可以解决以上问题
总体来说就是:
loading 属性指定浏览器是应立即加载图像还是延迟加载图像。 设置 loading="lazy" 只有鼠标滚动到该图片所在位置才会显示
语法:
<img src="URL" loading="eager|lazy">
属性值
值 | 描述 |
---|---|
eager | 默认,图像立即加载。 |
lazy | 图像延迟加载,只有鼠标滚动到该图片所在位置才会显示。 |
(1)获取浏览器窗口高度(可视区域高度)
浏览器窗口高度通过 window.innerHeight
这个 API
来获取
const viewportHeight = window.innerHeight
(2)获取元素距离浏览器窗口顶部的高度
获取元素距离可视区域顶部的高度需要通过getBoundingClientRect()
API 来实现,getBoundingClientRect()
获取的是 DOM 元素相对于窗口的坐标集合,集合中有多个属性,其中的 top
属性就是当前元素元素距离窗口可视区域顶部的距离
const element = document.getElementById("your-element-id");
const distanceToTop = element.getBoundingClientRect().top;
从上面这张图里面,我们就会得知:
负数
, 说明该元素处在浏览器的可视区域内
正数
, 说明该元素于浏览器的可视区域的外面
因此我们就可以编写我们的代码了:
lazyload 函数
,用于将当前视口的图片给展现出来 <img data-src="./image/1.jpg" src="http://iph.href.lu/200x200" alt="" id="one">
<img data-src="./image/2.jpg" src="http://iph.href.lu/200x200" alt="">
<img data-src="./image/3.jpg" src="http://iph.href.lu/200x200" alt="">
<img data-src="./image/3.png" src="http://iph.href.lu/200x200" alt="">
<img data-src="./image/5.jpg" src="http://iph.href.lu/200x200" alt="">
<img data-src="./image/6.jpg" src="http://iph.href.lu/200x200" alt="">
<img data-src="./image/7.jpg" src="http://iph.href.lu/200x200" alt="">
<img data-src="./image/1.jpg" src="http://iph.href.lu/200x200" alt="" id="one">
<img data-src="./image/2.jpg" src="http://iph.href.lu/200x200" alt="">
<img data-src="./image/3.jpg" src="http://iph.href.lu/200x200" alt="">
<img data-src="./image/3.png" src="http://iph.href.lu/200x200" alt="">
<img data-src="./image/5.jpg" src="http://iph.href.lu/200x200" alt="">
<img data-src="./image/6.jpg" src="http://iph.href.lu/200x200" alt="">
<img data-src="./image/7.jpg" src="http://iph.href.lu/200x200" alt="">
<script>
// 获取所有img元素
const imgarr = document.querySelectorAll('img');
// 获取浏览器的可视区域的高度
// 获取浏览器的可视区域的高度
const clientHeight = window.innerHeight
// 使用 debounce 函数来优化滚动事件
function debounce(func, wait) {
let timeout;
return function () {
const context = this;
const args = arguments;
clearTimeout(timeout);
timeout = setTimeout(function () {
func.apply(context, args);
}, wait);
};
}
// 优化后的 lazyload 函数
function lazyload() {
for (let i = 0; i < imgarr.length; i++) {
const distanceWindowTop = imgarr[i].getBoundingClientRect().top;
// 如果图片距离页面顶部的距离小于等于可视区域的高度,就加载图片
if (distanceWindowTop - clientHeight <= 0) {
imgarr[i].src = imgarr[i].getAttribute('data-src');
}
}
}
// 添加 debounce 后的滚动事件监听
const debouncedLazyLoad = debounce(lazyload, 200); // 调整需要的等待时间
window.addEventListener('scroll', debouncedLazyLoad);
// // 初次加载页面时执行一次 lazyload
document.addEventListener('DOMContentLoaded', lazyload);
</script>
</body>
效果:
IntersectionObserver
是一个在浏览器中提供的用于异步观察目标元素与其祖先元素或视口交叉情况的API。它可以有效地用于实现懒加载、无限滚动等场景。
IntersectionObserver
对象是观察器,负责观察目标元素的交叉状态。
目标元素是你希望观察的 DOM 元素。
目标元素与其祖先元素或视口的交叉状态,包括进入视口、离开视口等情况。
new IntersectionObserver(callback, options);
callback
是一个回调函数,会在目标元素的交叉状态发生变化时被调用。options
是一个配置对象,用于设置观察器的参数,例如 threshold
(交叉比例)等。 const observer = new IntersectionObserver(callback, options);
observer.observe(targetElement);
observe
方法,观察器会开始观察该元素。被 IntersectionObserver
观察的目标元素,当它们进入或离开视口时,会触发指定的回调函数(callback)。
function callback(entries, observer) {
entries.forEach(entry => {
// 处理每个目标元素的交叉状态变化
if (entry.isIntersecting) {
// 目标元素进入视口
} else {
// 目标元素离开视口
}
});
}
entries
数组,每个数组元素是一个 IntersectionObserverEntry
对象,表示一个观察的目标元素的状态。isIntersecting
为 true
,则表示目标元素正在视口内;如果为 false
,则表示目标元素已经离开视口。observer
参数是一个指向创建该 IntersectionObserver
实例的对象的引用。这个参数允许你在回调函数中调用 unobserve
方法,以停止观察某个特定的目标元素。unobserve
方法取消观察。使用IntersectionObserver 进行图片懒加载
// 获取所有带有 data-src 属性的 img 元素
const imageArr = document.querySelectorAll('img[data-src]')
// IntersectionObserver 的配置项
const config = {
threshold: 0.5, // 表示当目标元素的50%进入视口时触发回调
}
// 创建 IntersectionObserver 实例
let observer = new IntersectionObserver((entries, observer) => {
entries.forEach((entry) => {
// 如果目标元素进入视口
if (entry.isIntersecting) {
let img = entry.target
let src = img.dataset.src
// 如果存在 data-src 属性,则加载图片并移除 data-src 属性
if (src) {
img.src = src
img.removeAttribute('data-src')
}
// 解除观察
observer.unobserve(entry.target)
}
})
}, config)
// 遍历所有带有 data-src 属性的 img 元素并开始观察
imageArr.forEach((image) => {
observer.observe(image)
})
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。