非必须不载入图片技术(仿迅雷首页图片被动加载)

技术原理简介:
     用户访问页面很多时候,并没有滚动到底部,所以有时候很多图片载入却是浪费了时间
      将需要被动加载的图片的src属性用自定义属性写入HTML,src指向一个1像素宽高的占位图片
      根据滚动条位置和图片坐标计算判断图片是否出现在可视区域内,如果是,那么加载图片
技术的好处:
      1,加快页面载入速度,提高用户体验,首页图片较多的页面尤其明显
      2,节省流量和服务器连接数
/**
* Javascript Image Delay load
*
* Javascript实现的页面图片被动加载类,在使用前用1像素图像进行占位
* 并给img tag 添加 自定义bigsrc属性 ,当有图片进入可视区域内时,载入图片
* 提高页面载入速度,节省不必要的流量和连接数
*  
* @TODO    x轴滚动加载功能未被实现
*/
//闭包防止变量冲突
(function(){
    //预定义变量,减小代码体积
    var _ = document,
        A = _.compatMode,
        B = _.body,
        C = _.documentElement;
    //Constructor
    function AimoLoad(e){
        //要处理的包含延迟加载图片的容器
        this.area = e ?  this.get(e) : _;
        //需要延迟加载的所有图片对象
        this.imgs = [];
        //执行判断 条件成立 载入图片
        this.run();
    }
    //扩展原型链(注册类其他方法)
    AimoLoad.prototype = {
        //获取DOM元素,仅支持ID
        'get' : function(e){
            return typeof(e)=='string' ? _.getElementById(e) : e;
        },
        //获取所有需要被动载入的图片集合
        'getImages' : function(){
            var i = 0,
                imgs = this.area.getElementsByTagName('img'),
                l = imgs.length;
            for ( ; i < l; i++) {
                //过滤带有bigsrc属性的所有图片
                if(imgs[i].getAttribute('bigsrc')){
                    this.imgs.push(imgs[i]);
                }
            }
        },
        
        //获取元素位置坐标
        'getPosition' : function(el){
            var x = 0, y = 0;;
            if (el.getBoundingClientRect) {
                var box = el.getBoundingClientRect(),
                    el = (A != "CSS1Compat") ?
                    _.body : C;
                x = box.left + el.scrollLeft - el.clientLeft;
                y = box.top + el.scrollTop - el.clientTop;
            } else {
                x = el.offsetLeft;
                y = el.offsetTop;
                var parent = el.offsetParent;
                while (parent) {
                    x += parent.offsetLeft;
                    y += parent.offsetTop;
                    parent = parent.offsetParent;
                }
            }
            return {'x' : x, 'y' : y};
        },
        
        //封装判断变量是否定义
        'defined' : function(o){
            return (typeof(o)!="undefined");
        },
        
        //封装合法化Int变量
        'zeroFix' : function(n){
            return (!this.defined(n) || isNaN(n))? 0 : n;
        },
        //获取可视部分高度
        'getVisibileHeight' : function(){
            var cm = C && (!A || A=="CSS1Compat");
            if (!window.opera && cm) {
                return C.clientHeight;
            }else if (A && !window.opera && B) {
                return B.clientHeight;
            }
            return this.zeroFix(self.innerHeight);
        },
        //获取垂直滚动条位置
        'getScrollTop' : function(){
            if (C && this.defined(C.scrollTop) && C.scrollTop>0) {
                return C.scrollTop;
            }
            if (B && this.defined(B.scrollTop)) {
                return B.scrollTop;
            }
            return 0;
        },
        
        //执行主函数
        'run' : function(){
            //获取其他脚本注册到window上的onscroll和onresize事件,避免冲突
            var _resize = window.onresize || function(){},
                _scroll = window.onscroll || function(){},
                //引用自身,另存this指向
                _self = this,
                //定义注册函数
                delayLoad = function(){
                    //清空前一次获取的所有图片
                    _self.imgs = [];
                    //获取当前未载入的图片
                    _self.getImages();
                    //如果已经没有被动载入的图片了,那么释放注册的事件,提高性能,节省内存
                    if(_self.imgs.length==0){
                        window.onscroll = function(){
                            _scroll();
                        };
                        window.onresize = function(){
                            _resize();
                        };
                        //alert('清除事件');
                        return;
                    }
                    var i = 0,
                        m = _self.imgs,
                        l = _self.imgs.length,
                        y = _self.getVisibileHeight(),
                        t = _self.getScrollTop();
                    //遍历所有需要被动载入的图片
                    for( ; i < l; i++){
                        //闭包保证i变量
                        (function(i){
                            
                            //获取每个图像对象的坐标
                            var pos = _self.getPosition(m[i]);
                            //如果图片出现在可视区域内
                            if(t + y > pos.y){
                                //读取bigsrc属性,替换当前src属性
                                m[i].setAttribute('src', m[i].getAttribute('bigsrc'));
                                //删除bigsrc属性,提高性能
                                m[i].removeAttribute('bigsrc');
                            }
                        })(i);//闭包结束
                    }//循环结束
                };//定义注册函数结束
            
            //注册函数到window scroll事件
            window.onscroll = function(){
                _scroll();//执行其他脚本注册到当前事件的函数
                delayLoad();
            };
            //注册函数到window resize事件
            window.onresize = function(){
                _resize();//执行其他脚本注册到当前事件的函数
                delayLoad();
            };
        }
    }
    //暴露接口到外部,以便调用
    window.AimoLoad = AimoLoad;
})();

posted @ 2011-10-15 20:10  锐洋智能  阅读(287)  评论(0编辑  收藏  举报