使用 IntersectionObserver API 进行延迟加载
GenAI LIVE! | 2025年6月4日
大家好。在这篇文章中,我将提供一些有关IntersectionObserver API的信息。
在开始之前,我应该说一下 IE11 不支持这个 API。你可以在CanIUse上查看哪些浏览器支持这个 API 。
为什么?
有很多库支持延迟加载操作。我知道,但这个 API 是原生的。你可能不想使用外部库等等。
在一个项目中,我们有很多图片和列表项。由于这些图片,页面加载时间长达10-15秒。这对我们、我们的客户、访客等来说都很糟糕。
我们找到了一些解决方案,比如服务器端分页。但这对我们的项目来说不是一个好的解决方案。因为客户不想重新加载页面。
为了解决这个问题,我们找到了 Verlok 的lazyload库。但我们也找到了IntersectionObserver API。总之,我们决定使用 IntersectionObserver API。我们今天就用 IntersectionObserver。好的,我来演示一下。
HTML && CSS 代码
在此示例中,我们将使用 Bootstrap 4 的 Card 组件。我们还使用按钮组件来跟踪索引。默认索引为 0(零)。
<div class="container">
<div class="row">
<div class="col-md-12 card-container">
</div>
</div>
<div class="row">
<div class="col-md-12 load-more-container">
<button data-index="0" class="btn btn-primary btn-block load-more">Load More</button>
</div>
</div>
</div>
CSS 代码如下。只需要一点边距。现在我们的卡片看起来更漂亮了。
.load-more-container {
margin-top: 15px;
}
.card {
margin-bottom: 15px;
}
JavaScript代码
我将创建一个类。您可能需要创建一个函数。这取决于您。该类将以如下方式启动。它的名称为LazyLoad。
class LazyLoad {
constructor() {
this.btn = document.querySelector(".load-more")
this.cardContainer = document.querySelector('.card-container')
this.BASE_URL = 'https://picsum.photos/list'
}
}
我们将为图像提供 API 服务器。
在这个例子中,我们总是从这个服务器调用所有图片。因为我找不到任何分页功能。
然后,我将创建一个名为load的函数。
load() {
fetch(this.BASE_URL)
.then(resp => resp.json())
.then(obj => {
let start = (this.btn.dataset.index == 0) ? parseInt(this.btn.dataset.index) : parseInt(this.btn.dataset.index) + 1
let end = start + 5
let arr = obj.slice(start, end)
if(arr.length > 0) {
let cards = '';
arr.forEach(f => {
cards += `
<div class="card">
<div class="card-body">
<h5 class="card-title">${f.author}</h5>
<img src="https://picsum.photos/458/354/?image=${f.id}" alt="">
</div>
</div>
`
})
this.cardContainer.insertAdjacentHTML('beforeend',cards)
this.btn.dataset.index = end
}
})
}
通过此函数,我们将创建获取请求。我们还将使用模板字面量创建 HTML 内容,并将其放入.card-container
。
最后,我们将创建一个名为init的函数。该函数如下所示:
init() {
const container = document.querySelector(".load-more-container")
let observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
const { isIntersecting } = entry
if(isIntersecting) {
this.load()
//observer = observer.disconnect()
}
}, {
root: container
})
})
observer.observe(container)
}
在上面的代码中,当元素与用户视口相交时,代码将被运行。IntersectionObserver 提供两个参数。第一个参数是回调函数。第二个参数是选项。在本例中,我们只有root
选项。
接收一个或多个交集条目的回调。观察者将观察我们创建的容器。
observer.observe(container)
使用observer = observer.disconnect()
您将停止观察操作。这意味着更多加载功能将无法使用。
完成之前
如果你想要一个真实的例子,我在 CodePen 上创建了一个示例。你可以看看它是如何工作的。
资源
我希望这篇文章能够对您的项目有所帮助。
感谢阅读!
鏂囩珷鏉ユ簮锛�https://dev.to/itachiuchiha/lazy-loading-with-the-intersectionobserver-api-44pe