
要在JS原生中实现图片懒加载,可以通过Intersection Observer API、监听滚动事件、设置图像占位符三种方式来完成。 其中,使用Intersection Observer API是最推荐的方式,因为它性能更优,代码更简洁。下面将详细介绍如何使用Intersection Observer API来实现图片懒加载。
一、Intersection Observer API
Intersection Observer API是现代浏览器提供的一个强大的工具,用于检测元素是否进入视口。通过这个API,我们可以轻松实现图片懒加载,而不需要频繁监听滚动事件。
1、创建Intersection Observer
首先,我们需要创建一个Intersection Observer实例。这个实例会监视目标元素并在它们进入或离开视口时触发回调函数。
let observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
let img = entry.target;
img.src = img.dataset.src; // 将真实图片URL替换占位符URL
observer.unobserve(img); // 图片加载后停止观察
}
});
}, {
root: null, // 默认为视口
rootMargin: "0px",
threshold: 0.1 // 交叉比例
});
2、将图片添加到观察列表
接下来,我们需要将需要懒加载的图片添加到观察列表中。假设我们有以下HTML结构:
<img data-src="real-image.jpg" src="placeholder.jpg" alt="Lazy Load Image">
我们可以使用以下JavaScript代码将图片添加到观察列表中:
document.querySelectorAll('img[data-src]').forEach(img => {
observer.observe(img);
});
通过这样做,当图片进入视口时,Intersection Observer会触发回调函数,并将图片的真实URL替换占位符URL。
3、示例代码
综合以上步骤,完整的示例代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Lazy Load Images</title>
</head>
<body>
<img data-src="real-image1.jpg" src="placeholder.jpg" alt="Lazy Load Image 1">
<img data-src="real-image2.jpg" src="placeholder.jpg" alt="Lazy Load Image 2">
<img data-src="real-image3.jpg" src="placeholder.jpg" alt="Lazy Load Image 3">
<script>
let observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
let img = entry.target;
img.src = img.dataset.src;
observer.unobserve(img);
}
});
}, {
root: null,
rootMargin: "0px",
threshold: 0.1
});
document.querySelectorAll('img[data-src]').forEach(img => {
observer.observe(img);
});
</script>
</body>
</html>
二、监听滚动事件
尽管Intersection Observer API是实现懒加载的最佳方式,但在一些旧浏览器中可能不被支持。此时,我们可以使用监听滚动事件的方式来实现图片懒加载。
1、监听滚动事件
首先,我们需要监听窗口的滚动事件。
window.addEventListener('scroll', lazyLoad);
2、判断图片是否进入视口
在滚动事件的回调函数中,我们需要判断图片是否进入视口。如果是,则加载图片。
function lazyLoad() {
let images = document.querySelectorAll('img[data-src]');
images.forEach(img => {
if (img.getBoundingClientRect().top < window.innerHeight) {
img.src = img.dataset.src;
img.removeAttribute('data-src');
}
});
}
3、示例代码
综合以上步骤,完整的示例代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Lazy Load Images</title>
</head>
<body>
<img data-src="real-image1.jpg" src="placeholder.jpg" alt="Lazy Load Image 1">
<img data-src="real-image2.jpg" src="placeholder.jpg" alt="Lazy Load Image 2">
<img data-src="real-image3.jpg" src="placeholder.jpg" alt="Lazy Load Image 3">
<script>
function lazyLoad() {
let images = document.querySelectorAll('img[data-src]');
images.forEach(img => {
if (img.getBoundingClientRect().top < window.innerHeight) {
img.src = img.dataset.src;
img.removeAttribute('data-src');
}
});
}
window.addEventListener('scroll', lazyLoad);
window.addEventListener('load', lazyLoad); // Initial check
</script>
</body>
</html>
三、设置图像占位符
为了在图片加载前提供更好的用户体验,我们可以设置图像占位符。这不仅能告知用户有图片在加载,还能防止页面布局在图片加载前后发生变化。
1、使用CSS设置占位符
首先,我们可以使用CSS设置占位符。假设我们有以下HTML结构:
<img class="lazy" data-src="real-image.jpg" src="placeholder.jpg" alt="Lazy Load Image">
我们可以使用以下CSS代码设置占位符样式:
img.lazy {
display: block;
width: 100%;
height: auto;
background: url('loading-spinner.gif') center center no-repeat;
}
2、移除占位符
当图片加载完成后,我们可以移除占位符。假设我们使用Intersection Observer API来实现懒加载,可以在回调函数中移除占位符样式:
let observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
let img = entry.target;
img.src = img.dataset.src;
img.onload = () => {
img.classList.remove('lazy');
};
observer.unobserve(img);
}
});
}, {
root: null,
rootMargin: "0px",
threshold: 0.1
});
3、示例代码
综合以上步骤,完整的示例代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Lazy Load Images</title>
<style>
img.lazy {
display: block;
width: 100%;
height: auto;
background: url('loading-spinner.gif') center center no-repeat;
}
</style>
</head>
<body>
<img class="lazy" data-src="real-image1.jpg" src="placeholder.jpg" alt="Lazy Load Image 1">
<img class="lazy" data-src="real-image2.jpg" src="placeholder.jpg" alt="Lazy Load Image 2">
<img class="lazy" data-src="real-image3.jpg" src="placeholder.jpg" alt="Lazy Load Image 3">
<script>
let observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
let img = entry.target;
img.src = img.dataset.src;
img.onload = () => {
img.classList.remove('lazy');
};
observer.unobserve(img);
}
});
}, {
root: null,
rootMargin: "0px",
threshold: 0.1
});
document.querySelectorAll('img[data-src]').forEach(img => {
observer.observe(img);
});
</script>
</body>
</html>
四、性能优化
在实现图片懒加载时,我们还需要考虑性能优化。以下是一些常见的优化策略:
1、减少监听事件
如果使用滚动事件来实现懒加载,我们需要尽量减少监听事件的频率。可以使用debounce或throttle函数来限制滚动事件的触发频率。
function debounce(func, wait) {
let timeout;
return function(...args) {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), wait);
};
}
window.addEventListener('scroll', debounce(lazyLoad, 200));
2、使用图片压缩
为了减少图片加载时间,我们可以使用图片压缩技术。可以在服务器端使用工具如ImageMagick或在线压缩工具如TinyPNG来压缩图片。
3、延迟加载非关键图片
对于一些非关键图片,如页面底部的图片,可以延迟加载,直到用户滚动到该位置。这不仅能提高页面加载速度,还能减少用户的等待时间。
五、兼容性处理
尽管Intersection Observer API在现代浏览器中得到了广泛支持,但在一些旧浏览器中可能不被支持。我们可以使用polyfill来增加兼容性。
<script src="https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserver"></script>
六、总结
图片懒加载是一种提高网页性能和用户体验的有效方法。通过使用Intersection Observer API、监听滚动事件、设置图像占位符等方式,我们可以轻松实现图片懒加载。为了进一步优化性能,我们还可以使用图片压缩、减少监听事件、延迟加载非关键图片等策略。希望这篇文章能帮助你更好地理解和实现图片懒加载。
相关问答FAQs:
1. 图片懒加载是什么?
图片懒加载是一种优化网页性能的技术,它延迟加载页面上的图片,只在用户滚动到可见区域时再加载,以减少页面的加载时间和带宽消耗。
2. 如何使用原生JavaScript实现图片懒加载?
要实现图片懒加载,可以按照以下步骤进行:
a. 首先,给需要懒加载的图片添加一个占位符,例如使用一个1×1像素的透明图片。
b. 其次,使用JavaScript监听窗口的滚动事件,判断图片是否进入可见区域。
c. 当图片进入可见区域时,使用JavaScript动态替换占位符图片的src属性为真实的图片路径,从而实现懒加载效果。
3. 如何判断图片是否进入可见区域?
判断图片是否进入可见区域的一种常用方法是通过计算图片相对于窗口顶部的位置来确定。可以使用getBoundingClientRect()方法获取图片的位置信息,然后根据窗口的滚动位置和可见区域的高度来判断是否进入可见区域。
另外,还可以结合Intersection Observer API来实现图片懒加载。这个API提供了一种更高效的方式来监听元素是否进入可见区域,同时还可以设置阈值来控制何时加载图片,以进一步优化性能。
文章包含AI辅助创作,作者:Edit2,如若转载,请注明出处:https://docs.pingcode.com/baike/3734384