图片懒加载

栏目: JavaScript · 发布时间: 5年前

内容简介:图片懒加载在一些图片密集型的网站中运用比较多,通过图片懒加载可以让一些不可视的图片不去加载,避免一次性加载过多的图片导致请求阻塞(浏览器一般对同一域名下的并发请求的连接数有限制),这样就可以提高网站的加载速度,提高用户体验。

前言

图片懒加载在一些图片密集型的网站中运用比较多,通过图片懒加载可以让一些不可视的图片不去加载,避免一次性加载过多的图片导致请求阻塞(浏览器一般对同一域名下的并发请求的连接数有限制),这样就可以提高网站的加载速度,提高用户体验。

效果预览

图片懒加载

如何做

第一步 : 首先我们需要让我们html中需要懒加载的img标签的 src 设置缩略图或者不设置 src ,然后自定义一个属性,值为真正的图片或者原图的地址(比如下面的data-src),并且定义一个类名,表示该图片是需要懒加载的(比如下面例子的lazy-image),这有两个作用: 

1、为以后获取需要懒加载图片的img元素

2、可以给这个类名设置背景图片,作为图片未加载前的过度图片,比如显示为loading的图片。

<img data-src="https://tb1.bdstatic.com/tb/cms/liveshow/ent_slid2.jpg" class="lazy-image"/> 
// css部分 
.lazy-image { 
    background: url('../img/loading.gif') no-repeat center; 
} 
复制代码

第二步 :页面加载完后,我们需要获取所有需要懒加载的图片的元素集合,判断是否在可视区域,如果是在可视区域的话,设置元素的src属性值为真正图片的地址。

inViewShow() {     
    let imageElements = Array.prototype.slice.call(document.querySelectorAll('.lazy-image'))    
    let len = imageElements.length     
    for(let i = 0; i < len; i++) {         
        let imageElement = imageElements[i]        
        const rect = imageElement.getBoundingClientRect() // 出现在视野的时候加载图片         
        if(rect.top < document.documentElement.clientHeight) {             
            imageElement.src = imageElement.dataset.src // 移除掉已经显示的             
            imageElements.splice(i, 1)             
            len--             
            i--         
        }     
    } 
}复制代码

这里判断是否出现在可视区域内,是通过获取元素的 getBoundingClientRect 属性的 top 值和页面的 clientHeight 进行对比,如果 top 值小于 clientHeight ,则说明元素出现在可视区域了。 BoundingClientRect 是获取某个元素相对于视窗的位置集合,见下图,注意 bottomright 和我们平时的 rightbottom 不一样。 

图片懒加载

第三步 :当用户滚动窗口的时候,遍历所有需要懒加载的元素,通过每个元素的 BoundingClientRect 属性来判断元素是否出现在可视区域内,判断方法同第二步一样。 

document.addEventListener('scroll', inViewShow)
复制代码

这里我们可以优化下,可以通过函数节流优化滚动事件的处理函数。

完整代码

class LazyImage {    
    constructor(selector) {      
    // 懒记载图片列表,将伪数组转为数组,以便可以使用数组的api      
        this.imageElements = Array.prototype.slice.call(document.querySelectorAll(selector))
        this.init()    
    }      
    inViewShow() {      
        let len = this.imageElements.length      
        for(let i = 0; i < len; i++) {        
            let imageElement = this.imageElements[i]        
            const rect = imageElement.getBoundingClientRect()        
            // 出现在视野的时候加载图片        
            if(rect.top < document.documentElement.clientHeight) {          
                imageElement.src = imageElement.dataset.src          
                // 移除掉已经显示的          
                this.imageElements.splice(i, 1)          
                len--          
                i--          
                if(this.imageElements.length === 0) {            
                   // 如果全部都加载完 则去掉滚动事件监听            
                    document.removeEventListener('scroll', this._throttleFn)         
                 }        
            }      
        }    
    }      
    throttle(fn, delay = 15, mustRun = 30) {      
        let t_start = null     
        let timer = null      
        let context = this      
        return function() {        
            let t_current = +(new Date())        
            let args = Array.prototype.slice.call(arguments)        
            clearTimeout(timer)        
            if(!t_start) {          
                t_start = t_current        
            }        
            if(t_current - t_start > mustRun) {          
                fn.apply(context, args)          
                t_start = t_current        
            } else {          
                timer = setTimeout(() => {            
                    fn.apply(context, args)          
                }, delay)        
            }      
        }    
    }      
    init() {      
        this.inViewShow()      
        this._throttleFn = this.throttle(this.inViewShow)      
        document.addEventListener('scroll', this._throttleFn)    
    }  
}
// 调用例子
new LazyImage('.lazy-image')

复制代码

git地址: github.com/VikiLee/Laz…


以上所述就是小编给大家介绍的《图片懒加载》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Think Python

Think Python

Allen B. Downey / O'Reilly Media / 2012-8-23 / GBP 29.99

Think Python is an introduction to Python programming for students with no programming experience. It starts with the most basic concepts of programming, and is carefully designed to define all terms ......一起来看看 《Think Python》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试