js原生实现图片懒加载

2019-11-06 来源: 前端菜鸡儿 发布在  https://www.cnblogs.com/yushihao/p/11806633.html

使用原声js来实现图片预加载,或图片懒加载,小伙伴们可以根据项目需要来结合vue或者是react来进行修改。

一、什么是图片懒加载或什么是图片预加载

当访问一个页面的时候,先把img元素或是其他元素的背景图片路径缓存下来(这样就只需请求一次),当图片出现在浏览器的可视区域内时,才设置图片真正的路径,让图片显示出来。这就是图片懒加载。
其实简单来说就是:

1、就是创建一个自定义属性data-src存放真正需要显示的图片路径。
2、当页面滚动直至此图片出现在可视区域时,用js取到该图片的data-src的值赋给src。
ps:自定义属性可以取任何名字

二, 整体思路及实现过程

1.在img标签上定义data-src属性。
 <div class="wrapper">
     <ul id="ul">
       <li><img class="img"
           data-src="https://img.alicdn.com/imgextra/i3/1886487777/O1CN0127JufVir7DmPYpu_!!1886487777-0-daren.jpg_360x360xzq90.jpg">
       </li>
       <li><img class="img"
           data-src="https://img.alicdn.com/imgextra/i2/2585780740/O1CN011HKxYBjGug0VPwX_!!2585780740-0-beehive-scenes.jpg_360x360xzq90.jpg"
           alt=""></li>
       <li><img class="img"
           data-src="https://img.alicdn.com/tfscom/i4/2310153969/TB1.C3aiH1YBuNjSszeXXablFXa_!!0-item_pic.jpg_360x360xzq90.jpg"
           alt=""></li>
       <li><img class="img"
           data-src="https://img.alicdn.com/imgextra/i1/3158956210/TB25uKZssyYBuNkSnfoXXcWgVXa_!!3158956210-0-beehive-scenes.jpg_360x360xzq90.jpg"
           alt=""></li>
       <li><img class="img"
           data-src="https://img.alicdn.com/tfscom/TB2CXy1XerAQeBjSZFrXXbSvFXa_!!0-dgshop.jpg_360x360xzq90.jpg" alt="">
       </li>
       <li><img class="img"
           data-src="https://img.alicdn.com/bao/uploaded/TB2EUU6w8mWBuNkSndVXXcsApXa_!!2306497993.jpg_360x360xzq90.jpg"
           alt=""></li>
       <li><img class="img"
           data-src="https://img.alicdn.com/bao/uploaded/TB2PfjytbSYBuNjSspiXXXNzpXa_!!395676295-0-beehive-scenes.jpg_360x360xzq90.jpg"
           alt=""></li>
       <li><img class="img"
           data-src="https://img.alicdn.com/bao/uploaded/TB2Mb.9X4PI8KJjSspoXXX6MFXa_!!2948425669-0-beehive-scenes.jpg_360x360xzq90.jpg"
           alt=""></li>
       <li><img class="img"
           data-src="https://img.alicdn.com/bao/uploaded/TB2MGqTbLTJXuFjSspeXXapipXa_!!867439872.jpg_360x360xzq90.jpg"
           alt=""></li>
       <li><img class="img" data-src="https://aecpm.alicdn.com/simba/img/TB1j4LLKpXXXXcbaXXXSutbFXXX.jpg" alt=""></li>
       <li><img class="img" data-src="https://aecpm.alicdn.com/simba/img/TB13xKuLVXXXXcHapXXSutbFXXX.jpg" alt=""></li>
       <li><img class="img" data-src="https://aecpm.alicdn.com/simba/img/TB1X6uHLVXXXXcCXVXXSutbFXXX.jpg" alt=""></li>
       <li><img class="img"
           data-src="https://img.alicdn.com/imgextra/i2/57/O1CN01TfSEXR1CI93oiwRz7_!!57-0-lubanu.jpg_350x350q90.jpg"
           alt=""></li>
       <li><img class="img"
           data-src="https://img.alicdn.com/imgextra/i3/48/O1CN01zKg3pd1CE1UnQ2TD3_!!48-0-lubanu.jpg_350x350q90.jpg"
           alt=""></li>
     </ul>
   </div>
 2.获取到页面中所有的img标签
let img = document.getElementsByClassName('img')//获取到页面中class名为img的所有标签

这里呢我给每个img标签定义了同一个class类名。

3.定义一个函数用来获取每个img距离底部的距离
  function getOffsetByBody(el) {
       //获取标签元素距离底部的距离
       let offsetTop = 0
       while (el && el.tagName !== 'BODY') {
         offsetTop += el.offsetTop
         el = el.offsetParent
       }
       return offsetTop
     }

这里呢我是用的是while循环,把获取到的数据return出去。

4.获取到浏览器可用部分高度,也就是可视区域的高度
let availHeight = window.screen.availHeight // 浏览器可用部分高度

  5.获取滚动隐藏的高度

let scrollTop = document.body.scrollTop || document.documentElement.scrollTop // 滚动隐藏的高度

6.通过计算判断img是否进入可视区域,通过getAttribute 获取到data-src里面图片的真实路径,通过setAttribute将真实路径赋值给src,最后通过removeAttribute删除data-src属性。

 function lazyload() {
       let img = document.getElementsByClassName('img')//获取到页面中class名为img的所有标签
       let availHeight = window.screen.availHeight // 浏览器可用部分高度
       let scrollTop = document.body.scrollTop || document.documentElement.scrollTop // 滚动隐藏的高度
       for (let i = 0; i < img.length; i++) {
         let offsetTop = getOffsetByBody(img[i])//获取标签元素距离底部的距离
    img[i].setAttribute('src', src)  img[i].removeAttribute('data-src')     }

三,使用到的方法

1.getAttribute

getAttribute() 方法返回指定属性名的属性值

2.setAttribute

setAttribute() 方法添加指定的属性,并为其赋指定的值。

3.removeAttribute

removeAttribute() 方法删除指定的属性。

四,注意

在页面中在

在页面加载的时候以及滚动条滚动的时候一定要去触发定义的两个方法。

五,完整代码

 <!DOCTYPE html>
 <html>

 <head>
   <meta charset="utf-8" />
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <title>图片的懒加载</title>
   <meta name="viewport" content="width=device-width, initial-scale=1">
   <style>
     #ul {
       width: 200px;
       outline: 1px dashed #f00;
       list-style: none;
     }

     #ul>li {
       width: 180px;
       height: 100px;
       margin-bottom: 50px;
       outline: 1px dashed #0f0;
     }

     .img {
       width: 100%;
       height: 100%;
     }
   </style>
 </head>

 <body>
   <div class="wrapper">
     <ul id="ul">
       <li><img class="img"
           data-src="https://img.alicdn.com/imgextra/i3/1886487777/O1CN0127JufVir7DmPYpu_!!1886487777-0-daren.jpg_360x360xzq90.jpg">
       </li>
       <li><img class="img"
           data-src="https://img.alicdn.com/imgextra/i2/2585780740/O1CN011HKxYBjGug0VPwX_!!2585780740-0-beehive-scenes.jpg_360x360xzq90.jpg"
           alt=""></li>
       <li><img class="img"
           data-src="https://img.alicdn.com/tfscom/i4/2310153969/TB1.C3aiH1YBuNjSszeXXablFXa_!!0-item_pic.jpg_360x360xzq90.jpg"
           alt=""></li>
       <li><img class="img"
           data-src="https://img.alicdn.com/imgextra/i1/3158956210/TB25uKZssyYBuNkSnfoXXcWgVXa_!!3158956210-0-beehive-scenes.jpg_360x360xzq90.jpg"
           alt=""></li>
       <li><img class="img"
           data-src="https://img.alicdn.com/tfscom/TB2CXy1XerAQeBjSZFrXXbSvFXa_!!0-dgshop.jpg_360x360xzq90.jpg" alt="">
       </li>
       <li><img class="img"
           data-src="https://img.alicdn.com/bao/uploaded/TB2EUU6w8mWBuNkSndVXXcsApXa_!!2306497993.jpg_360x360xzq90.jpg"
           alt=""></li>
       <li><img class="img"
           data-src="https://img.alicdn.com/bao/uploaded/TB2PfjytbSYBuNjSspiXXXNzpXa_!!395676295-0-beehive-scenes.jpg_360x360xzq90.jpg"
           alt=""></li>
       <li><img class="img"
           data-src="https://img.alicdn.com/bao/uploaded/TB2Mb.9X4PI8KJjSspoXXX6MFXa_!!2948425669-0-beehive-scenes.jpg_360x360xzq90.jpg"
           alt=""></li>
       <li><img class="img"
           data-src="https://img.alicdn.com/bao/uploaded/TB2MGqTbLTJXuFjSspeXXapipXa_!!867439872.jpg_360x360xzq90.jpg"
           alt=""></li>
       <li><img class="img" data-src="https://aecpm.alicdn.com/simba/img/TB1j4LLKpXXXXcbaXXXSutbFXXX.jpg" alt=""></li>
       <li><img class="img" data-src="https://aecpm.alicdn.com/simba/img/TB13xKuLVXXXXcHapXXSutbFXXX.jpg" alt=""></li>
       <li><img class="img" data-src="https://aecpm.alicdn.com/simba/img/TB1X6uHLVXXXXcCXVXXSutbFXXX.jpg" alt=""></li>
       <li><img class="img"
           data-src="https://img.alicdn.com/imgextra/i2/57/O1CN01TfSEXR1CI93oiwRz7_!!57-0-lubanu.jpg_350x350q90.jpg"
           alt=""></li>
       <li><img class="img"
           data-src="https://img.alicdn.com/imgextra/i3/48/O1CN01zKg3pd1CE1UnQ2TD3_!!48-0-lubanu.jpg_350x350q90.jpg"
           alt=""></li>
     </ul>
   </div>
   <script>
     function getOffsetByBody(el) {
       //获取标签元素距离底部的距离
       let offsetTop = 0
       while (el && el.tagName !== 'BODY') {
         offsetTop += el.offsetTop
         el = el.offsetParent
       }
       return offsetTop
     }
     function lazyload() {
       let img = document.getElementsByClassName('img')//获取到页面中class名为img的所有标签
       let availHeight = window.screen.availHeight // 浏览器可用部分高度
       let scrollTop = document.body.scrollTop || document.documentElement.scrollTop // 滚动隐藏的高度
       for (let i = 0; i < img.length; i++) {
         let offsetTop = getOffsetByBody(img[i])
         console.log(offsetTop)
         if (offsetTop - scrollTop < availHeight) {  // 判断条件,元素是否出现在用户视野内
           let src = img[i].getAttribute('data-src') // 获取真实地址
           if (src) { // 如果获取到了 data-src 说明图片是第一次出现在视野内
             img[i].setAttribute('src', src) // 将真实地址赋给图片的src属性
             img[i].removeAttribute('data-src') // 移除data-src
           }
         }
       }
     }
     window.onload = lazyload // 页面加载执行 lazyload
     window.onscroll = lazyload // 监听滚动事件,滚动时执行lazyload

   </script>
 </body>

 </html>

好啦,今天就到这里了,下次给大家分享一下,原声js图片懒加载结合瀑布流,实现淘宝商品无序排列的方法,有疑问的可以留言哦~