[JavaScript] 原生js实现图片懒加载(并且使用节流来限制频率)

效果

请添加图片描述

可以看到我们的图片不是一次性加载的,而是当滚动条滚动的时候不断的加载新的图片。这就是懒加载。懒加载的好处有:

  1. 可以缓解服务器端的压力
  2. 可以节约用户的流量,有时候用户并不是要看所有的图片,只是看前面几张而已。

使用原生js实现图片懒加载

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
      html, body{
          padding: 0;
          margin: 0;
          width: 100%;
          height: 100%;
      }
      #container {
        width: 100%;
        height: 100%;
        background-color: green;
        display: flex;
        flex-direction: column;
      }
      #header {
          width: 100%;
          height: 50px;
          background-color: pink;
          text-align: center;
          flex: 0 0 auto;
      }
      #content {
        width: 100%;
        background-color: gray;
        flex-grow: 1;
        overflow: auto;
      }
      #imgContainer {
          width: 80%;
          margin-left: auto;
          margin-right: auto;
          padding: 30px;
          background-color: hotpink;
      }
      img {
          margin-bottom: 20px;
          width: 100%;
      }
      #footer {
          height: 50px;
          background-color: pink;
          text-align: center;
          flex: 0 0 auto;
      }
    </style>
</head>
<body>
<!-- 
    整体布局:
    整体采用flex进行布局,上中下
    中间的区域用于展示图片
    content的高度是固定的
    imgContainer的高度由其内部的图片撑起来
    设置content的overflow为auto,所以当imgContainer过高时content会产生滚动条
    主要思路就是:我们需要做的是判断页面还有多少在底部,如果快要滑到页面底部了,就去加载新的图片
 -->
<div id="container">
    <div id="header">
        <h3>这是一个懒加载结合节流的例子</h3>
    </div>
    <div id="content">
        <div id="imgContainer">
            <!-- 这里放置动态添加的图片 -->
        </div>
    </div>
    <div id="footer">
        <h3>这是页面底部</h3>
    </div>
</div>

</body>
<script>
    window.onload = function () {
        // 手写一个节流函数(也可以通过引入一些库函数来实现)
        // 节流的作用是避免鼠标滑动时回调函数太过频繁的触发
        // 节流可提高浏览器性能
        function throttle(fn, delay){
            let timer = null;
            return function(){
                let context = this;
                let args = arguments;
                if(!timer){
                    timer = setTimeout(()=>{
                        timer = null; // 重要
                        fn.apply(context,args)
                    },delay)
                }
            }
        }
        // 定义要进行懒加载的图片的路径(一般从后台返回的)
        const arr = [
            './images/1.jpg',
            './images/2.jpg',
            './images/3.jpg',
            './images/4.jpg',
            './images/5.jpg',
            './images/6.jpg',
            './images/7.jpg',
            './images/8.jpg',
            './images/9.jpg',
            './images/10.jpg',
            './images/11.jpg',
            './images/12.jpg'
        ]
        // 为content元素绑定滚动事件(这里使用了节流)
        // 限制check_if_load_more_img函数300ms内只能被调用一次
        document.getElementById('content').onscroll = throttle(check_if_load_more_img, 300)
        // 首先就加载一次图片
        loadImg()
        // 定义一个函数用于判断当前滚动条是否快要到底部了 如果快到底部了 就加载图片
        function check_if_load_more_img() {
            const scrollHeight = document.getElementById("imgContainer").scrollHeight
            const scrollTop = document.getElementById("content").scrollTop
            const height = document.getElementById("content").clientHeight
            console.log(scrollHeight, scrollTop, height)
            let BottomPixels = scrollHeight-(scrollTop+height)

            if (BottomPixels < 200) { // 还差200px就到底部了,加载图片
                loadImg()
            }
        }
        // 定义一个函数来加载图片
        function loadImg() {
            let fragment = document.createDocumentFragment();
            let temp = arr.splice(0, 3) // 从arr中取出前3张图片进行加载(splice会影响原数组)
            temp.forEach(function(item) {
                let imgNode = document.createElement('img')
                imgNode.src = item
                fragment.appendChild(imgNode)
            })
            let imgContainer = document.getElementById("imgContainer")
            imgContainer.appendChild(fragment)
        }
    }
</script>
</html>

计算原理

在这里插入图片描述

关键属性

Element.scrollTop: 一个元素的 scrollTop 值是这个元素的内容顶部(卷起来的)到它的视口可见内容(的顶部)的距离的度量。当一个元素的内容没有产生垂直方向的滚动条,那么它的 scrollTop 值为0。
Element.scrollHeight: 是一个元素内容高度的度量,包括由于溢出导致的视图中不可见内容。
Element.clientHeight: 它是元素内部的高度(单位像素),包含内边距,但不包括水平滚动条、边框和外边距。

参考

《Element.clientHeight》

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值