懒加载

人走茶凉 提交于 2019-12-03 07:01:26

1. 懒加载

懒加载英文为lazy-loading或load-on-demand,顾名思义,就是按需延迟加载。典型的适用场景:

1) 随着页面滚动,延迟加载资源。

2) 实现资源随页面滚动无限生成。

2. 资源延迟加载(Pure Javascript)

 1 <!doctype html>
 2 <html lang="en">
 3   <head>
 4     <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
 5     <meta name="viewport" content="width=device-width, initial-scale=1" />
 6     <script type="text/javascript" src="/index.js"></script>
 7     <style type="text/css">
 8       .gallery { width: 80%; margin: auto; }
 9       .lazy-image { display: inline-block; width: 30%; height: 50vh; }
10     </style>
11   </head>
12   <body>
13     <div class="gallery">
14       <img class="lazy-image"> <img class="lazy-image"> <img class="lazy-image">
15       <img class="lazy-image"> <img class="lazy-image"> <img class="lazy-image">
16       <img class="lazy-image"> <img class="lazy-image"> <img class="lazy-image">
17       <img class="lazy-image"> <img class="lazy-image"> <img class="lazy-image">
18       <img class="lazy-image"> <img class="lazy-image"> <img class="lazy-image">
19       <img class="lazy-image"> <img class="lazy-image"> <img class="lazy-image">
20       <img class="lazy-image"> <img class="lazy-image"> <img class="lazy-image">
21       <img class="lazy-image"> <img class="lazy-image"> <img class="lazy-image">
22       <img class="lazy-image"> <img class="lazy-image"> <img class="lazy-image">
23       <img class="lazy-image"> <img class="lazy-image"> <img class="lazy-image">
24     </div>
25   </body>
26 </html>
 1 window.onload = () => {
 2   let lazyImages = [...document.querySelectorAll(".lazy-image")];
 3 
 4   lazyImages.forEach(image => {
 5     image.dataset.src = "https://picsum.photos/seed/" + Math.floor(Math.random() * 10000) + "/200.webp";
 6   });
 7 
 8   function handler() {
 9     lazyImages.forEach(image => {
10       let imageTop = image.getBoundingClientRect().top + window.pageYOffset;
11 
12       if(imageTop < window.innerHeight + window.pageYOffset) 
13         image.src = image.dataset.src;
14     });
15   };
16 
17   handler();
18 
19   window.addEventListener("scroll", handler);
20   window.addEventListener("resize", handler);

3. 资源延迟加载(IntersectionObserver)

 1 window.onload = () => {
 2   function handler(entryies, observer) {
 3     entryies.forEach(entry => {
 4       if(entry.isIntersecting) {
 5         observer.unobserve(entry.target);
 6         entry.target.src = entry.target.dataset.src;
 7       }
 8     });
 9   }
10 
11   const OPTIONS = {
12     root: null,
13     threshold: [0.0],
14     rootMargin: "0px 0px 0px 0px",
15   };
16   
17   let lazyImages = [...document.querySelectorAll(".lazy-image")];
18 
19   lazyImages.forEach(image => {
20     image.dataset.src = "https://picsum.photos/seed/" + Math.floor(Math.random() * 10000) + "/200.webp";
21   });
22 
23   let observer = new IntersectionObserver(handler, OPTIONS);
24 
25   lazyImages.forEach(image => observer.observe(image));
26 };

4. 资源无限生成(IntersectionObserver)

 1 <!doctype html>
 2 <html lang="en">
 3   <head>
 4     <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
 5     <meta name="viewport" content="width=device-width, initial-scale=1" />
 6     <script type="text/javascript" src="/index.js"></script>
 7     <style type="text/css">
 8       .box { width: 80%; margin: auto; }
 9       .image { display: inline-block; width: 15%; height: 25vh; }
10     </style>
11   </head>
12   <body>
13     <div class="box"></div>
14     <footer class="footer"></footer>
15   </body>
16 </html>
 1 window.onload = function() {
 2   const ONE_PAGE = 4 * 6;
 3 
 4   function loadMore(size) {
 5     let box = document.querySelector(".box");
 6     
 7     while(size--) {
 8       let txt = document.createTextNode(" ");
 9       let img = document.createElement("img");
10 
11       img.className = "image";
12       img.src = "https://picsum.photos/seed/" + Math.floor(Math.random() * 10000) + "/200.webp";
13 
14       box.appendChild(img);
15       box.appendChild(txt);
16     }
17   }
18   
19   loadMore(ONE_PAGE);
20 
21   new IntersectionObserver((entries) => {
22     if(entries[0].isIntersecting) loadMore(ONE_PAGE);
23   }).observe(document.querySelector(".footer"));
24 };

5. 扩展知识

1) Lazy load images with zero Javascript

2) Intersection Observer API

3) IntersectionObserver API使用教程

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!