实现图片的异步加载

图片异步加载功能是现在web中非常常见的一个针对web做优化的方法。尤其是在移动端,面对大量的图片列表的时候,如果没有做相应的优化,会直接导致页面滑动和加载的卡顿,而且用户会莫名的发现当前应用占用的流量会很大,因为他可能都没有浏览到很多图片,而程序就自动加载了所以的图片,对于一个流量吃紧的人来讲,这个也是很讨厌的。所以实现按浏览需求加载时十分有必要的。

其实实现图片异步加载的核心思路十分简单,就是通过判断当图片元素是否出现在视窗范围内后,则去加载图片资源,否则不加载。所以我们需要首先解决判断img元素是否处于视图范围内的这个核心问题。让我们看看下面的图:

通过抓取img元素,js提供了相应的方法让我们可以获取到img元素距离视图top,和left的距离,viewport的高度和宽度等数据。然后通过监听窗口滚动事件,当页面滚动的时候,我们就去动态检测img元素的top和left值,与视窗的高度和宽度作比较,从而判断当前的img是否处于视窗范围。计算如下:

处于垂直范围: 图片距离视窗顶部距离 > 0 && 图片距离视窗顶部距离 <= 视窗高度 
处于水平范围: 图片距离视窗左边距离 > 0 && 图片距离视窗左边距离 <= 视窗宽度

解决了这个判断图片在可视范围内的核心问题后,那么其他的问题都是否简单了。我们看下详细代码:

获取视窗的高度和宽度:

var _viewPortHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0),
    _viewPortWidth = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);

是否处于垂直范围

function isOnVerticalViewPort(ele) {
    var rect = ele.getBoundingClientRect(); // 获取距离视窗的位置信息
    return rect.top > 0 && rect.top <= _viewPortHeight;
};

是否处于水平范围

function isOnHorizontalViewPort(ele) {
    var rect = ele.getBoundingClientRect();
    return rect.left > 0 && rect.left <= _viewPortWidth;
};

有了这核心代码,我们只需要在滚动事件触发后,去动态的判断img元素了, 判断的示例代码如下:

function load(images) {
    for (var i = 0; i < images.length; i++) {
        var img = images[i];
        if (isOnVerticalViewPort(img) && isOnHorizontalViewPort(img)) {
            var url = img.getAttribute(‘lz-src‘); // 获取图片资源的地址
            img.setAttribute("src", url);
            img.isload = true; // 加载过后的图片设置加载标记,以免重复加载
        }
    }
}

在html页面中的img元素的引用:

 <img lz-src="http://s.cn.bing.net/az/hprichbg/rb/SkunkKit_ZH-CN10809503929_1920x1080.jpg"></img>

通过给img元素添加lz-src标记,告诉异步脚本,这个元素需要异步加载图片。

监听滚动事件

    var images = document.querySelectorAll(‘img[‘ + lz-src + ‘]‘); // 按标记获取图片元素
    window.addEventListener("scroll", function(e) {
        load(images);
    }, false);

总结

以上就是图片异步加载的主要代码了。当然里面可以进行跟多的性能优化,例如我这里每次都需要重新遍历图片列表,只是通过单独的加载标记来确认图片是否加载过,我们当然可以用不同的数组列表分别装载加载过和未加载的图片元素,从而降低遍历次数等等。另外也可以给图片添加过度的loading动画等等,让这个异步加载插件更完善。我这里有个较为完整的异步加载的代码,有兴趣的朋友可以查看:https://github.com/wewoor/sloth

原文地址:http://imziv.com/blog/article/read.htm?id=75

时间: 2024-08-22 23:28:37

实现图片的异步加载的相关文章

Android开发之图片处理专题(三):利用ThreadPoolExcutor线程池实现多图片的异步加载

在上一篇专题Android开发之图片处理专题(二):利用AsyncTask和回调接口实现图片的异步加载和压缩中我们实现了listView的图片的大量加载.今天,我们换一种方式,采用线程池的方式来实现. 我们需要准备两个东西: 1.图片下载任务类 2.线程池. 1.图片下载任务类. 图片下载任务类,将需要显示的iamgeView,线程通讯消息管理者handler进行了封装.当图片下载无论成功还是失败,handler发送对应的消息,传入的iamgeView显示对应的图片.这里就不在应用软引用技术,采

Android开发之图片处理专题(二):利用AsyncTask和回调接口实现图片的异步加载和压缩

在上一篇专题Android开发之图片处理专题(一):利用软引用构建图片高速缓存中我们讲述了如何利用软引用技术构建高速缓存.那么想要用到图片,首先得有图片的来源.一般而言,一个应用的图片资源都是从服务器处获得的.今天,我们利用Android开发之网络请求通信专题(二):基于HttpClient的文件上传下载里面封装好的httpUtils来实现图片的下载,然后加载到本地配合软引用缓存使用,以一个listView为例子来说明. 一.准备工作 我们需要准备以下几个类(图片对象和软引用缓存类请参考上一篇专

图片高效加载(二) 图片的异步加载

图片的异步加载是利用AsynTask类对图像进行后台加载完成后再给ImageView,先转载一篇前人的较好的总结后面再添加一些自己的见解和贴上完整的实现demo. 前面的转自:https://my.oschina.net/rengwuxian/blog/183802 摘要: 有没有过这种体验:你在Android手机上打开了一个带有含图片的ListView的页面,用手猛地一划,就见那ListView嘎嘎地卡,仿佛每一个新的Item都是顶着阻力蹦出来的一样?看完这篇文章,你将学会怎样避免这种情况的发

WPF技术触屏上的应用系列(五): 图片列表异步加载、手指进行缩小、放大、拖动 、惯性滑入滑出等效果

原文:WPF技术触屏上的应用系列(五): 图片列表异步加载.手指进行缩小.放大.拖动 .惯性滑入滑出等效果 去年某客户单位要做个大屏触屏应用,要对档案资源进行展示之用.客户端是Window7操作系统,54寸大屏电脑电视一体机.要求有很炫的展示效果,要有一定的视觉冲击力,可触控操作.当然满足客户的要求也可以有其它途径.但鉴于咱是搞 .NET技术的,首先其冲想到的微软WPF方面,之前对WPF的了解与学习也只是停留在比较浅的层面,没有进一步深入学习与应用.所以在项目接来以后,也就赶鸭子上架了,经过努力

Android中图片的异步加载

转: 1.  为什么要异步加载图片 下载图片比较费时,先显示文字部分,让加载图片的过程在后台,以提升用户体验 2.  SoftReference的作用 栈内存—引用 堆内存—对象 Eg: Object obj = new Object(); Obj = null; 当垃圾收集器启动时,会回收对象: 当一个对象没有任何引用指向,就会被回收. SoftReference<Object>sr = new SoftReference<Object>(new Obnject()); 引用是软

Android下载图片 图片的异步加载 和缓存存取

一.创建异步任务 public class LoadBitmapAsyn extends AsyncTask<String,Void,Bitmap> { Context context; ImageView img; private HashMap<String,SoftReference<Bitmap>> imageCache=null; public LoadBitmapAsyn(ImageView img){ this.img=img; this.context=

BitmapImage处理网络图片,例如阿里云获取的图片。异步加载到需要显示的控件上。提升速度非常明显。

想直接把网络图片赋给控件,又要下载又要缓存,速度非常慢.不流畅. 需要进行处理,异步加载会显著提升速度.方法如下: public static BitmapImage ByteArrayToBitmapImage(byte[] byteArray) { BitmapImage bmp = null; try { bmp = new BitmapImage(); bmp.BeginInit(); bmp.StreamSource = new MemoryStream(byteArray); bmp

今日头条图片ajax异步加载爬取,并保存至mongodb,以及代码写法的改进

import requests,time,re,json,pymongofrom urllib.parse import urlencodefrom requests.exceptions import RequestExceptionfrom bs4 import BeautifulSoup as bs #连接mongodbclient = pymongo.MongoClient(host='localhost',port=27017)#指定数据库名称db = client.toutiao #

gridcontrol 图片列异步加载

在gridview中指定一列,将ColumnEdit设置成pictureEdit 在使用showDialog这里窗体后,需要frm.Dispose()将资源释放 1.将该列的UnboundType属性设置为bound(默认值)以外的数据类型 2.为该列设置一个窗体内全局唯一的FieldName,这个FieldName不能是窗体中绑定数据源的的列,否则不会触发绑定事件 3.处理CustomUnboundColumnData事件 gridView1.CustomUnboundColumnData +