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.實例
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,發現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的優勢.

 


 

注:HTC有很好的思想,但由於其基於IE,不穩定。代碼複雜之後,會出現很多莫名其妙的BUG。

例如,MS IE WebControls中的TreeView,如果每個節點都帶一個小圖標,節點有上百個或者數百個,此時,就有可能出現莫名其妙的問題。爲此事詢問Microsoft,得到的答覆是,HTC中的圖片太多,導致過多圖片請求,需要修改IE在註冊表中的配置解決。Microsoft並且認爲不是BUG,而認爲只是一個需求缺陷。

一:我們使用複雜的客戶端技術處理一些邏輯,一定程度上就是爲了降低網絡訪問頻率。當帶寬不是問題的時候,複雜邏輯由服務端處理其實從整體上來看是比較合理的(安全性,可擴展性等)。因爲畢竟IE的Script runtime能力很有限。
二:ASP和ASP.NET在我看來主要區別中的一點就是:
      ASP基於HTTP的擴展與封裝做的很弱,他存在的價值就是COM的黏合劑。在MS平臺下使用ASP+COM/COM+完成靈活、交互複雜的系統還是很喫力的事情,當你的客戶端請求不想只侷限於FORM的get,post的時候,藉助HTC+Microsoft.XMLDOM/XMLHTTP就可以實現一些相對傳統ASP技術實現起來比較困難的功能,比如Http異步請求,頁面的局部刷新等等。所以HTC+Microsoft.XMLDOM/XMLHTTP對我來說的確在很大程度上彌補了ASP的不足。
     ASP.NET將http過程做了很不錯的封裝,ViewState幫助我們完成信息從服務端到客戶端的交互(不過也有若干缺陷),我們幾乎不需要在客戶端考慮Post的問題了。所以當ASP.NET使Client和Server之間的界限變得不是那麼硬的時候。Client的處理能力彷彿加強了。
     所以隨着ASP.NET出現,我沒有再像以前那樣把基於IE瀏覽器的客戶端技術看得過重。

HTC標準由微軟提出,運行在IE特定環境之下,微軟的支持與否對HTC的健康發展至關重要。

HTC是一個不錯的基於IE的組建模型技術,思想也很不錯。但是如果嘗試使用HTC去構建基於IE的Rich Client體系的話,存在着一定的風險。HTC做一些相對輕型的可重用組件還是不錯的。所以我們討論的只是HTC定位的問題,而非此種技術的好壞。
另:我從來沒有使用HTC訪問數據庫,也從來沒有在IE端直接訪問數據庫的經驗和經歷。我只是利用HTC封裝的組件處理Microsoft.XMLDOM從服務端Load的XmlStream,利用數據綁定做顯示,再通過Microsfot.XMLHTTP提交到服務端來完成最常見的數據CIUD工作。

我感覺隨着微軟下一代操作系統Longhorn對Internet支持的逐漸強大,Avalon做爲新一代界面框架將成使資源展現,搜索時所處的位置是本機還是網絡有所弱化。我沒見過Longhorn是什麼樣子,但我感覺到時候我們訪問internel上的資源,不管html,圖像,媒體。可以通過更多途徑。IE+DHtml的展現方式不會被取代,但更強大的Xaml將成爲Microsoft的主要方向。微軟對DHTML整個體系的支持都在減弱。

經驗是,不建議基於Web開發過於複雜的UI界面。因爲IE這個開發環境不夠可靠,而且微軟也不打算改進它。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章