蔡繁荣
蔡繁荣
  • 发布:2015-07-01 14:41
  • 更新:2022-08-24 17:15
  • 阅读:26715

分享基于plus.downloader的图片懒加载功能,支持本地缓存v1.1.0

分类:MUI

今天试用了下hello mui上的图片懒加载功能,发现有些地方还无法满足我的需求,ajax动态加载的时候无法实现懒加载。

然后又看了下36kr的示例,因为代码关系实在太多了,耦合度比较高,遂自己动手写了一个轻量级的懒加载功能模块,而且支持图片缓存到本地哦~~~

欢迎各位拍砖,交流碰撞思想!

升级日志

v1.1.0 build 20160107
1、已增加 @LFZ 的代码,不用重复下载两次服务器端的图片
2、新增图片加载淡入特效
3、新增图片加载完成后回调
4、修改data-src为data-lazyload

功能特性

~原生实现,不依赖任何前端框架
~ajax动态加载支持图片懒加载
~支持图片缓存到本地
~轻量模块化

如何使用

1、引入md5.min.js,因为依赖js版md5函数,用于将图片url转换为32位md5

<script s r c="md5.min.js"></script>

2、在头部js包含下面的lazyload方法函数,否则可能报错函数未定义

3、HTML代码使用ajax动态生成如下img标签,src为默认图片,data-src填写图片网络地址,并且必须包含onload事件来触发懒加载功能。

<img s r c="placehold.jpg" data-lazyload="http://...jpg"  onload="lazyload(this)" />

注意:因为函数依赖plus.io和plus.downloader接口,所以在plus还没ready的时候img onload执行lazyload可能会报错,lazyload比plus先执行完毕。

当然,在真实环境中,不管是商品列表、订单列表等,我们的图片一般都是动态加载的,所以问题不大。
在代码的写法策略上需要使用动态加载方式,尽量不使用写死在html里面。

4、添加.img-lazyload 支持图片淡入样式

@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}  
@keyframes fadeIn{0%{opacity:0}100%{opacity:1}}  
.img-lazyload{-webkit-animation: fadeIn 350ms linear 0ms 1 normal both;animation: fadeIn 350ms linear 0ms 1 normal both;opacity:1;}

5、图片默认缓存到_downloads/image/目录下

活动图

函数源代码

/**  
 * 图片懒加载  
 * @param {Object}   obj       DOMElement  
 * @param {Function} callback  加载完成回调函数  
 *   
 * @author fanrong33  
 * @version 1.1.0 build 20160107  
 */  
function lazyload(obj, callback){  
    var debug = false; // 默认打印调试日志  
    if(obj.getAttribute('data-loaded')){  
       return;   
    }  

    var image_url = obj.getAttribute('data-lazyload');  
    debug && console.log(image_url);  

    // 1. 转换网络图片地址为本地缓存图片路径,判断该图片是否存在本地缓存  
    // http://...jpg -> md5  
    // 缓存目录 _downloads/image/(md5).jpg  
    var image_md5           = md5(image_url);  
    var local_image_url     = '_downloads/image/'+image_md5+'.jpg'; // 缓存本地图片url  
    var absolute_image_path = plus.io.convertLocalFileSystemURL(local_image_url); // 平台绝对路径  

    // new temp_img 用于判断图片文件是否存在  
    var temp_img = new Image();  
    temp_img.src = absolute_image_path;  
    temp_img.onload = function(){  
        debug && console.log('存在本地缓存图片文件'+local_image_url+',直接显示');  

        // 1.1 存在,则直接显示(本地已缓存,不需要淡入动画)  
        obj.setAttribute('src', absolute_image_path);  
        obj.setAttribute('data-loaded', true);  
        obj.classList.add('img-lazyload');  

        callback && callback();  
        return;  
    }  
    temp_img.onerror = function(){  
        debug && console.log('不存在本地缓存图片文件');  

        // 1.2 下载图片缓存到本地  
        debug && console.log('开始下载图片'+image_url+' 缓存到本地: '+local_image_url);  
        function download_img(){  
            var download_task = plus.downloader.createDownload(image_url, {  
                filename: local_image_url // filename:下载任务在本地保存的文件路径  
            }, function(download, status) {  
                if(status != 200){  
                    // 下载失败,删除本地临时文件  
                    debug && console.log('下载失败,status'+status);  
                    if(local_image_url != null){  
                        plus.io.resolveLocalFileSystemURL(local_image_url, function(entry) {  
                            entry.remove(function(entry) {  
                                debug && console.log("临时文件删除成功" + local_image_url);  
                                // 重新下载图片  
                                download_img();  
                            }, function(e) {  
                                debug && console.log("临时文件删除失败" + local_image_url);  
                            });  
                        });  
                    }  
                }else{  
                    // 把下载成功的图片显示  
                    // 将本地URL路径转换成平台绝对路径  
                    obj.setAttribute('src', plus.io.convertLocalFileSystemURL(local_image_url));  
                    obj.setAttribute('data-loaded', true);  
                    obj.classList.add('img-lazyload');  

                    callback && callback();  
                }  
            });  
            download_task.start();  
        }  
        download_img();  
    }  

}
52 关注 分享
BoredApe 粥冰 羊羽亻子 Loadingz hilongjw wenju Nation LFZ 豆花饭 豆腐果lyl DCloud_UNI_CHB 后海 G_jia DCDDD 老贪嗔痴 lauhome ztingjian 球风无痕 王帆 信不过你开车 建东 EM b***@msn.com 5675557 l***@boholo.com chenyumu 地球人 小白免 4***@qq.com 老火 成都H5 牛顿爱吃苹果 陨落星辰 jwenlee shwanYu 1***@qq.com WinXP qiuxiaojun ROBOT10086 3***@qq.com 5***@qq.com 1***@qq.com [已删除] android_yang 全栈开发南京 杨婆婆管家家 n***@qq.com 7***@qq.com 邱水仙 1***@qq.com

要回复文章请先登录注册

user_name

user_name

回复 3***@qq.com :
为什么我传的这个this是null?
2022-08-24 17:14
即时通讯开发

即时通讯开发

我看代码里还有newimage 这个是在app端可以用的吗
2022-08-15 16:30
j***@gmail.com

j***@gmail.com

mark
2021-01-11 09:44
俊海

俊海

回复 俊海 :
已经解决了,因为ios14,img的onload会一直调用,要obj.onload=null处理
2020-11-25 16:03
俊海

俊海

您好,iOS14,70+图片数量,应用就卡的不能滑动了,不用缓存的话就可以,请问是什么原因呢?
2020-11-25 14:27
阿蔥

阿蔥

MK 记录一下
2020-01-24 13:26
2***@qq.com

2***@qq.com

回复 1***@qq.com :
app端不能用啊 ~ ~vue-lazyload
2019-08-27 15:36
3***@qq.com

3***@qq.com

好东西
2019-08-18 16:26
苛学加

苛学加

mark
2019-04-19 10:30
n***@qq.com

n***@qq.com

mark
2018-08-14 03:03