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它。

  • 相关阅读:
    虚树学习笔记
    CF487E Tourists
    [HNOI/AHOI2018]毒瘤
    [HEOI2014]大工程
    hive初始化元数据报错
    layui简单的两个页面
    springboot配置swagger信息入门2
    spark连接hive出现错误,javax.jdo.JDODataStoreException: Required table missing : "`DBS`" in Catalog "" Schema ""
    springboot整合shiro关于任务入门3
    Flink部署Standalone模式
  • 原文地址:https://www.cnblogs.com/bugluo/p/2861723.html
Copyright © 2011-2022 走看看