zoukankan      html  css  js  c++  java
  • HTC编程思想

    1.摘要
    本文在实例的基础上讨论了HTC(HTML Component)的编程方法,提出了一种编写脚本组件的基本模式。

    2.目标读者
    HTML开发人员,脚本开发人员,系统分析人员

    3.背景知识
    HTML, DHTML, CSS

    4.引言
    HTC(HTML Component)直译为HTML组件,并不是一项新技术。可是说谈不上是一门技术。实际上只是IE浏览器内置的一种脚本封装机制。由于讨论的人很少,而Microsoft也没有什么技术支持,故而应用的人很少。但是HTML有着很好的特性可以使我们的开发工作高效。并且你有可能发现,HTC或许可以改变你以往开发应用的方式。

    在MSDN online对HTC的定义仅如下几句:
    HTML Components (HTCs) provide a mechanism to implement components in script as Dynamic HTML (DHTML) behaviors. Saved with an .htc extension, an HTC is an HTML file that contains script and a set of HTC-specific elements that define the component.
    (HTC是由HTML标记、特殊标记和脚本组成的定义了DHTML特性的组件.)

    一般而言,HTC是组件化了的脚本过程。尽管引入浏览器的机制不同,但遵循相同的SDK规范。无论是脚本运行环境,还是DOM文档结构。但HTC有着极高的扩展性。也就是说,HTC可以为我们的HTML引入高级的自定义行为(behavior)。例如自定义的attribute, method, 或者事件。这就说明,我们可以使用HTC机制来开发一个有着高级特性的,可重用的,可扩展的组件。

    5.实例
    为了使篇幅不会太大,我们设想一个实例。话说有一天你的项目经理找到你,说客户不满意我们的项目中的用户UI设计,因为我们的客户是比较有审美情趣的人,讨厌那些windows样式的灰秃秃的按钮。所以要你设计一系列平面的,而且能随着鼠标变化颜色的按钮。你说这没问题,但是需要一天时间,不出意料地使你的项目经理惊讶之后,你解释到以你的技术水准,不可能写一堆脚本和CSS class到HTML里,你的产品一定是reusable, flexiable, 和extendable的。他答应了。于是第二天,你交给他如下源代码:

    ButtonStyleFlat.htc:
    另外有一个sample用于参考:
    sample.html:
    (分别见以下文本框)
     
    ButtonStyleFlat.htc:
    <PUBLIC:COMPONENT>
    <PUBLIC:ATTACH EVENT="ondocumentready" ONEVENT="DoInit()" />
    <PUBLIC:ATTACH EVENT="onmouseover" ONEVENT="DoMouseOver()" />
    <PUBLIC:ATTACH EVENT="onmouseout" ONEVENT="DoMouseOut()" />
    <PUBLIC:ATTACH EVENT="onmousedown" ONEVENT="DoMouseDown()" />
    <PUBLIC:ATTACH EVENT="onmouseup" ONEVENT="DoMouseUp()" />
    <PUBLIC:ATTACH EVENT="onclick" ONEVENT="DoClick()" />

    <PUBLIC:PROPERTY NAME="ColorOver" />
    <PUBLIC:PROPERTY NAME="ColorOut" />
    <PUBLIC:PROPERTY NAME="ColorDown" />
    <PUBLIC:PROPERTY NAME="ColorUp" />
    <PUBLIC:PROPERTY NAME="Scheme" />

    <PUBLIC:EVENT NAME="onPush" ID="push"  />

    <PUBLIC:METHOD NAME="showMessage"  />

    <script>
    function DoInit(){
        
    switch(Scheme)
    {
            
    case "Normal"
    :
                
    if(ColorOver==null) ColorOver=
    'Orange';
                
    if(ColorOut==null) ColorOut=
    'RoyalBlue';
                
    if(ColorDown==null) ColorDown=
    'Black';
                
    if(ColorUp==null) ColorUp=
    'YellowGreen';
            
    break
    ;
            
    default
    :
                
    if(ColorOver==null) ColorOver=
    'Orange';
                
    if(ColorOut==null) ColorOut=
    'RoyalBlue';
                
    if(ColorDown==null) ColorDown=
    'Black';
                
    if(ColorUp==null) ColorUp=
    'YellowGreen';
        }

        
            runtimeStyle.borderWidth
    ='0px';
            runtimeStyle.textAlign
    =
    'center';
            runtimeStyle.padding
    ='3
    ';
            runtimeStyle.verticalAlign
    =
    'bottom';
            runtimeStyle.color
    =
    'white';
            runtimeStyle.cursor
    =
    'hand';
            runtimeStyle.background
    =
    ColorOut;
            runtimeStyle.unselectable
    =
    'on';
    }


    function DoMouseOver(){
        runtimeStyle.background
    =
    ColorOver;
    }


    function DoMouseOut(){
        runtimeStyle.background
    =
    ColorOut;
    }


    function DoMouseDown(){
        runtimeStyle.background
    =
    ColorDown;
    }


    function DoMouseUp(){
        runtimeStyle.background
    =
    ColorUp;
    }


    function DoClick(){
        push.fire();
    }


    function showMessage(){
        alert(
    "showMessage run."
    );
    }

    </script>
    </PUBLIC:COMPONENT>

     
    sample.html:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    <html><head><title>Sample</title>
    </head><body bgcolor=#ffffff>
    <button id=oButton style='behavior: url(ButtonStyleFlat.htc)'>push me please</button>
    <script>
    oButton.onpush
    =function(){
       oButton.showMessage();
    }

    </script>
    </body>

     
    6.分析
    让我们看看所完成的工作。我们把ButtonStyleFlat.htc和sample.html放在一起。我们打开sample.html, 效果如图:
     
    图1:实际效果图
    (图像不可见)

    我们发现button变平了,而且鼠标经过,移开,按下,弹起动作时颜色都会发生变化,而且仔细看脚本会发现,我们可以handle一个onpush事件和调用showMessage()方法。
    这一切的变化都来自style='behavior:url(ButtonStyleFlat.htc)', 一个behavior声明。而不用在HTML中写任何脚本。我们不探讨behavior的用法,仅仅讲解如何开发一个完整的HTC。

    一个完整的HTC由两个部分组成:我们把它们叫做API声明和脚本实现。API声明由以下部分组成:
    a. PUBLIC:COMPONENT
    这一部分组成了HTC的最外围元素。仅仅定义了所包容的内容是一个组件
    b. PUBLIC:ATTACH
    本部分定义了对于客户事件的处理
    c. PUBLIC:PROPERTY
    公开的属性定义
    d. PUBLIC:EVENT
    公开的事件定义
    e. PUBLIC:METHOD
    公开的方法定义

    由于本文仅仅是一个tutorial, 仅分析使用到的语法, 更多规范可以参考MSDN文档:
    ms-help://MS.MSDNQTR.2004JAN.1033/Behavior/workshop/components/htc/reference/htcref.htm
    (地址可能需要修改)
    或者联机版本:
    http://msdn.microsoft.com/workshop/components/htc/reference/htcref.asp?frame=true
    (以下规范基于IE5.0及以上版本)
     
    PUBLIC:ATTACH
    表示绑定事件与处理过程
    EVENT: 表示事件句柄名
    ONEVENT: 表示处理过程名
    PUBLIC:PROPERTY
    表示公开到环境的属性
    NAME: 属性名
    属性可设置类似C# property的读写器, 分别是get和put过程. 设置属性之后, 可使用HTML语法指定组件的属性值为任意值。

    PUBLIC:METHOD
    公开到环境的方法
    NAME: 方法名
    PUBLIC:EVENT
    可由环境catch的事件
    NAME: 事件名
    ID: 内部引用名称
    脚本实现

    API声明仅定义了组件公开到环境的编程接口, 在组件中需要使用脚本来实现内部逻辑. 脚本实现主要有以下部分:
    1. 定义事件处理过程
    2. 定义PROPERTY的取设过程
    3. 定义METHOD的具体实现
    4. 定义EVENT的引发逻辑
    5. 其他内部过程

    其中EVENT的引发一般在其他过程中进行. 而脚本的语法与普通HTML页上的脚本没有什么不同.

    7.实例讲解
    以上的Button Style Flat虽然很短小, 但可以基本说明本文的中心内容, 即HTC编程思想. 我们接着看上面提供的实例:

    a. 在第一行我们注意到, 改实例将ondocumentready事件交给了一个OnInit()的脚本过程处理(ATTACH语法). Ondocumentready是component特有的事件. 表示当表示component的前端HTML完全载入的时刻.可以说ondocumentready事件是components初始化时的过程. 在我写的所有HTC中, 都ATTACH了这个事件. 这一习惯不知道从什么时候开始的. 慢慢我发现不能离开ondocumentready了. 只要我们的HTC中需要一个类似初始化的过程, 我们就需要指定ondocumentready时刻发生的过程. 在本实例中, 我们在ondocumentready所绑定的过程中初始化了button的最初样式. 即根据schema特性决定button的外观.

    b. 定义一组鼠标事件. 一般而言, 我们的component都是可见的. 而HTML页中与用户交互的主要动作是鼠标的
    动作. 所以, 通常情况下, 我们总是会deal鼠标的五个基本事件mouse over, mouseout, mouse down, mouse up 和click. 同样是一个习惯, 我通常不加考虑的ATTACH 这五个事件. 即使绑定的过程是空的.

    c. PROPERTY, 可以定义get和put过程做属性的取设器. 一般情况下都可以省略这两个过程. 除非要对设置的值进行合法性校验.

    d. EVENT的引发. PUBLIC:EVENT声明的ID attribute用于script部分的内部引用. 当需要引发该事件时, 仅需要使用类似: push.fire()命令就可以. 环境就是开始准备catch该事件. 相当简单.

    e. METHOD实现. METHOD的name attribute直接代表<script>部分的函数名. 因此可以直接声明一个同名的function. 可以有返回值, 也可以没有返回值. 在本实例中我们仅仅发出了一个客户端消息.
    注意, 实例中的push事件和showMessage()方法都是没有什么实际意义的. 放在实例中仅仅为了说明编程方法.

    8.总结
    到这里为止, 我们可以总结一下简单模式下, 我们可以做的工作: 如何创建一个有效的HTC组件
    a. ATTACH ondocumentready事件, 在过程中实现初始化时的步骤.
    b. 分别ATTACH鼠标的五个基本事件. 如果该组件设计了键盘事件, 也进行同样的绑定过程.
    c. 如果组件设计了特定的客户端事件, 仅需要定义并且在需要的时候引发.
    d. 特定的METHOD语法也很简单. 仅需要声明一个METHOD, 并且在SCRTIPT部分实现同名函数即可.
    e.考虑更复杂和实用的应用

    button实在是太简单和太不值得一提了. 我们来考虑一个很受欢迎的东西: treeview. 一个所有web开发人员都非常热爱的东西.

    我们知道, 现在实现treeview的方法很多. 多美观, 多实用的都有. 我们给自己提出需求, 来看一看用HTC如何设计一个好用而且节省成本的treeview.

    需求
    可以使用客户端数据填充其内容; 外观与windows 资源管理器一致; 可以catch到expand/collipse事件; 可以catch到节点的click事件; 可以定义节点展开/收缩的模式(记忆模式); 可以由接受环境指令expand/collipse指定的节点.

    分析
    如果以上需求都可以实现, 那么将是一个非常"高级"的treeview了. 我们逐一分析上述需求:

    1. 使用客户端数据填充: 既然是treeview, 则必然由节点构成. 既然是节点, 就必然体现一定的数据. 而数据的由来一般情况下是由后端传送来的. 这就要求我们最好使用一种数据格式. 不需要更改, 在后端和前端都可读. 一般朋友都会想到用XML. 这是很好的想法. 这样, 我们的treeview必须能够按照一定的规则读取XML数据. 将节点解析出来, 并且使用一定的输出方法输出目标HTML形成带有图标, 文本, 节点线的外观. 这样过程一般在OnInit()过程中进行.

    2. expand/collipse事件. 有时候环境需要了解treeview的状态. 例如展开某个节点是自动显示某些内容. 因此环境必须随时了解treeview里发生了什么. 这样需要我们分别定义expand/collispse事件. 在某些情况下自动地引发他们.

    3. 节点的click事件很重要. 一般情况下, 用户单击某节点是总是会期望得到什么.

    4. 设定展开/收缩的模式. 我们可以指定treeview是否自己记住展开的节点的状态. 而有些情况下我们希望treeview不会太长而希望不准同时展开两个节点. 这需要我们定义一个PROPERTY. 可以通过HTML attribute或者script设定该值从而影响compenent的behavior.

    5. 接受环境指定改变节点状态. 如果我们希望不经过用户操作而自动打开某节点(不经过页发回), 希望通过环境的script命令操作treeview. 我们可以定义一些列METHOD, 例如expandNode(id): 展开指定id值的节点.
    这样, 我们就开发了一个有着高级特性的treeview component. 而且该组件的重用性是很高的. 我们只需要在HTML中插入一个特定的标记, 类似<Timeline:Treeview ><xml data…. /></Timeline:Treeview>. 你的 HTML页就会出现一个非常漂亮的树型目录了.

    结束
    本文论述了开发HTC的一般性方法. 作者希望可以通过本文, 使广大web工作者认识到HTC的优势. 以期待可以抛砖引玉, 得到遍地开花的美好结果.


    作者发现经常有朋友转载文章而不说明出处. 作者欢迎转载, 但同时希望得到应有的尊重.
    本文最初发于博客园(http://www.cnblogs.com)之春鱼文集(Jay's Blog)(http://www.cnblogs.com/jayxu).
     
  • 相关阅读:
    【BZOJ 4581】【Usaco2016 Open】Field Reduction
    【BZOJ 4582】【Usaco2016 Open】Diamond Collector
    【BZOJ 4580】【Usaco2016 Open】248
    【BZOJ 3754】Tree之最小方差树
    【51Nod 1501】【算法马拉松 19D】石头剪刀布威力加强版
    【51Nod 1622】【算法马拉松 19C】集合对
    【51Nod 1616】【算法马拉松 19B】最小集合
    【51Nod 1674】【算法马拉松 19A】区间的价值 V2
    【BZOJ 2541】【Vijos 1366】【CTSC 2000】冰原探险
    【BZOJ 1065】【Vijos 1826】【NOI 2008】奥运物流
  • 原文地址:https://www.cnblogs.com/ZetaChow/p/2237380.html
Copyright © 2011-2022 走看看