JS实现图片和滚动事件上的懒加载

记录一下图片和页面滚动的懒加载

1、使用Intersection Observer API进行图片的懒加载

Intersection Observer API是一个JavaScript API,允许开发人员观察元素与特定祖先或视口的交叉变化。它跟踪目标元素的可见性,并在元素进入或离开视图时通知开发人员。它非常适用于延迟加载图像,因为它在图像进入或离开视口时通知我们,从而允许我们根据需要加载图像。它在一个单独的线程上运行,不会阻塞主JavaScript线程。该API不仅限于图像,还可以用于延迟加载任何内容,例如视频、iframe甚至是生成的页面部分。

多个Intersection Observers可以同时观察同一页上的不同元素。例如,假设您有一个页面上有多个图像,并且希望在用户向下滚动页面时延迟加载这些图像。下面是如何使用Intersection Observer API和原生JavaScript实现延迟加载的方法。要开始,请确保您有一个基本的HTML结构,其中包含带有 img 标签的 data-src 属性,指定图像的实际源URL。我们将使用 data-src 来存储图片的URL,而不是使用传统的 src 属性来实现图片的懒加载。

<!DOCTYPE html>
<html>
<head>
 <title>Lazy Loading Images</title>
</head>
<body>
 <h1>Lazy Loading Images Example</h1>
 <img class="lazy" data-src="image1.jpg" alt="Image 1">
 <img class="lazy" data-src="image2.jpg" alt="Image 2">
 <!-- Add more images with the "lazy" class and "data-src" attribute -->
</body>
</html>

在我们的JavaScript代码中,我们将创建一个Intersection Observer的实例,并指定一个回调函数,每当观察的元素进入或离开视口时,该函数将被触发。

// Get all elements with the "lazy" class
const lazyImages = document.querySelectorAll(".lazy");
// Create a new Intersection Observer
const observer = new IntersectionObserver((entries, observer) => {
    
    
 entries.forEach((entry) => {
    
    
  if (entry.isIntersecting) {
    
    
   // Load the image when it comes into the viewport
   entry.target.src = entry.target.dataset.src;
   observer.unobserve(entry.target); // Unobserve the image after it's loaded
  }
 });
});
// Observe each lazy image
lazyImages.forEach((image) => {
    
    
 observer.observe(image);
});

在上面的代码中,首先使用 document.querySelectorAll(“.lazy”) 选择所有具有“lazy”类的元素。然后,我们创建一个新的Intersection Observer实例,传入一个回调函数,每当观察的元素(在这种情况下是懒加载的图片)进入或退出视口时触发。当观察到一张图片并进入视口时(即 entry.isIntersecting 为真),我们将其 src 属性设置为 data-src 的值,该值保存了实际的图片URL。这个操作触发了图片的懒加载。然后,我们调用 observer.unobserve(entry.target) 来停止观察图片一旦加载完成以优化性能。

2. 滚动事件上的懒加载内容

基于滚动事件的方法可以实现高度定制的懒加载实现。您可以完全控制内容何时以及如何加载,使其适用于需要在元素可见时执行特定任务或转换的场景。滚动事件是JavaScript的一个特性,被所有现代浏览器支持。这意味着您不必担心兼容性问题。

对于单页应用程序,其中内容随着用户浏览网站而加载,使用滚动事件可能更直观。与Intersection Observer API最适合图像和特定元素不同,基于滚动事件的懒加载提供了更多的灵活性。您可以将其应用于任何内容或复杂组件,这些内容可能不适合“在视图中”的概念。让我们看一个例子。在这里,您将再次拥有一个基本的HTML结构,其中包含要惰性加载的元素。但是,这次我们不需要像 data-src 这样的特殊属性。

<!DOCTYPE html>
<html>
<head>
 <title>Lazy Loading Content on Scroll</title>
</head>
<body>
 <h1>Lazy Loading Content Example</h1>
 <div class="lazy-content">
  <p>Some content to be lazily loaded...</p>
 </div>
 <div class="lazy-content">
  <p>More content to be lazily loaded...</p>
 </div>
 <!-- Add more elements with the "lazy-content" class -->
</body>
</html>

在我们的JavaScript代码中,你将会有一个函数 isElementInViewport(element) ,它会检查一个元素是否在视口中,然后定义一个 lazyLoadContent() 函数,该函数使用 document.querySelectorAll(“.lazy-content”) 遍历所有具有“lazy-content”类的元素。

// Function to check if an element is in the viewport
function isElementInViewport(element) {
    
    
 const rect = element.getBoundingClientRect();
 return (
  rect.top >= 0 &&
  rect.left >= 0 &&
  rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
  rect.right <= (window.innerWidth || document.documentElement.clientWidth)
 );
}
// Function to lazily load content
function lazyLoadContent() {
    
    
 const lazyContentElements = document.querySelectorAll(".lazy-content");
 lazyContentElements.forEach((element) => {
    
    
  if (isElementInViewport(element)) {
    
    
   // Add your logic to load the content for the element here
   element.classList.add("loaded");
  }
 });
}
// Attach the lazyLoadContent function to the scroll event
window.addEventListener("scroll", lazyLoadContent);
// Call the function initially to load the visible content on page load
lazyLoadContent();

对于每个元素,它使用 isElementInViewport(element) 检查它是否在视口中,如果为真,则加载该元素的内容。在这个例子中,我们只是给元素添加一个类名“loaded”,但你可以根据你的使用情况自定义这部分。然后,我们使用 window.addEventListener(“scroll”, lazyLoadContent) 将 lazyLoadContent() 函数附加到滚动事件上。这确保了每当用户滚动页面时都会调用该函数。此外,我们在页面加载时调用 lazyLoadContent() 来加载可见内容。

猜你喜欢

转载自blog.csdn.net/weixin_45324044/article/details/132402938