zoukankan      html  css  js  c++  java
  • javascript图片预加载技术

    再谈javascript图片预加载技术

    图片预加载技术的典型应用:

    如lightbox方式展现照片,无疑需要提前获得大图的尺寸,这样才能居中定位,由于javascript无法获取img文件头数据,必须等待其加载完毕后才能获取真实的大小然后展示出来,所以lightbox显示的图片的速度体验要比直接输出的差很多,而本文说提到的预加载技术主要针对获取图片尺寸。

    一段典型的使用预加载获取图片大小的例子:

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

    一、结合flash加载图片,获取图片头部数据的尺寸

    flash虽然很强大,但它与生俱来的缺点让人爱恨交织,加上很多移动设备不支持falsh无疑更是致命的伤,还是放弃吧。

    二、在服务端保存图片尺寸数据

    这里不得不提到腾讯Qzone的lightbox相册,它就是这样做的。它能在图片没有加载完全的时候就居中放大图片,速度与优雅基本兼得。不过它仍然难以避免blog插入的外链图片的问题,也只能按传统的方式加载完毕才能展示。

    三、javascript通过占位方式获取图片头部数据的尺寸

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

    实现代码:

    QUOTE:
    var imgReady = function (url, callback, error) {
            var width, height, intervalId, check, div,
                    img = new Image(),
                    body = document.body;

            img.src = url;

            // 从缓存中读取
            if (img.complete) {
                    return callback(img.width, img.height);
            };

            // 通过占位提前获取图片头部数据
            if (body) {
                    div = document.createElement('div');
                    div.style.cssText = 'visibility:hidden;position:absolute;left:0;top:0;1px;height:1px;overflow:hidden';
                    div.appendChild(img)
                    body.appendChild(div);
                    width = img.offsetWidth;
                    height = img.offsetHeight;

                    check = function () {
                            if (img.offsetWidth !== width || img.offsetHeight !== height) {
                                    clearInterval(intervalId);
                                    callback(img.offsetWidth, img.clientHeight);
                                    img.onload = null;
                                    div.innerHTML = '';
                                    div.parentNode.removeChild(div);
                            };
                    };

                    intervalId = setInterval(check, 150);
            };

            // 加载完毕后方式获取
            img.onload = function () {
                    callback(img.width, img.height);
                    img.onload = img.onerror = null;
                    clearInterval(intervalId);
                    body && img.parentNode.removeChild(img);
            };

            // 图片加载错误
            img.onerror = function () {
                    error && error();
                    clearInterval(intervalId);
                    body && img.parentNode.removeChild(img);
            };

    };
    --------------------代码如下------------------------
    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>img ready demo</title>
    <script>
    /*!
     * http://www.planeart.cn/?p=1121
     * Copyright 2011, TangBin
     */
    var imgReady = function (url, callback, error) {
        var width, height, intervalId, check, div,
            img = new Image(),
            body = document.body;
           
        img.src = url;
       
        // 从缓存中读取
        if (img.complete) {
            return callback(img.width, img.height);
        };
       
        // 通过占位提前获取图片头部数据
        if (body) {
            div = document.createElement('div');
            div.style.cssText = 'visibility:hidden;position:absolute;left:0;top:0;1px;height:1px;overflow:hidden';
            div.appendChild(img)
            body.appendChild(div);
            width = img.offsetWidth;
            height = img.offsetHeight;
           
            check = function () {
                if (img.offsetWidth !== width || img.offsetHeight !== height) {
                    clearInterval(intervalId);
                    callback(img.offsetWidth, img.clientHeight);
                    img.onload = null;
                    div.innerHTML = '';
                    div.parentNode.removeChild(div);
                };
            };
           
            intervalId = setInterval(check, 150);
        };
       
        // 加载完毕后方式获取
        img.onload = function () {
            callback(img.width, img.height);
            img.onload = img.onerror = null;
            clearInterval(intervalId);
            body && img.parentNode.removeChild(img);
        };
       
        // 图片加载错误
        img.onerror = function () {
            error && error();
            clearInterval(intervalId);
            body && img.parentNode.removeChild(img);
        };
       
    };
    </script>
    <style>
    /*demo style*/
    body { font:12px 'Microsoft Yahei', Tahoma, Arial; _font-family:Tahoma, Arial; }
    a { color:#0259C4; }
    a:hover { color:#900; }
    .demoInfo { 540px; padding:10px; background:#F7F7F7; border:1px solid #EEE; -webkit-border-radius:5px; -moz-border-radius:5px; border-radius:5px; }
    .tips { color:#CCC; }
    #path { 36em; padding:5px; border:2px solid #0259C4; background:#FAFAFA;-webkit-border-radius:3px; -moz-border-radius:3px; border-radius:3px; }
    #path:focus { background:#FFFFF7; }
    #submit { padding:5px 10px; border:2px solid #0259C4; background:#0259C4; color:#FFF; -webkit-border-radius:3px; -moz-border-radius:3px; border-radius:3px; cursor:pointer; }
    #submit.disabled { background:#D7D7D7; color:#ABABAB; border-color:#ABABAB; cursor:default; }
    </style>
    <script>
    /* demo script */
    window.onload = function () {
       
        var $ = function (id) {
            return document.getElementById(id);
        };
       
        // 传统图片预加载
        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;
                };
            };
       
        };
       
        var imgUrl,
            path        = $('path'),
            submit        = $('submit'),
            clsCache    = $('clsCache'),
            status        = $('status'),
            statusReady    = $('statusReady'),
            statusLoad    = $('statusLoad'),
            imgWrap        = $('imgWrap');
       
        submit.disabled = false;   
        submit.onclick = function () {
            var that = this;
           
            imgUrl = path.value;
            that.disabled = true;
            that.className = 'disabled';
            status.style.display = 'block';
            statusLoad.innerHTML = statusReady.innerHTML = 'Loading...';
            imgWrap.innerHTML = '<img src="' + imgUrl + '" />';
           
            // 使用占位方式快速获取大小
            imgReady(imgUrl, function (width, height) {
                statusReady.innerHTML = 'width = ' + width + '; height = ' + height;
            }, function () {
                statusReady.innerHTML = 'Img Error!';
            });
           
            // 使用传统方式获取大小
            imgLoad(imgUrl, function (width, height) {
                statusLoad.innerHTML = 'width = ' + width + '; height = ' + height;
                that.disabled = false;
                that.className = '';
            }, function () {
                statusLoad.innerHTML = 'Img Error!';
                that.disabled = false;
                that.className = '';
            });
        };
       
        clsCache.onclick = function () {
            var value = path.value;
            path.value = (value.split('?')[1] ? value.split('?')[0] : value) + '?' + new Date().getTime();
            status.style.display = 'none';
            imgWrap.innerHTML = '';
        };

    };
    </script>
    </head>

    <body>
    <div class="demoInfo">
    <p>《<a href="http://www.planeart.cn/?p=1121">再谈javascript图片预加载技术</a>》文章演示例子</p>
    <p>(通过测试的浏览器:Chrome、Firefox、Safari、Opera、IE6、IE7、IE8)</p>
    </div>
    <div style="height:40px; line-height:40px;"><input type="text" id="path" value="http://www.planeart.cn/demo/imgReady/vistas24.jpg" /> <input type="button" id="submit" value="加 载" /> <a id="clsCache" href="#" style="color:#0259C4;">清空缓存</a><em class="tips">(浏览器会缓存加载过后的图片)</em></div>
    <div id="status" style="display:none">
        <p><strong>通过文件头信息获取尺寸:</strong> <span id="statusReady"></span><p>
        <p><strong>通过加载完毕后获取尺寸:</strong> <span id="statusLoad"></span></p>
    </div>
    <div id="imgWrap"></div>
    <div style="display:none"><script src="http://s86.cnzz.com/stat.php?id=1581115&web_id=1581115" charset="gb2312"></script></div>
    </body>
    </html>
    ----------------华丽丽的分界线--------------------------
    好了,请观赏令人愉悦的 DEMO : http://www.planeart.cn/demo/imgReady/
  • 相关阅读:
    Mybatis和Spring整合也是能用BatchExecutor的
    与Spring整合的Mybatis没法真正使用BatchExecutor
    Mybatis和Spring整合后sqlsession啥时候关闭的
    Mybatis和Spring的整合原理
    Mybatis是怎么执行一条语句的
    8.11查询结果排序
    8.10、11(select分组和过滤)()
    8.7、8、9(select语句基本用法)(select语句基本运算符)(select聚合查询)
    8.4SQL(DML数据操作语言)-(insert插入数据)(updata更新数据),(delete数据)
    8.2数据库DDL语言(即数据库定义语言)(命名规则以及数据类型)
  • 原文地址:https://www.cnblogs.com/xulan/p/1994119.html
Copyright © 2011-2022 走看看