• 图片预加载


    今天在做页面的时候需要实现图片预加载的功能,保证迅速正常的显示。

    解决方式:

    css方式,将图片作为背景图片加载

    .pic{background-image: url(image/demo.png) no-repeat -9999px -9999px;}
    

    这种方式的前提是,进入页面后的图片不会立即用到。如果一打开页面就需要看到完整图片,这种方式也还是挺耗时间的。

    通过javascript加载图片:

    首先创建一个Image对象,实现图片的预加载;然后检测图片是否存在缓存中如果存在就直接调用回调函数,若不在执行 onload() 方法。

    function preLoadImages(url,callback){
        var img = new Image();  
        img.src = url;
        if(img.complate){   //判断图片是否在缓存中
            callback(img);
            return;
        }
        img.onload = function(){    //下载图片异步调用callback函数
            callback(img);
        }
    }
    

    分析:这个方式还是有一些问题
    1.创建了一个临时的匿名函数来作为图片的onload事件处理函数,形成了闭包。闭包有保存外部运行环境的能力(依赖于作用域链的实现),所以imag.onload这个函数内部有保存了对img的引用,这样就形成了循环作用,导致内存泄露。(这种方式只存在于与ie6,高版本的浏览器一般都不会出现内存泄露)。
    2.只考虑了静态图片的加载,忽略了gif等动态图片,这些动态图片可能多次触发onload事件。
    解决方式:

    img.onload = function(){
        img.onload = null;
        callback(img);
    }
    

    关于这段代码,看相关博文里的叙述,原因如下:
    经过对多个浏览器版本的测试,发现ie、opera下,当图片加载过一次以后,如果再有对该图片的请求时,由于浏览器已经缓存住这张图片了,不会再发起一次新的请求,而是直接从缓存中加载过来。对于 firefox和safari,它们试图使这两种加载方式对用户透明,同样会引起图片的onload事件,而ie和opera则忽略了这种同一性,不会引起图片的onload事件,因此上边的代码在它们里边不能得以实现效果。
    确实,在ie,opera下,对于缓存图片的初始状态,与firefox和safari,chrome下是不一样的(有兴趣的话,可以在不同浏览器下,测试一下在给img的src赋值缓存图片的url之前,img的状态),但是对onload事件的触发,却是一致的,不管是什么浏览器。产生这个问题的根本原因在于,img的src赋值与 onload事件的绑定,顺序不对(在ie和opera下,先赋值src,再赋值onload,因为是缓存图片,就错过了onload事件的触发)。应该先绑定onload事件,然后再给src赋值,代码如下:

    function loadImage(url, callback) {     
        var img = new Image(); //创建一个Image对象,实现图片的预下载     
        img.onload = function(){
            img.onload = null;
            callback(img);
        }
        img.src = url; 
    }
    

    这样内存泄漏,动态图片的加载问题都得到了解决,而且也以统一的方式,实现了callback的调用。

    所以我使用了下面的代码:

    function loadImage(url, callback) {     
        var img = new Image(); //创建一个Image对象,实现图片的预下载     
        img.onload = function(){
            img.onload = null;
            callback(img);
        }
        img.src = url; 
    }
    

    或者直接采用加载多张图的方法
    1.

    function preloadimages(arr, callback){
        var newimages=[], loadedimages=0
        var arr=(typeof arr!="object")? [arr] : arr
        function imageloadpost(){
            loadedimages++
            if (loadedimages==arr.length){
                //alert("图片已经加载完成")
                callback(newimages);
                return;
            }
        }
        for (var i=0; i<arr.length; i++){
            newimages[i]=new Image()
            newimages[i].src=arr[i]
            newimages[i].onload=function(){
                imageloadpost()
            }
            newimages[i].onerror=function(){
            imageloadpost()
            }
        }
    }   
    使用方法:
    preloadimages(['1.gif', '2.gif', '3.gif'], function(images){
       //代码块
       console.log(images.length);
    });
    
    function preloadimages(arr){   
        var newimages=[], loadedimages=0
        var postaction=function(){}  //此处增加了一个postaction函数
        var arr=(typeof arr!="object")? [arr] : arr
        function imageloadpost(){
            loadedimages++
            if (loadedimages==arr.length){
                postaction(newimages) //加载完成用我们调用postaction函数并将newimages数组做为参数传递进去
            }
        }
        for (var i = 0; i<arr.length; i++){
            newimages[i] = new Image()
            newimages[i].src = arr[i]
            newimages[i].onload = function(){
                imageloadpost()
            }
            newimages[i].onerror = function(){
                imageloadpost()
            }
        }
        return { //此处返回一个空白对象的done方法
            done:function(f){
                postaction=f || postaction
            }
        }
    }
    使用方式:
     preloadimages(['1.gif', '2.gif', '3.gif']).done(function(images){
       alert(images.length) //alerts 3
       alert(images[0].src+" "+images[0].width) //alerts '1.gif 220'
    })
    

    代码地址
    最后收藏一个 css3.0 实现的 load样式

  • 相关阅读:
    web报表工具FineReport常用函数的用法总结(日期和时间函数)
    web报表工具FineReport常用函数的用法总结(文本函数)
    实例:供应商管理报表需求调研报告
    电信业务支撑报表系统解决方案
    小程序开发快速入门教程(附源码)
    不用代码,10分钟打造属于自己的第一款小程序
    移动端iPhone系列适配问题的一些坑
    【前端统计图】echarts多条折线图和横柱状图实现
    不用代码,10分钟打造属于自己的第一款小程序
    markdown模式的一些语法
  • 原文地址:https://www.cnblogs.com/aoxiaoqiang/p/4976363.html
Copyright © 2020-2023  润新知