zoukankan      html  css  js  c++  java
  • 构建一个前端库做一个富客户端的基类

    基类,我们需要一个基类。

    数据库访问我们通常有一个基类,用于操作的统一性。

    那么,我们现在需要一个富客户端的前端基类。

    为什么我们需要它。

    1.我们需要一个dom元素与javascript之间的桥梁。

    2.我们需要一个可伸缩布局的方案。

    3.它是可拖动的。

    4.它是可改变大小的。

    5.它是可参数化配置的。

    6.它是可绑定数据源的。

    7.它是可隐藏也可延迟加载的。

    我们需要这么一个基类,避免我们重复写很多相似的代码、

    我们一个一个来说它们的实现。

    1.构建桥梁

    通常我们都用document.getElementById来用javascript获取一个dom元素。

    但这里,我们富客户端的方案是用javascript生成dom对象,并且用jQuery辅助我们的元素获取。

    所以首先我们来动态构建html

    复制代码
        if (v.modal == 1) {
            //允许多个模态对象并存
            if (_modal_layer) _modal_layer += 5;
            else _modal_layer = radf.MODAL_LAYER;
    
            v.parent = _root;
            v.zIndex = _modal_layer + 1;
    
        } else if (v.modal == 2) {
            //只允许同时存在一个非模态对象,后面的非模态对象会替代前面的非模态对象
            if (_modeless) {
                _modeless._param.modal = 0;
                if (_modeless._loaded) _modeless.sendToTop();
                else _modeless._param.zIndex = 1;
            }
            
            v.parent = _root;
            v.zIndex = radf.MODELESS_LAYER;
            _modeless = this;
        }
    
        //html定义
        if (v.id) this._html= v.tagName + " id=" + v.id + " class='" + v.className + "' _objIndex=" + this._objIndex + " _loadMode=" + v.loadMode;
        else this._html= v.tagName + " class=" + v.className + " _objIndex=" + this._objIndex + " _loadMode=" + v.loadMode;
    
        if (v.tip) this._html += " title='" + v.tip + "' ";
    
        //样式属性
        this._style = " style='position:absolute;overflow:" + v.scrollBar;
    
        if (this._padding.text) this._style+= ";padding:" + this._padding.text;                //留白
        if (this._borderWidth.text) this._style+= ";border-" + this._borderWidth.text;//边框宽度
        if (v.borderStyle) this._style+= ";border-style:" + v.borderStyle;                    //边框样式
        if (v.borderColor) this._style+= ";border-color:" + v.borderColor;                    //边框颜色
        if (v.background) this._style+= ";background:" + v.background;                        //背景
        if (v.style) this._style += ";" + v.style;                                            //样式
    
        if (v.minWidth == 0 ) v.minWidth = this._borderWidth.left + this._borderWidth.right + this._padding.left + this._padding.right;
        if (v.minHeight == 0 ) v.minHeight = this._borderWidth.top + this._borderWidth.bottom + this._padding.top + this._padding.bottom;
    
        //位置属性
        this._top = v.top;
        this._left = v.left;
    
        this._y0 = this._padding.top + this._borderWidth.top;
        this._x0 = this._padding.left + this._borderWidth.left;
        this._oldY0 = this._y0
        this._oldX0 = this._x0;
    复制代码

    然后,我们把这个html用jQuery包装起来。

    Control.prototype.$ = $(this._html);

    最后,我们用一个全局的数组来保存所有产生的javascript对象。

    var radf._objIndex = [];
    this._objIndex = radf._obj.length;
    radf._obj[this._objIndex] = this;

    这样,我们在这个对象内部就拥有了它自己的jQuery对象,在全局上也拥有了一个可控的Javascript对象。

    我们可以轻易的在全局使用这个javascript也可以方便的在原型中使用jQuery对象。

    2.可伸缩布局的方案

    浮动和清除浮动是前端永恒的话题。但是我们的方案中,用了一个神奇的东西。

    position:absolute

    好吧,我们都知道它是一个禁果。

    它非常轻易的可以实现元素的随意摆放,但也非常损耗性能。

    使用它,我们要注意几件事

    1.margin,padding不再可使用。

    2.需要一个可承受的性能损耗。

    3.z-index变得十分重要。

    4.可控的元素嵌套。

    5.可实现的算法。

    所以我们写了三种情况下的算法。

    复制代码
        //1. 重画大小不依赖于父组件的子组件
        this._redrawFirst();
    
        //2. 确定自适应方式下的组件大小
        this._redrawSecond();
    
        //3. 重画大小依赖于父组件的子组件
        this._redrawThird();
    
        //4. 布局子组件
        if (this._layout) this._layout();
    复制代码

    由于我们在布局的时候,ajax操作会异步执行,

    所以经过测试,在数据到来的零点几秒之内,

    dom元素的布局是完成了,所以算法的时间消耗是可以接受的。

    3.可拖动及可以改变大小

    绝对定位的原因,可拖动变得十分简单。

    改变大小的问题,在于改变大小后,调用上面的方法,重算父窗口就ok了。

    4.可配置的参数

    复制代码
    Control.prototype.create = function(v) {
        //设置缺省参数
        //for (var i in this._defaultParam) if (v[i]==null) v[i] = this._defaultParam[i];
        radf.Utility.copy(this._defaultParam,v);
    
        //保存初始化参数
        this._param = v;
    
        //设置父对象
        if (v.parent == null || v.modal > 0 ) {
            if (_root) v.parent = _root;
            else v.parent = root();
        }
    
        v.parent._addChild(this);
    
        //建立对象索引
        this._objIndex = radf._obj.length;
        radf._obj[this._objIndex] = this;
    
        //初始化参数
        this._iniParam(v);
    }
    复制代码

    我们看一下一个类实例化的时候会做些什么, 将默认参数存起来,将填写的参数加入到实例中,

    将父对象保存起来,建立对象的索引号。

    5.可绑定数据

    我之前提到的MVVM模式的优势在于,数据先到的话,就会将数据存起来,

    dom先加载了,就会将外框的div先加载,而里面的数据,例如table中的td,在数据到来的时候再加载。

    并且,在dom元素操作的时候,也会通过基类写好的方法,将数据重新绑到数据对象。

    或者在操作数据对象,例如重新从数据库取出数据后,就会重新生成dom元素。

    这样,一个可绑定的组件基类就ok了。

     

    7.它是可隐藏并且可以延迟加载

    我们知道,当一个dom对象需要隐藏,将它的display设成none,就会让这个元素不占位的隐藏。

    如果用visible的话,就会占位隐藏。由于富客户端的作法,我们基本上没有外链,所有操作都在一个页面上,

    空间非常的局限。所以一个可以伸缩的页面是非常必要的。

    那么我们使用display将单个组件变得可以隐藏起来,以用来显示全全部内容。

    那么延迟加载就很好理解了,如果元素被设为visible:false,那我们就不做这个元素的数据绑定,也不会这个对象的宽高,

    只有一个空的div在那里。当这个元素被要求显示,例如一个折叠框打开时候,我们再去load它。

     
     
  • 相关阅读:
    iOS resign code with App Store profile and post to AppStore
    HTTPS科普扫盲帖 对称加密 非对称加密
    appid 评价
    使用Carthage安装第三方Swift库
    AngularJS:何时应该使用Directive、Controller、Service?
    xcode7 The operation couldn't be completed.
    cocoapods pod install 安装报错 is not used in any concrete target
    xcode7 NSAppTransportSecurity
    learning uboot how to set ddr parameter in qca4531 cpu
    learning uboot enable protect console
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2861942.html
Copyright © 2011-2022 走看看