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

分享基于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 1***@qq.com android_yang 全栈开发南京 杨婆婆管家家 n***@qq.com 7***@qq.com 邱水仙 1***@qq.com

要回复文章请先登录注册

成都H5

成都H5

不兼容ios吗 大神们
2016-11-21 15:32
qiuxiaojun

qiuxiaojun

可以用,大图片会卡,建议再优化下
2016-11-14 16:42
mrwhisper

mrwhisper

回复 蔡繁荣 :
var absolute_image_path = plus.io.convertLocalFileSystemURL(local_image_url); // 平台绝对路径
这里还是抛异常 说的是plus.io未初始化完成。请指教
2016-10-27 11:23
1***@qq.com

1***@qq.com

并没有完全做到懒加载吧,懒加载还需要控制页面之外的图片滞后显示
2016-10-13 15:15
Thyme释念帅

Thyme释念帅

回复 Loadingz :
您好,请问下这一块儿您怎么解决的啊
2016-09-29 15:24
3***@qq.com

3***@qq.com

关于我对缓存图片的看法:
上面的方法,一个图片会两次下载,体验并不好
我个人认为,完全可以在页面 onload 以后,获取图片元素列表,然后js直接获取每个图片的base64字符串,
保存于 localStorage 或 plus.storage 或 plus.io 中,这样 只需一次。

<img id="img1" src='waiting.gif' data-src='images/cbd.jpg' onload="加载并缓存(this)" />

在函数中,读取 data-src, 发现有缓存 就载入 base64, 没有就 赋值给 src , 这样简单。
这样的好处是,即使不在 5+ 的基座中,比如微信浏览器中,也可以利用 localStorage 数M的容量来缓存加速, 实现首页极速显示

我的联系方式 qq 30234923, 欢迎交流
2016-09-23 17:19
旋风小皮皮

旋风小皮皮

大赞 非常好用,配合vue实现图片列表懒加载
2016-08-19 13:56
好冷

好冷

mark
2016-07-29 22:43
dongs

dongs

mark
2016-07-29 15:13
成都H5

成都H5

Uncaught TypeError: Object [object DOMWindow] has no method 'getAttribute' 我这报这个错误 咋回事呢 急急 qq 864173267
2016-06-28 18:06