图片懒加载

为何要懒加载

有时候页面中会有不少图片,一个图片就意味着一个http请求,一个js文件几十k,一张图片就多是几M,过多的图片须要很长的加载时间,等图片加载完成,早就人走茶凉,图片懒加载对提高用户体验有着显著的效果浏览器

懒加载的原理

当图片不在可视区域内时,统一设置imgsrc为指定图片src='default.png',添加data-src(自定义属性)属性指向真实图片url
bash

<img src='default.png' data-src='httt://www.xxx.com/images/001.jpg'>
复制代码

监听scroll事件,当图片出如今可视区时,提取data-src的值并赋给src,加载真正图片app

实现代码

let img = document.getElementsByTagName('img')
        //设置每次遍历的起始图片,防止重复加载
        let n = 0
        //加载可视区域图片
        lazyLoad()
        window.onscroll = lazyLoad
        function lazyLoad() {
            let seeHeight = document.documentElement.clientHeight
            let scrollHeight = document.body.scrollHeight
            for (let i = n; i<img.length;i++) {
               if(img[i].src === 'default.png'){
                   if(img[i].offsetHeight < seeHeight + scrollHeight){
                       img[i].setAttribute('src',img[i].getAttribute('data-src'))
                       n++
                   }
               }
            }
        }
复制代码

还没完,lazyLodescorll事件绑定会致使高频触发,这只会增长浏览器的压力,违背了咱们的初衷,因此咱们须要限制事件频率,改良代码以下函数

let img = document.getElementsByTagName('img')
        //设置每次遍历的起始图片,防止重复加载
        let n = 0
        //加载可视区域图片
        lazyLoad()
        function lazyLoad() {
            let seeHeight = document.documentElement.clientHeight
            let scrollHeight = document.body.scrollHeight
            for (let i = n; i<img.length;i++) {
               if(img[i].src === 'default.png'){
                   if(img[i].offsetHeight < seeHeight + scrollHeight){
                       img[i].setAttribute('src',img[i].getAttribute('data-src'))
                       n++
                   }
               }
            }
        }
        //防抖
        function debounce(fn,wait) {
            let timeout = null
            return function(){ 
                let context = this
                let args = arguments
                clearTimeout(timeout)
                timeout = setTimeout( function(){
                  fn.apply(context,args)
                },wait)                    
            }
        }
        window.addEventListener('scroll',debounce(lazyLoad,800),true)
复制代码

debounce函数限制了lazyLoad的触发频率,800ms等待时间内scroll时间再次触发则重置时间,术语叫防抖。这就完了?nonono!假设咱们把wait设的大点,2s,若是用户一直滑动滚动条,时间不断被重置,形成的效果是lazyLoad一直不被执行,图片加载不出来,这是不能接受的,因此咱们须要设置一个时间,超过该时间lazyLoad必须执行一次,术语叫节流,代码以下ui

let img = document.getElementsByTagName('img')
        //设置每次遍历的起始图片,防止重复加载
        let n = 0
        //加载可视区域图片
        lazyLoad()
        function lazyLoad() {
            let seeHeight = document.documentElement.clientHeight
            let scrollHeight = document.body.scrollHeight
            for (let i = n; i<img.length;i++) {
               if(img[i].src === 'default.png'){
                   if(img[i].offsetHeight < seeHeight + scrollHeight){
                       img[i].setAttribute('src',img[i].getAttribute('data-src'))
                       n++
                   }
               }
            }
        }
        //节流
        function throttle(fn,wait,mustTime){
            let timeout = null
            let startTime = new Date()
            let curTime
            return function(){
                let context = this
                let args = arguments
                curTime = new Date()
                if( (curTime - startTime) >= mustTime){
                     startTime = curTime
                    fn.apply(context,args) 
                    clearTimeout(timeout)    
                }else{
                    clearTimeout(timeout)
                    timeout = setTimeout( function(){
                        fn.apply(context,args)
                        startTime = new Date()
                    },wait)
                }
            }
        }
        window.addEventListener('scroll',throttle( lazyLoad,2000,3000))
复制代码
相关文章
相关标签/搜索