lightbox类效果为了让图片居中显示而使用预加载,需要等待完全加载完毕才能显示,体验不佳(如filick相册的全屏效果)。javascript无法获取img文件头数据,真的是这样吗?本文通过一个巧妙的方法让javascript获取它。

这是大部分人使用预加载获取图片大小的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var imgLoad = function (url, callback) {
    var img = new Image();
    img.src = url;
    if (img.complete) {
        callback(img.width, img.height);
    } else {
        img.onload = function () {
            callback(img.width, img.height);
            img.onload = null;
        };
    };
};

可以看到上面必须等待图片加载完毕才能获取尺寸,其速度不敢恭维,我们需要改进。

web应用程序区别于桌面应用程序,响应速度才是最好的用户体验。如果想要速度与优雅兼得,那就必须提前获得图片尺寸,如何在图片没有加载完毕就能获取图片尺寸?

十多年的上网经验告诉我:浏览器在加载图片的时候你会看到图片会先占用一块地然后才慢慢加载完毕,并且不需要预设width与height属性,因为浏览器能够获取图片的头部数据。基于此,只需要使用javascript定时侦测图片的尺寸状态便可得知图片尺寸就绪的状态。

当然实际中会有一些兼容陷阱,如width与height检测各个浏览器的不一致,还有webkit new Image()建立的图片会受以处在加载进程中同url图片影响,经过反复测试后的最佳处理方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// 更新:
// 05.27: 1、保证回调执行顺序:error > ready > load;2、回调函数this指向img本身
// 04-02: 1、增加图片完全加载后的回调 2、提高性能
/**
 * 图片头数据加载就绪事件 - 更快获取图片尺寸
 * @version 2011.05.27
 * @author  TangBin
 * @see     http://www.planeart.cn/©p=1121
 * @param   {String}    图片路径
 * @param   {Function}  尺寸就绪
 * @param   {Function}  加载完毕 (可选)
 * @param   {Function}  加载错误 (可选)
 * @example imgReady('http://www.google.com.hk/intl/zh-CN/images/logo_cn.png', function () {
        alert('size ready: width=' + this.width + '; height=' + this.height);
    });
 */
var imgReady = (function () {
    var list = [], intervalId = null,
    // 用来执行队列
    tick = function () {
        var i = 0;
        for (; i < list.length; i++) {
            list[i].end © list.splice(i--, 1) : list[i]();
        };
        !list.length && stop();
    },
    // 停止所有定时器队列
    stop = function () {
        clearInterval(intervalId);
        intervalId = null;
    };
    return function (url, ready, load, error) {
        var onready, width, height, newWidth, newHeight,
            img = new Image();
         
        img.src = url;
        // 如果图片被缓存,则直接返回缓存数据
        if (img.complete) {
            ready.call(img);
            load && load.call(img);
            return;
        };
         
        width = img.width;
        height = img.height;
         
        // 加载错误后的事件
        img.onerror = function () {
            error && error.call(img);
            onready.end = true;
            img = img.onload = img.onerror = null;
        };
         
        // 图片尺寸就绪
        onready = function () {
            newWidth = img.width;
            newHeight = img.height;
            if (newWidth !== width || newHeight !== height ||
                // 如果图片已经在其他地方加载可使用面积检测
                newWidth * newHeight > 1024
            ) {
                ready.call(img);
                onready.end = true;
            };
        };
        onready();
         
        // 完全加载完毕的事件
        img.onload = function () {
            // onload在定时器时间差范围内可能比onready快
            // 这里进行检查并保证onready优先执行
            !onready.end && onready();
         
            load && load.call(img);
             
            // IE gif动画会循环执行onload,置空onload即可
            img = img.onload = img.onerror = null;
        };
        // 加入队列中定期执行
        if (!onready.end) {
            list.push(onready);
            // 无论何时只允许出现一个定时器,减少浏览器性能损耗
            if (intervalId === null) intervalId = setInterval(tick, 40);
        };
    };
})();

调用例子:

1
2
3
imgReady('http://www.google.com.hk/intl/zh-CN/images/logo_cn.png', function () {
    alert('size ready: width=' + this.width + '; height=' + this.height);
});

是不是很简单?这样的方式获取摄影级别照片尺寸的速度往往是onload方式的几十多倍,而对于web普通(800×600内)浏览级别的图片能达到秒杀效果。看了这个再回忆一下你见过的web相册,是否绝大部分都可以重构一下呢?好了,请观赏令人愉悦的 DEMO :http://www.planeart.cn/demo/imgReady/

转载于:https://www.cnblogs.com/vbluebirdv/archive/2012/11/18/2776337.html

再谈javascript图片预加载技术(转)相关推荐

  1. 再谈javascript图片预加载经典技术

    图片预加载技术的典型应用: 如lightbox方式展现照片,无疑需要提前获得大图的尺寸,这样才能居中定位,由于javascript无法获取img文件头数据,必须等待其加载完毕后才能获取真实的大小然后展 ...

  2. 转javascript图片预加载技术

    今天看一篇文章,再谈javascript图片预加载技术(http://www.planeart.cn/?p=1121) http://www.qiqiboy.com/2011/05/20/javasc ...

  3. 很山寨的网页游戏图片预加载技术

    很山寨的网页游戏图片预加载技术 以下一种简单易懂,方便易用的网页图片预加载技术.:=D. 这种预加载技术使用了javascript技术.静态页面技术.div隐藏技术.gif动态图片技术.bash脚本技 ...

  4. 3种Javascript图片预加载的方法详解

    3种Javascript图片预加载的方法详解 预加载图片是提高用户体验的一个很好方法.图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度. 这对图片画廊及图片占据很大比例 ...

  5. 一种网页游戏图片预加载方案

    一种网页游戏图片预加载方案 上个月我写了一篇关于网页游戏图片预加载技术的文章,叫<很山寨的网页游戏图片预加载技术>.这个方案用到项目上后,发现了一些问题,经过大家的努力,这些问题基本得到解 ...

  6. php预加载图片,图片预加载的一个简明例子

    图片预加载技术的典型应用:如lightbox方式展现照片,无疑需要提前获得大图的尺寸,这样才能居中定位,由于javascript无法获取img文件头数据,必须等待其加载完毕后才能获取真实的大小然后展示 ...

  7. imageReady 图片预加载

    imageReady javascript图片预加载,监测图片加载完成,获取图片真实尺寸的组件(图片延迟加载) 如何使用 // 首先在页面中引入imageReady.js/** * @param im ...

  8. html图片怎么预加载,如何利用CSS和Javascript实现图片预加载

    说到图片预加载,想必大家已经很熟悉了,在平时的项目中,我们常用插件实现预加载,比如:懒加载lazyload插件等等.如果你想了解下lazyload,可以看下这两篇文章: 今天主要想介绍不用插件实现图片 ...

  9. javascript图片浏览器的核心——图片预加载

    网站开发时经常需要在某个页面需要实现对大量图片的浏览,如果考虑流量的话,大可以像pconline一样每个页面只显示一张图片,让用户每看一张图片就需要 重新下载一下整个页面.不过,在web2.0时代,更 ...

  10. 利用CSS、JavaScript及Ajax实现图片预加载的三大方法

    预加载图片是提高用户体验的一个很好方法.图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度.这对图片画廊及图片占据很大比例的网站来说十分有利,它保证了图片快速.无缝地发布 ...

最新文章

  1. 一文掌握机器学习必备数学知识(附学习资源)
  2. Android自定义组件
  3. mysql出现连接错误不识别 utf8mb4
  4. 简单概述 .NET Framework 各版本区别
  5. django国际化与html语言,Django 国际化
  6. Gym 100553J Jokewithpermutation(dfs)
  7. QT5开发及实例学习之十一Qt5文件操作功能
  8. Servlet学习-MVC开发模式
  9. python怎么计算指数_如何在Python中使用SciPy计算值和指数值的立方根?
  10. winform显示器适配(解决字体模糊,界面错乱,多屏适配)
  11. 【面试题001】最强java八股文
  12. hdu4121 象棋checkmate模拟
  13. Java读取数据库的数据并转换为json数据
  14. 面试 - 阿里华为资深HR面试套路全揭晓
  15. ZLG_USBCAN-Ⅱ+ 设置滤波问题
  16. 钟汉良日记:为何我持续写日记四十天后,让他精神层面完全被影响?
  17. Lévy State-Space Models for Tracking and Intent Predictionof Highly Maneuverable Objects
  18. 避免使用虚函数作为库的接口
  19. fiddler安装证书失败
  20. SPSS Statistics 17.0多国语言(含中文)完整注册版

热门文章

  1. 安卓桌面软件哪个好_有哪些好用的手机记事本软件?安卓手机便签哪个好用?
  2. flowable 配置自定义表单_SpringBootSecurity学习(03)网页版登录添加自定义登录页面...
  3. 在HTML中添加图片阴影,html – 如何在CSS中为图像添加内部阴影[复制]
  4. TensorFlow:作用域name_scope和variable_scope
  5. 容器技术Docker K8s 8 容器服务ACK Pro版集群
  6. 人工智能中的深度结构学习 Learning deep architectures for AI - Yoshua Bengio
  7. 深度图像配准_巧解图像处理经典难题之图像配准
  8. 反地理编码 高德地图_由中文地址返回点位坐标-地理编码脚本分享
  9. memcpy和strcpy的区别
  10. 杭电HDUacm2098