Html5 组件开发指南

wangyanwy0209 贡献于2014-07-11

作者   创建于2012-08-08 07:40:17   修改者  修改于2012-09-11 03:16:29字数12783

文档摘要:Html5组件目标性能:web程序的html和js运行时要渲染和解释,因些比c编译产生的本地程序执行略慢,页面越复杂差距越明显;html5和css3为了改善这种状况提供了很多新的技术手段,组件要利用这些技术,去提升ui交互体验;设计也是提升用户体验的一种有手段。规范:js做为动态言语有很好的灵活性,但也缺少静态语言的规范性能,在做大规模项目时经常带来维护和扩展的问题;html和css不是程序员的强项,有时可以用css很简单做到,却写了大量js脚本来实现;
关键词:

Html5组件开发指南 Html5组件目标 性能: web程序的html和js运行时要渲染和解释,因些比c编译产生的本地程序执行略慢,页面越复杂差距越明显;html5和css3为了改善这种状况提供了很多新的技术手段,组件要利用这些技术,去提升ui交互体验;设计也是提升用户体验的一种有手段。 规范: js做为动态言语有很好的灵活性,但也缺少静态语言的规范性能,在做大规模项目时经常带来维护和扩展的问题;html和css不是程序员的强项,有时可以用css很简单做到,却写了大量js脚本来实现;为了应对这种情况组件要提供js、css、html全面的规范,应用开发时只需要选择已有的组件就可以,而不必陷入css等细节问题。以文档和打包工具来保证规范。 效率: 为了提高应用开发效率,要提供足够数量的组件,对常见场景进行封装,以便重用;探索项目最佳实践,提供示例程序和文档,保证应用项目性能和结构的优良。 扩展: 易扩展,易重用,结构保证扩展功能不影响性能。 为了实现以上目标曾经尝试过requirejs+jquery+backbone+twitter-bootstrap的轻量级组合,具有良好的加载性能,但是其它方面工作量和难度都大,例如平衡各种框架风格形成模块规范、数据的统一模型、不同插件间代码重用、插件功能扩展对性能的影响。 使用dojo不存在以上问题,统一的代码风格和类机制使dojo使用起来更像java,独有的声明式组件用法能促进规范提升开发效率;各种组件具有统一的数据模型;组件数量丰富,层次结构先进,在核心库基础上形成基础组件库和扩展组件库,并且具有基于LESS的风格管理,支持国际化;强悍的打包工具用以保证规范,提升加载性能;其它的一些优势:文档丰富、周边工具丰富、许可证宽松、大量使用html5的技术。 使用dojo最大的问题是性能,因为类库规模庞大,性能必然受到影响,解决的方法是按照特定的方法使用组件,这些方法是经过设计和验证的,不会造成性能问题。 后面会逐一介绍针对金融应用对dojo组件进行的定制和扩展,以及在应用中的特定用法和一些常见问题的解决方法。 Dojo入门 详见另外的文档 ------- Dojo入门.doc 、 Dijit组件系统基础架构.doc 注意:采用dojo 1.7以后的用法,各种文档和资料中的1.7以前非AMD用法不采用,包括官方文档和示例,很多采用旧格式,还没有更新。 // Dojo 1.7+ (AMD) require(["dojo/_base/array", "dojo/query"], function(array, query){ array.forEach( query("select") , function(selectTag){ selectTag.disabled = true; } ); }); // Dojo < 1.7 dojo.forEach( dojo.query("select"), function(selectTag){ selectTag.disabled = true; }); 组件继承体系 Dojo 提供的类继承机制可以通过继承一些特定的基类,方便地扩展出一个标准的 Dijit 控件。这些基类抽象了一个 Dijit 控件所需的底层功能,大大方便了新控件的开发。 需要注意的是,Dojo 的继承机制与 Java 有所不同,它支持多重继承,因此一个 Dijit 控件往往也继承了多个父类。如dijit.form.Select 控件: dojo.declare( // 控件名 "dijit.form.Select", // 父类 [dijit.form._FormSelectWidget, dijit._HasDropDown], { // 成员属性 baseClass: "dijitButton", templateString: dojo.cache("dijit.form", "templates/Button.html"), ... // 成员方法 buildRendering: function(){...}, reset: function(){...}, _onClick: function(/*Event*/ e){...} ... }) Dijit 控件一般都需要由以下基类来支撑:dijit._WidgetBase,dijit._Templated,dijit._CssStateMixin 等   其中最底层的基类是 dijit._WidgetBase。所有 Dijit 包中的控件都继承于它。在这个类中定义了一个标准 Dijit 控件的基本创建流程。大多数 Dijit 控件在继承 dijit_WidgetBase 这个基类之外还继承了 dijit._Templated。故名思意该基类为控件提供了模板功能。dijit._CssStateMixin 也是大部分 Dijit 所继承的基类。它会监听控件的一系列属性,如"disabled","readOnly","checked","selected","focused", "state","hovering","active"等。当这些属性发生改变时,控件 DOM 节点上的某些 CSS class 名会被同步修改,从而反映出控件的当前状态。此外,该类还在控件创建的过程中为其鼠标事件(mouseenter, mouseleave, mousedown)绑定了回调函数。该回调函数监听用户的鼠标操作,并及时更新控件的"hovering"、"active"属性,最终对其 DOM 节点上的 CSS class 进行修正。 组件声明 Dijit 控件是面向对象的,每个 Dijit 控件都是由 dojo.declare 方法声明的一个类,控件类的声明方式与声明一个普通的 Dojo 类并没有什么区别,只是承了一些特定的基类。Dojo 的代码风格规定以下划线"_"开头的方法为对象私有,然而这仅仅是代码风格上的要求,用户在使用时仍可直接调用 Dijit 控件的这些方法(但不推荐)。前面的代码声明了一个 dijit.form.Select 类,在创建该控件对象时,只需通过 new 关键字进行实例化即可。 new dijit.form.Select({ name: 'select2', options: [ { label: 'TN', value: 'Tennessee' }, { label: 'VA', value: 'Virginia', selected: true }, { label: 'WA', value: 'Washington' }, { label: 'FL', value: 'Florida' }, { label: 'CA', value: 'California' } ] } , "selectId"); 另一种用法是利用解析HTML来生成组件: 实际使用中HTML标签可以自然的表示位置包含关系,代码方式需要标签或另外的容器对象;代码方式不需要解析,性能好一些。 实例化流程  在实例化一个控件时会自动执行以上步骤:其中以下三个方法以供覆写。 postMixinProperties:此时控件对象生成完毕,但还未向全局进行注册,且 DOM 节点还未构建。可以通过覆写此方法为控件初始化一些额外的资源。 buildRendering:控件需要实现此方法来为已注册好的控件对象构建 DOM 树。 postCreate:此时控件已经创建完毕,且已绘制到页面中。可以通过覆写此方法来对控件节点进行最后的调整,如绑定事件的回调函数等。 操作组件 在创建 Dijit 控件之后,用户可以通过 dijit.byId、dijit.findWidgets、dijit.byNode、dijit.getEnclosingWidget 等方法获取控件实例。 // 获取 widget id 为 programmatic 的控件 var widget = dijit.byId("programmatic"); // 获取 body 标签下的所有控件 var widgets = dijit.findWidgets(dojo.body()); // 获取 DOM 树根节点为以 node 的控件 var widget = dijit.byNode(node); // 获取 DOM 树中包含 node 节点的控件 var widget = dijit.getEnclosingWidget(node); 获取控件实例之后可以像使用Java 类那样调用控件方法,并使用 get、set 方法来获取/设置控件的属性。 // 调用控件方法 widget.someMethod(); // 使用 get 获取控件属性 var value = widget.get(attributeName); // 使用 set 设置控件属性 widget.set(attributeName, value); 这是因为 dijit._WidgetBase 这个基类为控件实现了 get/set 方法。在调用这两个方法时,如果控件是实现过对应的 _getAttributenameAttr/_setAttributenameAttr 方法 (Attributename 为首字母大写后的属性名 ), 则会调用这两个方法,否则便直接使用默认方法获取/设置控件属性。借助这一特性,可以为某个属性定制其获取/配置方法。 应用定制 应用代码快速概览:                Dojo - TodoMVC                                 dojoConfig = {               async:true, parseOnLoad:false,                paths:{'demos':'../demos'},                //noscale:true, _baseW:900,_baseH:550,               //locale:'en', //放开测试国际化               deps:["dijit/dijit-all",'dojox/slickgrid/slickgrid',      'dojox/widget/TitleGroup','dojo/data/ItemFileReadStore'],               callback: function() {                   require(['demos/todo/src'],function(main){main();});               }           }                                          
           
                          
               
           
               加载 要求应用达到在一秒内显示界面(库加载500毫秒左右,解析200毫秒左右,数据处理及网络时间根据实际情况采用优化策略)。 以上头部代码形式固定不变,不再引入其它文件。 组成部分:页面,主逻辑文件,自定义组件 打包程序优化加载过程,同步与异步兼有。 官方文档和示例,很多采用旧格式或者只为演示功能。官方demo改为1.7以后写法的不多,很多示例性能达不到我们的要求。 缩放 配置整体是否缩放noscale:true,缩放的基数: _baseW:900,_baseH:550,  缩放定义成模块,类似一个对象公开接口,把变化控制在模块内,而不影响其它组件,例如加一个noscale配置,不用把有组件去改。弹出位置的计算,用缩放模块。 打包工具 定制dojo打包,将常用的拖拽、数据、组件支持等打包dojo.js,所有基础组件指导包到dijit.js,图形、表格、k线等扩展组件单独打包,dojo.js与dijit.js之间是同步加载,扩展组件之间是异步加载。 应用也要打包,所有自定义组件和模板都被打包到指定文件里,即src.js,统一使用这个名字,方便以后自动为应用打包。应用可以在代码不变的情况下,在src目录下调试,在release目录下测试发布的真实效果。在src目录的dojo的代码都是源码,方便调试。 样式主题也是被打包过的,开发时只要选择文件就了,不需要修改样式。 不规范的脚本不打包,例如多个逗号,全局变量改变位置造成代码不能执行 基于has()的功能检测:这使得为特定浏览器打包(移除该浏览器不需要的功能,例如一些针对IE的特殊代码)成为可能。 ContentPane 的href指向文件不打包,自定义组件的模板会被打包到应用的js文件里。 自定义组件 采用自定义组件可以解决组件解析前页面显示乱,前后不一致。 自定义组件模板中去除第一次不显示的组件声明、数据组件异步创建、采用程序创建组件都可加快页面渲染速度,使应用更快的呈现出来。 Dojo规模很大,代码结构要靠对象技术来控制,不造成混乱的依赖。类、模块、组件都有明确的职责。不能随意把生命周期方法名改掉,例如扩展库dojox.charting 图形组件,规模宠大功能多,无法全面测试,保持对象概念不变才行,改掉一个叫refresh的方法,不能马上知道影响,要真正运行到那段代码才知道,不像java静态类型语法工具可以很容易指示出问题。功能扩展时提倡继承,而不是修改原来的类。继承也不能过度使用,也要看情况,有时组合更合适,不能因为layout有处理resize,就把表格写成继承自布局组件,造成不必要的生命周期方法执行和依赖,影响同步官方升级。 每个组件都可以用声明式和程序式两种方式创建,声明式简洁方便,程序式不需要解析,所以创建快些。两种方式根据不同场景结合使用。实际使用中比如几个对话框五六十行模板的解析大概要五十毫秒。一个应用文件加载大概五百毫秒多些,主要显示组件解析大概要二百多毫秒,如果对话框比较多使一个应用显示出来超过一秒的情况,建议把对话框等第一次不显示内容做成另外的组件模块,通过事件由程序式创建。虽然也要解析模板,但二百毫秒的影响在显示一个对话框时就不明显了。 自定义组件包含布局组件的情况自定义组件需要继承_ContentPaneResizeMixin,并且在模板最外层div里指定data-dojo-attach-point="containerNode",才能使布局组件正常展示。 模板里组件不能用data-dojo-attach-event属性,HTML标签可以用。 不提倡在代码中拼HTML字符串,也不在HTML里写代码;需要结合使用用模板data-dojo-props="label:'${label1}'"和data-dojo-attach-point等技术。 组件ui部分依赖于数据,数据不应依赖于ui,所以把ui对象传入数据模型对象,并在数据对象方法里操作是不规范的做法。 应用主界面分为几大块由自定义组件来实现,逻辑代码可以写在定义组件里,也可以单独写成模块;对话框等初次不显示内容也有逻辑,如用href方式则没地方写逻辑代码,可以根据需要定义组件来写逻辑.也可以纯代码方式生成对话框. 组件有生命周期方法,不要直接操作生成的dom,应获得组件对象后调用其自身方法。 扩展时生命周期里的方法不改变输入和输出,不要改变方法对应的含意,让方法里的代码做与命名含义不同的其它事情.比如 domStyle 相关在buildRendering里而不是postcreate css规范or表格布局 提供hbox、vbox样式来进行水平和垂直布局,对布局元素可以根据需要设置不同的高度或宽度比例,通过嵌套可以满足各种布局需要。 dojox.layout.TableContainer组件来提供了类似html的table的功能,可以根据需要选择,例如显示一个复杂不规则的表单页面。建议更多的使用hbox、vbox样式,因为性能好,除非布局复杂不规则需要的嵌套太多,非常不方便使用。 简单情况可用hbox、vbox样式代替BorderContainer,性能更好。 统一数据接口 详见文档------------统一数据接口.doc 全局对象控制 1.7以后全局对象主要有require、define、dojoConfig,其它API以模块方式使用,而不建议直接使用dojo、dijit来调用。 require(["dojo/_base/window","dojo/_base/connect"], function(win,connect){ var currentBody = win.body(); // Dojo < 1.7 You can also use: dojo.body() . var newText = win.doc.createTextNode("Some text"); currentBody.appendChild(newText); connect.connect(win.global, 'onresize', function(){ Console.log("window resize"); }); }); 另一个使用dojo不习惯的想法,不习惯用define定义模块,想像原来那样把函数写在一个文件里,在任何地方都可调用。这种情况在大规模合作开发时是不安全的,想想java是没有全局函数的,dojo和java一样,java处理这种情况会写一类,再调用这个类,dojo是用define定义一个模块,然后用require引入再调用,这个模块可以是declare类、function函数、Object对象,这些都是概念上的,本质上没什么区别。 国际化 通过定义国际化资源文件,可切换不同语言版本的应用,详见Todo示例。 内容组件自适应 默认的窗口大小的1272*678,每一行高度是25px,具体来说就是一个树结点,一个按钮,一个下拉,表格的一行,水平分割条的高度都是25px。这样从上到下一共是27行内容。这个可以通过修改缩放的基数:_baseW和_baseH来改变,缩放的效果会不一样。 表格的外面要ContentPane来决定它在布局里的大小,ContentPane大小可以由vbox的方式来解决高度的自适应需要:占满剩余空间,初始大小会随收缩等布局组件调整. 树的外面要ContentPane来决定它在布局里的大小,它才能正常的显示滚动. 表格图高度宽度走容器,单一位置设置,减少出错机率,适合html特点,style方便,尽量不在组件上设置高宽 使用适合的技术,例如表格抬头居中的解决方案使用hbox样式来实现,性能好,具有通用性能,而用js计算line-height的方式则比在合并、多层等各种抬头时不够灵活,各种计算要写很多代码,性能不如样式。所以要分清问题的属性,样式问题CSS解决有优势。 当拖动分割条,或收缩左侧或上侧时,布局里面的组件的resize会自动调用。所以一个页面上的组件外边一定要有布局组件。一般是内容组件会有resize,包括表格,图型,还有布局组件本身,例如嵌套的页签等。 主题风格 现在具备套风格,切换方式如下: 黑色样式: 蓝色样式: 基于LESS结构书写的CSS,方便创建新风格,详见文档-------------dojo主题风格.doc 深度链接 可以从外部链接并直接到达应用的任何组件界面,并可进行前进和后退的导航,基于router实现,实例演示见主题投资库示例。 基础组件 树形组件:2种 1.菜单项可配置多个父节点。也能配置图片。 2.带复选框的树(checkBoxTree):checkbox 选中子节点,父节点菜单项会有第三种状态。 日历组件:Calendar 年份可选择上一年,下一年。月份也能选择上一年,下一年,并可以下拉选择月份。 颜色选择器组件:ColorPalette 默认提供一套7x10 大小的颜色选择器。可配置大小。每个颜色小方块给出title颜色提示。 Form容器组件:Form Form表单提交组件。里面放置各种表单控件,方便做验证。 按钮组件:2种 1.普通按钮(button):有3种大小按钮,指定style里的font-size.分别是small(21行高)default(25px行高)large() 2.带下拉菜单按钮:DropDownButton:按钮和下拉箭头作为整个按钮在一起。 复选框组件:CheckBox 单选按钮组件:RadioButton 选择框控件:4种 普通下拉(select):普通下拉文本框不允许编辑。但弹出的下拉里的内容项可配置样式 如:大小,字体,颜色等等。 带自动提示的下拉(comboBox):此文本框可以编辑,并自动提示。 带错误提示的下拉(FlteringSelect):不输入或者输入错误的匹配项会弹出错误提示。 双向多选框(MultiSelect):在两个选择框里,按住ctrl 或shitt 可选择多个项。 文本输入控件:7种 文本输入框(TextBox):用于文本输入,可配置大小,长宽等。 数值增减的文本框(NumberSpinner):放置数值,如年份。点击上下箭头,增减数值。 数字文本框(NumberTextBox):只能输入数值,输入其他会出现错误提示。并可指定 数值格式。以及最大最小。 格式验证文本框(ValidationTextBox):如只能输入有限字符。不允许有空格等等。 下拉日期文本框(DateTextBox):弹出下拉日历,供选择日期。 文本区域组件(Textarea):文本区域输入框组件,大小随输入变化。 文本区域组件(SimpleTextarea):输入时大小不变,可拉拽右下角改变textarea大小 行内编辑组件:InlineEditBox 以文本框形式高亮显示文本框所在行,并可以编辑。自动保存。也可以配置保存和取消按钮等。 页面布局组件:BorderContainer 控制整个页面的整体结构的布局组件。 容器组件:ContentPane 用于页面布局,contentPane存放各种内容和组件。 折叠菜单容器组件 :AccordionContainer 折叠菜单展开项里放置各种常用组件,比如树,超链接等. Tab页签选项卡组件:TabContainer 选中某一页签,显示这一页签对应区域的内容。 页签超过Tab容器组件宽度会出现向左,向右两个箭头按钮用来滑动页签,页签可配置为关闭。 页签容器:StackContainer Tab的父类,只显示多个子容器中的一个;与Tab相比,控制条比较灵活,可以放在任意位置,也可以没有。 超链接容器组件:LinkPane 类似于ContentPane,区别是title属性取自标签内容。 TitlePane组件:TitlePane 开展开和收缩的容器组件,用于放置文本内容和各种小组件。 工具条组件:ToolBar 放置各种图片小按钮和表单小组件。 菜单组件 1.菜单栏(MenuBar):可以添加下拉菜单,以及禁用菜单栏里某一单项。 2.菜单(Menu):可以添加菜单项。可以显示为右键菜单。 3.菜单项(MenuItem):菜单项可配置图片,并可展开二级 三级项,展开项包括日历,颜色选择器等小组件。可禁用单个菜单项。下拉菜单项可配置图片和checkBox复选框。 对话框组件:Dialog 弹出可供拖动的对话框,对话框里可放置布局容器组件或者小组件和内容。 提示信息组件:Tooltip 供链接,文字,图标,组件等弹出提示。 提示对话框组件:TooltipDialog 给文字,组件等弹出一个提示框,放置文本内容或者小组件。 扩展组件 图形组件 见文档---------图形组件使用说明手册.doc 表格组件 见文档-------- 导航组件 dojox/widget/TitleGroup控制只打开包含的一组多个TitlePane中的一个 参考知识点 Dojo常用函数 见文档---------常用函数简介.doc parserAutoRequire 1.8新特性 写法上以“/”代“.”:
并且自定义组件模板里还不支持此特性。 BorderContainer定制分割条 (TabContainer类似的具有定义页签控制条的功能) 注:以下代码的div属性用法为过进用法,新用法是以data开头的html5自定义属性
Declaration
${name} update delete
XXXXXX
YYYYYY dojo/connect与dojo/method声明式用法与事件 与 按钮支持自定义样式,很多组件都提供扩展接口。 HTML5拖拽无插件 HTML5的自定义属性 Dojox扩展包中提供dojox.mvc和dojox.app
下载需要 10 金币 [金币充值 ]
亲,您也可以通过 分享原创文档 来获得金币奖励!

相关文档

下载文档到电脑,查找使用更方便

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 10 金币 [ 分享文档获得金币 ] 0 人已下载

下载文档