zoukankan      html  css  js  c++  java
  • 非必须不载入图片技术(仿迅雷首页图片被动加载)

    技术原理简介:
         用户访问页面很多时候,并没有滚动到底部,所以有时候很多图片载入却是浪费了时间
          将需要被动加载的图片的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;
    })();

  • 相关阅读:
    变量可变性问题
    Android 创建Listener监听器形式选择:匿名内部类?外部类?
    linux下安装zookeeper
    翻页工具类
    将哈夫曼树转化成二叉树
    Activity的启动流程分析
    题目1186:打印日期
    数据库设计--数据流图(DFD)
    c#基础之数组
    10.3.1 一个CONNECT BY的样例
  • 原文地址:https://www.cnblogs.com/interdrp/p/2213622.html
Copyright © 2011-2022 走看看