`
qinzhenzhou
  • 浏览: 10670 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
社区版块
存档分类
最新评论

javascript控件开发之布局控件

阅读更多
    上篇写完了页面控制器,本篇接着写下一个控件--布局控件,布局控件在系统开发中不算最重要,但也是起着举足经重的作用,相信做过网页的应该了解,在Html中页面布局是一件让人蛋痛的事情,有时候花一天都搞不定,因此所有控件开始之前,先把布局控件做好,后续有部份控件需要从这布局控件继承。
    在html标签中,有外边距、内边距、还有边框、坐标这几样属性,这几项控制好,布局的大方向基本能做好,再有就是浏览器的兼容问题一并考虑,
    首先,我们需要对先前写的com.ui.window.js做修改,把先前的 this.thisWindow改为this.win(前面的变量太长,改短一点)
对渲染函数render()进行修改
   添加容器功能,控件内可以添加控件,
   思路是
   1 先拿到控件dom元素(this.win),
   2 通过它获得父dom元素,
   3 判断父dom元素的_object是否为空,
   4 不为空就把父控件指向_object,
   5 设置_object为当前控件的父对象,
   6 给当前控件的dom(this.win)元素添加_object属性,指向当前控件this
   上面的这个思路是通用思路,不管哪个控件,都会有这上下层关系
    //初始化DOM框架
    var parent = this.win.parentNode;
    if(this.isNotEmpty(parent)) {
        if(this.isNotEmpty(parent._object)) {
            parent = parent._object;
        }
        this.setParent(parent, true);
    }		    
    this.win._object = this;
    parent = null;

  把设置内边距、外边距从doResize中移到render函数中来,
  接着调用doResize函数.
    this.setStyle(this.win, "winStyle");
    //边距处理
    var valpx = this.option.margin + "px";
    if(this.win.style.margin != valpx) {
        this.win.style.margin = valpx;
    }
    valpx = this.option.padding + "px";
    if(this.win.style.padding != valpx) {
        this.win.style.padding = valpx;
    }
    if(this.option.borderWidth !== "") {
        this.win.style.borderWidth = this.option.borderWidth + "px";
    }
    //处理大小变量
    if(this._hasResize() && this._update) {
        this._doResize();
        this._afterResize();
    }

doReize保留最原始的设置位置、宽度、高度的代码。
  其中新增加一个右对齐的代码,思路是获取父控件的宽度,计算靠右的位置,
  当然父控件有可能是最原始的dom元素,也可能是别的容器控件,
    if(this.isNotEmpty(this.option.right)) {
        var pw = this.parent;
        if(pw.isComponent) {
            pw = pw._getRectWidth();
        } else {
            pw = this._getRectWidth(pw);
        }
        valpx = (pw - this.option.right - this.getWidth()) + "px";
        if(this.win.style.left !== valpx) {
            msg += " left:" + this.win.style.left + " to " + valpx + " ";
            this.win.style.left = valpx;
            isResize = true;
        }
    }

另外再修改内部宽高的获取函数,加一个参数,添加支持通过传入任一dom元素,返回除去边距后dom元素的内宽和内高,
    /**
     * 获取内宽.
     * @return 返回宽度
     */
    _getRectWidth:function(el) {
        var width = this.getWidth();
        if(this.isNotEmpty(el)) {
            if(el.tagName == "BODY") {
                //设置默认边距
                width = this._getBodyWidth();
                if(this.isEmpty(el.style.marginLeft)) {
                    el.style.marginLeft = "0px";
                }
                if(this.isEmpty(el.style.marginRight)) {
                    el.style.marginRight = "0px";
                }
            } else {
                width = el.offsetWidth;
            }
        }
        //总宽度减去边距宽度
        width = width - (this._getMarginLeft(el)
	        + this._getMarginRight(el)
	        + this._getPaddingLeft(el)
	        + this._getPaddingRight(el));  
        if(!this.browser.msie) {
            width = width - (this._getBorderLeft(el) 
                + this._getBorderRight(el));
        }
        return width;
    },


修改完com.ui.window后,在component文件夹内添加com.ui.panel.js文件,并且在该件内编写我们的布局控件com.ui.panel,继承com.ui.window控件
控件的创建函数create中,添加默认的控件对齐方式this.align="none",添加是否panel控件的判断属性 this.isPanel=true
    /**
     * 创建函数
     */
    create:function() {
        this.base();
        this.className = "com.ui.panel";
        this.logInfo("create");      
        //对齐属性
        this.align = "alNode";
        this.isPanel = true;
    },

渲染函数render中,除了调用基类渲染函数this.base()外,添加this.win的绝对样式属性,再调用对齐设置函数。
    /**
     * 渲染.
     */
    render:function() {
        this.beginUpdate();
        this.base();
        this.endUpdate();
        //如果父层是控件对象则用绝对定位样式
        if(this.isNotEmpty(this.parent)) {
            this.win.style.position = "absolute";
        }
        //设置对齐方式
        if(this.isNotEmpty(this.option.align)) {
            this.setAlign(this.option.align);
        }
    },

渲染后函数afterRender中,判断如果父元素是body或其它dom元素时,为元素添加onresize事件,用作布局控件变化的的启动事件,在onresize事件中调用控件的_doResize函数
    /**
     * 渲染后函数.
     */
    afterRender:function(){
        //this.logInfo("Panel.afterRender");
        var _this = this;
        if(this.isNotEmpty(this.parent) && 
                !this.parent.isComponent) {
            //如果父控件是dom,则添加onResize事件
            var _this = this;
            var _lock = false;
            this.parent.onresize = function(ev) {
                if(_lock) return false;
                _lock = true;
                _this._doResize(_this.getBody());
                _lock = false;
            };
        }
        this.base();
    },

_doResize事件是本控件的核心,参数有一个,用于传入指定的元素,参数可以不传,在此先计算left, top坐标和height, width
    /**
     * 执行对齐事件.
     */
    _doResize:function(el){
        this.base();
        var lw = 0, 
        rw = 0, 
        th = 0, 
        bh = 0;
        var alcn = null;
        if(this.isNotEmpty(el)) {
            var rectLeft = this._getPaddingLeft(el),
                rectTop = this._getPaddingTop(el),
                rectHeight = this._getRectHeight(el),
                rectWidth = this._getRectWidth(el);
        } else {
            var rectLeft = this._getPaddingLeft(),
                rectTop = this._getPaddingTop(),
                rectHeight = this._getRectHeight(),
                rectWidth = this._getRectWidth();
                el = this;
        }

接着控制当前控件内的所有子控件的布局及宽高,
该段代码的思路是,先运算alTop、alLeft、alRight、alBottom控件,合计已占用的左、右、顶和底的宽度,最后计算alClient
    //处理所有子控件的对齐方式.
    for(var i = 0, len = el.childComponent.length; i < len; i++) {
        var cn = el.childComponent[i];
        if(cn.isPanel) {
            //只处理内部控件
            var al = cn.getAlign();
            if(al === "alClient") {
                //全屏的留后处理
                alcn = cn;		    				
            } else if(al === "alRight") {
                //靠右
                rw += cn.getWidth();
                cn.setHeight(rectHeight - th - bh, false);
                cn.setTop(th, false);
                cn.setLeft(rectWidth - rw + rectLeft);	    			    	
            } else if(al === "alLeft") {	
                cn.setTop(th, false);
                cn.setLeft(lw, false);					
                lw += cn.getWidth();				        
                cn.setHeight(rectHeight - th - bh);	    			    	
            } else if(al === "alTop") {
                cn.setTop(th, false);
                cn.setLeft(lw, false);					
                th += cn.getHeight();						
                cn.setWidth(rectWidth - lw - rw);
            } else if (al === "alBottom") {
                //靠底
                bh += cn.getHeight();
                cn.setWidth(rectWidth - lw - rw, false);
                cn.setTop(rectHeight - bh + rectTop);
                cn.setLeft(lw, false);
            }
        } else {
            cn._doResize();
        }
        cn = null;
    }
    if(this.isNotEmpty(alcn)) {
        //最后处理全屏的控件.
        alcn.setWidth(rectWidth - lw - rw, false);
        alcn.setLeft(lw + rectLeft, false);
        alcn.setHeight(rectHeight - th - bh, false);
        alcn.setTop(th + rectTop);
    }
    alcn = null;
    this._rectLeft = lw + rectLeft;
    this._rectTop = th + rectTop;	

最后添加设置对齐方式用的函数,
    /**
     * 设置对齐属性.
     * @param algin 对齐方式
     */
    setAlign:function(align) {
        if(this.align !== align) {
            this.align = align;
            if(this.isNotEmpty(this.parent)) {
                if(this.parent.isComponent) {
                    this.parent._doResize();
                } else {
                    this._doResize(this.parent); 
                }
            }
        }
    }

到此我们的的布局控件编写完成,
下面是test.html中的测试代码,
<!DOCTYPE html>
  <head><title>test</title>
    <script src="../script/common/init.js" type="text/javascript"></script>
  </head>  
  <body code="controllor/test.js" scroll="no" style="overflow:hidden">
    <div id='test1' code='com.ui.panel' option='{"align":"alTop","height":"40","width":"200","borderWidth":1,"padding":1}'></div>
    <div id='test6' code='com.ui.panel' option='{"align":"alTop","height":"100","width":"200","borderWidth":1,"padding":1}'></div>
	<div id='test4' code='com.ui.panel' option='{"align":"alBottom","height":"50","width":"200","borderWidth":1,"padding":1}'>
		<div id='test2' code='com.ui.button' option='{"height":"25","width":"100","top":"12","right":"116"}'></div>
	    <div id='test3' code='com.ui.button' option='{"height":"25","width":"100","top":"12","right":"8"}'></div>
	</div>
	<div id='test7' code='com.ui.panel' option='{"align":"alLeft","height":"100","width":"200","borderWidth":1,"padding":1}'></div>
	<div id='test5' code='com.ui.panel' option='{"align":"alClient","height":"100","width":"200","borderWidth":1,"padding":1}'></div>

  </body>
</html>

完整代码请下载附件,
请关注下一篇,javascript控件开发之工具栏控件


  • 9.rar (17.1 KB)
  • 下载次数: 4
  • 大小: 41.9 KB
分享到:
评论

相关推荐

    javascript控件开发之工具栏控件

    在JavaScript控件开发中,工具栏控件是一个关键的元素,它通常被用来提供用户界面中的功能快捷方式或操作选项。工具栏控件的设计和实现是网页交互性的重要组成部分,尤其是在构建富客户端应用或者增强用户体验的网页...

    几个经典JavaScript控件

    在网页设计中,JavaScript控件是不可或缺的一部分,它们为用户提供了丰富的交互体验。以下是一些基于JavaScript的经典控件及其相关的知识点: 1. **表格操作**: - `javascript 表格操作.html` 和 `操控表格.txt` ...

    javascript控件

    JavaScript控件是网页开发中的重要组成部分,它们是用JavaScript编程语言编写的一组功能模块,用于增强用户界面并提供丰富的交互性。这些控件通常作为框架出现,为开发者提供了便捷的工具集,帮助他们构建功能丰富的...

    Javascript密码输入控件

    JavaScript密码输入控件是网页开发中常见的一种交互元素,它用于收集用户的安全信息,如登录密码、PIN码等。在Web应用中,正确地实现密码输入控件对于提高用户体验和保障数据安全至关重要。本文将深入探讨JavaScript...

    Web2.0控件开发(电子书)

    在Web2.0控件开发中,Ajax(Asynchronous JavaScript and XML)技术起到了关键作用。Ajax允许页面在不刷新整个页面的情况下与服务器进行数据交换,提升了用户体验。开发者需要掌握JavaScript、XMLHttpRequest对象、...

    VC++ Activex控件开发

    VC++ ActiveX控件开发是Windows应用程序开发中的一个重要部分,主要涉及的是利用Microsoft Visual C++这一集成开发环境(IDE)创建能够嵌入到其他应用程序、网页或者Active Desktop中的控件。ActiveX技术允许开发者...

    Web2.0控件开发

    总的来说,Web2.0控件开发是.NET开发者必备的技能之一,它涉及到服务器端编程、前端交互、用户体验设计等多个方面。通过深入理解和实践,开发者可以构建出富有创新、高度互动的Web应用程序,满足不断发展的Web2.0...

    日期控件 javascript日期控件

    JavaScript日期控件因其轻量级、灵活性和易于集成的特点,在Web开发中被广泛使用。本篇将深入探讨JavaScript日期控件,包括其基本原理、使用方法以及如何与jQuery库结合,同时也将提及压缩包中的相关资源。 一、...

    JavaScript经典日期控件

    同时,为了适应不同的网站设计,控件可能支持自定义样式,以匹配网页的主题和布局。 4. **多语言支持**:考虑到全球化的需求,My97DatePicker可能会支持多种语言,包括但不限于中文、英文等,让用户在任何语言环境...

    阿赖实用javascript控件程序

    "阿赖实用javascript控件程序"可能是一个包含了一系列用于简化网页开发的JavaScript库或者组件集合。这些控件可能涵盖了表单处理、数据展示、用户界面元素等多个方面,旨在提高开发效率和用户体验。 在JavaScript中...

    JavaScript日期控件01(日期选择器)

    JavaScript日期控件是一种常见的前端开发元素,用于在网页上提供日期选择功能,用户可以方便地选取日期,常用于表单填写、事件安排等场景。在这个案例中,我们关注的是一个名为"JavaScript日期控件01(日期选择器)...

    单据控件开发使用手册

    4. **开发技术**:单据控件的开发可以基于多种技术,如HTML5、JavaScript(配合库如jQuery或React)、WPF、WinForms、JavaFX等。开发者需要熟悉相应技术栈,理解其事件处理机制和数据绑定原理。 5. **数据绑定**:...

    JavaScript开发的日期控件

    这篇内容我们将深入探讨如何使用JavaScript来开发各种日期控件。 1. **基础日期处理** JavaScript中的`Date`对象是处理日期和时间的核心。你可以通过构造函数创建一个新的`Date`对象,或者使用现有的日期和时间。...

    javascript 日期控件

    JavaScript 日期控件是网页开发中常用的一种交互元素,它允许用户在网页上方便地选择日期,常用于表单填写、日程安排等场景。在本案例中,我们有两个文件:`date.html` 和 `setday.js`。前者是HTML页面,后者是...

    TridiumNiagara4控件开发参考手册.rar

    4. **控件设计**:详细讲述如何使用AX或JX创建自定义控件,包括控件的布局、样式、图标以及与用户交互的方式。 5. **数据绑定和模型**:讨论如何将控件与Niagara 4的数据模型绑定,以便显示和操作实时数据。 6. **...

    javascript时间选择控件

    总的来说,JavaScript时间选择控件是Web开发中的一个重要工具,它结合了JavaScript的动态功能和CSS的视觉设计,为用户提供了一种直观且方便的方式来输入日期和时间。这个压缩包中的资源提供了一个实际应用的例子,有...

    阿赖实用javascript控件程序使用教程

    总的来说,"阿赖实用javascript控件程序使用教程"是一份有价值的资源,对于想要提升JavaScript交互控件开发技能的开发者来说,无论是初学者还是有一定经验的开发者,都能从中获益。通过深入学习和实践,你不仅可以...

    javascript 经典tab控件

    在实际开发中,创建一个JavaScript Tab控件通常涉及以下几个关键步骤: 1. **HTML结构**:首先,我们需要构建一个基础的HTML结构,包含一组可切换的标签和对应的内容区域。每个标签都是一个链接,而内容区域则隐藏...

Global site tag (gtag.js) - Google Analytics