zoukankan      html  css  js  c++  java
  • javascript 图像预载入和如何判断图片是否加载完成

    很多high-res图像真的可以使 Web 站点更加整洁。但是它们也会使站点的访问速度变慢——图像是文件,文件使用带宽,带宽直接与等待时间相关。是该了解如何通过一个叫做图像预载入(preloading)的技巧来提高 Web 站点的访问速度的时候了。

    图像预载入

    对于浏览器载入图像来说,只有在对图像发送一个 HTTP请求之后,它们才会被浏览器载入,对图像的 HTTP 请求要么使用 <img> 标记,要么通过方法调用实现。如果使用 JavaScript 脚本来处理在 mouseover 事件时交换图像,或者在一段时间之后自动更改图像,那么在从服务器获取图像时可能要等上几秒钟到几分钟的时间。如果使用一个慢速的 Internet 连接,或者要获取的图像非常大,或者其它一些情况,这种现象就特别明显;这样,延迟就造成你不能达到自己期望的效果。

    一些浏览器采用一些措施来缓解这一问题,比如试图通过在本地缓存中存储图像,从而使随后对图像的调用能够立即被满足;但是在图像第一次被调用时依然会存在一些延迟。预载入是在需要图像之前将其下载到缓存的一种方法。通过这一措施,当真正需要图像时,它就可以被立即从缓存中取出,从而能够立即显示。

    Image() 对象

    预载入图像最简单的方法是在 JavaScript 中实例化一个新 Image() 对象,然后将需要载入的图像的 URL 作为参数传入。假设我们有一个图像叫做heavyimagefile.jpg,在用户的鼠标放到一个已经显示的图像之上时,我们希望显示这个图像。为了预载入这一图像从而得到较快的响应时间,我们简单地创建一个 Image() 对象 heavyImage,然后在 onLoad() 事件处理器中将其同时载入。

    function preloader()
    {
        heavyImage=new Image();
        heavyImage.src="../images/bigGirl.jpg";
    }
    document.onload=preloader;


    <img src="../images/yanzi.jpg" name="img1" onmouseover="js:document.images.img1.src='../images/bigGirl.jpg';  /> </a>

    或者this.src=' ';

    使用数组载入多个图像

    在实际应用中,我们可能需要预载入多个图像,而不止一个;例如,在一个包含多个图像翻卷的菜单栏中,或者在我们试图创建平滑效果时,都需要预载入多个图像。其实这并不困难,只要使用 JavaScript 的数组即可实现,如下例所示:

    function preloader()
    {
        var i=0; //counter;
        var imageObj=new Image();
        var images=new Array();
        for(i=0;i<5;i++)
        {
            images[i]=i+'jpg';
            
        }
        for(i=0;i<5;i++)
        {
            imageObj.src=images[i];
        }
    }

    在上面的例子中,我们定义一个变量 i和一个 Image() 对象 imageObj。然后定义了一个新数组 images[],每个数组元素存储要被预载入的图像。最后,创建一个 for() 循环来处理整个数组,并将每个元素赋给 Image() 对象,这样将其载入到缓存中。

    function onloadFunc()
    {
    var objImage=new Image();
    objImage.src="../images/bigGirl.jpg";//preload the image
    objImage.onload=function(){ window.location.href="http://www.baidu.com"; }
    }

    <img src="../images/yanzi.jpg" name="img1" onmouseover="js:onloadFunc();" />

    当然,你还可以创建一个图像数组然后在其上进行循环操作,预载入每个图像,然后在每一阶段跟踪被载入图像的数目。一旦所有图像载入完毕,根据事件处理器的程序逻辑,它就可以将浏览器带入下一个页面(或者执行其它任务)。

    当然,你还可以创建一个图像数组然后在其上进行循环操作,预载入每个图像,然后在每一阶段跟踪被载入图像的数目。一旦所有图像载入完毕,根据事件处理器的程序逻辑,它就可以将浏览器带入下一个页面(或者执行其它任务)。

    via:http://www.wzsky.net/html/Website/Javascript/39549.html

    http://blog.donews.com/bigcarp/archive/2006/12/21/1100702.aspx

    如何判断图片是否加载完成

    一、一般情况下

    1)图片静态页面标签<img />创建

    <img src = 'http://www.baidu.com/img/baidu_sylogo1.gif' onload='onloadHandler(this)' />

    2)图片通过脚本动态创建

    1 var img = document.createElement('img');
    2 img.onload = function(){
    3   alert('img loaded, img.src = ' + this.src);
    4 };
    5 img.onload = onloadHandler;

    二、

    假设页面原本有这么张静态图片,但没有通过行内脚本的绑定onloadHandler,如下代码所示:(有可能开发GG很痛恨行内脚本)

    复制代码
    <img src="http://www.baidu.com/img/baidu_sylogo1.gif" id="pic" />
    多很多很多的资源要加载 -->
    
    <!-- 假设此处有很
    <script>
    
    function $(id) { return document.getElementById(id);}
    function onloadHandler(){
    
      alert('img loaded, img.src = ' + this.src);
    
    };
    
    var img = $('pic');
    img.onload = onloadHandler;baidu.com/img/baidu_sy
    img.src = "http://www.logo1.gif"; </script>
    复制代码

    会有什么问题呢?有可能这段脚本运行之前,图片的onload事件已经触发了,于是,onloadHandler永远也不会执行 >_<

    如何解决?—— img.complete

    img.complete:如果图片之前已经加载完成,则为true,否则为false

    复制代码
    <script>
    
    function $(id) { return document.getElementById(id);}
    function onloadHandler(){
      alert('img loaded, img.src = ' + this.src);
    };
    
    var img = $('pic');
    img.src = "http://www.baidu.com/img/baidu_sylogo1.gif";
    if(img.complete){
        onloadHandler.call(img);
    }else{
        img.onload =onloadHandler;  //注意这里跟上面的区别,img.src赋值 与 绑定 onload事件的顺序相反  
    } </script>
    复制代码

    写在后面:以上代码未经各大浏览器/版本 严格摧残验证,以下问题尚待验证,求不小心踩进来的大大指教!

    1)是否所有主流浏览器均支持 img.complete(包括不同版本)

    2)有没有可能在第一个分支判断 if(img.complete) 结束后,但未运行到 img.onload 这块代码,img的onload事件已经触发,导致onloadHandler不会执行

    下面这段代码中间插了个耗时无比的逻辑,延迟onload的绑定,结果:onload处理方法还是执行了

    复制代码
    var img = document.createElement('img');
    img.src = 'http://im-img.qq.com/inc/images/new_header2/logo.gif';
    if(img.complete){
        console.log('a');
        onloadHandler.call(img);
    }else{
        var t1 = new Date() - 0;
        var div = document.createElement('div');
        for(var i=0; i<10000; i++){
            div.innerHTML = div.innerHTML + i;
        }
        document.body.appendChild(div);
        var t2 = new Date() - 0;
        console.log(t2 - t1);  //在chrome23.0里,6000++ms
        img.onload = onloadHandler;
        
        img.onload = onloadHandler;  //神奇的事情:onload事件触发,而且处理方法被执行了
    }
    复制代码

    demo:http://jsfiddle.net/x2aW8/light/
    ----------------

    avascript如何判断一张图片是否加载完成:
    在实际应用中有时候需要判断图片是否加载完成,以便判断在完成前和完成后应该做哪些事情,下面就简单介绍一下如何实现此功能。代码实例如下:

    <!DOCTYPE html> 
    <html> 
    <head> 
    <meta charset=" utf-8"> 
    <meta name="author" content="http://www.softwhy.com/" />
    <head>
    <title>如何判断一个图片是否加载完成-蚂蚁部落</title>
    </head>
    <body>
    <img src="1.png" id="myimage" />
    <script type="text/javascript">
    var myimage=document.getElementById("myimage");
    myimage.onload=function()
    {
      alert("图片加载完成");
    } 
    </script>
    </body>
    </html>

    以上代码,当图片加载完成的时候会弹出一个提示框,实现了我们的需求。但是此种方法有个缺点,那就是不能够使用window.onload=function(){},因为这个时候文档已经加载完成了,图片的onload事件自然就无效了。所以推荐使用动态方式。
    代码如下:

    <!DOCTYPE html> 
    <html> 
    <head> 
    <meta charset=" utf-8"> 
    <meta name="author" content="[url=http://www.softwhy.com/]http://www.softwhy.com/[/url]" />
    <head>
    <title>如何判断一个图片是否加载完成-蚂蚁部落</title>
    <script type="text/javascript">
    window.onload=function()
    {
      var mydiv=document.getElementById("mydiv");
      var newImage=new Image()
      newImage.src='1.png'
      newImage.onload=function()
      {
        alert("图片加载完成");
        mydiv.appendChild(newImage);
      }
    }
    </script>
    </head>
    <body>
    <div id="mydiv"></div>
    </body>
    </html>

    以上代码同样可以在图片加载完成之后弹出一个对话框,并且将图片在div中显示.

    JS快速获取图片宽高的方法

    // 图片地址
    var img_url = 'http://www.qttc.net/static/upload/2013/13643608813441.jpg';
     
    // 创建对象
    var img = new Image();
     
    // 改变图片的src
    img.src = img_url;
     
    // 判断是否有缓存
    if(img.complete){
        // 打印
        alert('from:complete : '+img.width+',height:'+img.height);
    }else{
        // 加载完成执行
        img.onload = function(){
            // 打印
            alert('from:onload : '+img.width+',height:'+img.height);
        };
    }

    通过定时循环检测获取

    看看以下例子,为了避免从缓存里读取数据,每一次请求都带时间戳:

    // 记录当前时间戳
    var start_time = new Date().getTime();
     
    // 图片地址
    var img_url = 'http://b.zol-img.com.cn/desk/bizhi/image/2/2560x1600/1365477614755.jpg?'+start_time;
     
    // 创建对象
    var img = new Image();
     
    // 改变图片的src
    img.src = img_url;
     
    // 定时执行获取宽高
    var check = function(){
        // 只要任何一方大于0
        // 表示已经服务器已经返回宽高
        if(img.width>0 || img.height>0){
            var diff = new Date().getTime() - start_time;
            document.body.innerHTML += '<div>from:<span style="color:red;">check</span> : '+img.width+',height:'+img.height+', time:'+diff+'ms</div>';
            clearInterval(set);
        }
    };
     
    var set = setInterval(check,40);
     
    // 加载完成获取宽高
    img.onload = function(){
        var diff = new Date().getTime() - start_time;
        document.body.innerHTML += '<div>from:<span style="color:blue">onload</span> : '+img.width+',height:'+img.height+', time:'+diff+'ms</div>';
    };

    更详细的看:http://www.qttc.net/201304304.html

    http://www.111cn.net/wy/js-ajax/50093.htm

  • 相关阅读:
    Mysql 中的MVCC原理,undo日志的依赖
    Innodb 实现高并发、redo/undo MVCC原理
    Django restful 规范
    TCP 原理
    HTTPS建立连接的过程
    HTTP协议,Http 常用状态码
    SQL注入
    Mysql 索引问题集锦
    Mysql MyISAM与InnoDB 表锁行锁以及分库分表优化
    归并排序Python 实现
  • 原文地址:https://www.cnblogs.com/youxin/p/2692335.html
Copyright © 2011-2022 走看看