|
這里對前面文章講的CSS設(shè)計(jì)器系統(tǒng)關(guān)鍵代碼作一些小結(jié),如果沒有看過前面文章的請先參看"開發(fā)基于Web的CSS設(shè)計(jì)器"
解析CSS樣式文件
這段代碼主要作用是把CSS文件分解為多個樣式類,并按名稱/文本屬性生成ClassItem對象,并保存在一個ArrayList(cssList)中(C#代碼)
//讀取文件 FileInfo theSource= new FileInfo (@m_filePath); StreamReader reader = theSource.OpenText(); //將文件流轉(zhuǎn)化為文本 m_cssText = reader.ReadToEnd(); reader.Close(); //定義CSS文本分割符 char[] delimiters = new char[] { '{','}'}; int iCheck = 1; string className = null; //將文本轉(zhuǎn)化為ArrayList foreach ( string substring in m_cssText.Split(delimiters)) { if (iCheck%2==0) //當(dāng)iCHeck為偶數(shù)時,字符串為樣式屬性內(nèi)容 //將解析的樣式名和屬性作為ClassItem對象存入cssList cssList.Add( new ClassItem ( className, substring.Trim() ) ); else //當(dāng)iCHeck為奇數(shù)時,字符串為樣式名,暫存 className = substring.Trim(); iCheck++; }
交互界面構(gòu)建
交互界面由Javascript通過XmlDocument讀取Xml文件動態(tài)生成。
首先要讀取XML文件,然后遍歷整個XML文件,先遍歷樣式分類,再對每個分類遍歷其下的所有樣式屬性。比較關(guān)鍵的代碼是對XML的遍歷,下面是對樣式分類的遍歷代碼。
//LoadXML是XML文件讀取函數(shù) var dom = LoadXML("css.xml"); //通過XPath和selectNodes方法返回一個XMLDOMNodeList對象 var oNode = dom.selectNodes("//Category/Name"); //獲取該對象長度,即XML文檔中該路徑節(jié)點(diǎn)的數(shù)量 var intCategory = oNodes.length; for (i=0; i<intCategory; i++) { //獲取集合中的節(jié)點(diǎn) oNode = oNodes.nextNode; if (oNode != null) { //樣式分類界面構(gòu)建代碼-略 …… } }
樣式輸入控件構(gòu)建函數(shù),該函數(shù)作用是根據(jù)XPath路徑查詢XML定義,生成交互控件
function BuildInput ( path ) { var str=""; var aNode=null; var attValue=null; //通過selectSingleNode返回符合條件的第一個節(jié)點(diǎn) var actNode = dom.selectSingleNode(path+"ActionType"); var nameNode = dom.selectSingleNode(path+"CssName"); //如果屬性為選擇輸入,則讀取SelectItems,并構(gòu)建select控件 if (actNode.text=="select") { str += "<select id='"+nameNode.text+"' name='"+nameNode.text+"' class='eSelect'>\n"; //查詢該項(xiàng)的所有選擇列表項(xiàng) var itemsNodes = dom.selectNodes (path+"SelectItems/Item"); str += "<option value='-1'>未設(shè)置</option>\n"; for (ii=0;ii<itemsNodes.length;ii++) { aNode = dom.selectSingleNode (path+"SelectItems/Item["+ii+"]"); //如果該項(xiàng)含有Name屬性則在列表中顯示Name屬性值 attValue = aNode.getAttribute("Name") var txtNode = dom.selectSingleNode (path+"SelectItems/Item["+ii+"]");
if (attValue==null) str += "<option value='"+txtNode.text+"'>"+txtNode.text+"</option>\n"; else str += "<option value='"+txtNode.text+"'>"+attValue+"</option>\n"; } str += "</select>"; } else //如果屬性為其他模式,則構(gòu)建input輸入,設(shè)置class屬性為ActionType { str = "<input name='"+nameNode.text+"' id='"+nameNode.text+"' class='"+actNode.text+"'>\n"; } return(str); }
設(shè)計(jì)器初始化
Js腳本讀取解析樣式元素的style屬性值,然后為設(shè)計(jì)器中構(gòu)建的控件賦值
//設(shè)計(jì)器初始化 function Init() { //獲得由服務(wù)器端賦值的樣式屬性值 var txt=document.all("DemoShow").style.cssText; if (txt.length>0) { var strClassName; //解析字符串 var aryClass = txt.split(/[:;]/); for( i in aryClass) { var str = aryClass[i].replace(/(^\s*)|(\s*$)/g, ""); if(!(i%2==1)) { //當(dāng)i為奇數(shù)時,解析的字符串應(yīng)該為樣式屬性名稱 strClassName=str; } else { //當(dāng)i為偶數(shù)時,獲得屬性值 //屬性名稱即控件ID //判斷該屬性對應(yīng)的控件是輸入框還是選擇列表 if(document.all(strClassName).type=="select-one") { //如果是選擇列表通過setIndexOfValue函數(shù)設(shè)定選擇項(xiàng) setIndexOfValue(strClassName,str); } else { document.all(strClassName).value=str; } } i++; } } }
界面交互
在XML中一共定義了select/input_ColorSelect/input_SizeSelect/input_BorderSelect(后3種為顏色/大小/邊框輸入模式)共4種輸入模式,除select為直接選擇外,其他在對應(yīng)控件初始化的時候作為class屬性賦值到控件中,類似class代碼如下
/* 顏色輸入模式input框的樣式類 */ .input_ColorSelect{ width:100px; font-family:Tahoma; behavior:url(htc/effColorSelect.htc); }
通過behavior屬性,把該輸入控件和相應(yīng)的組件相關(guān)聯(lián),該組件effColorSelect.htc代碼如下
<PUBLIC:ATTACH EVENT="onfocus" ONEVENT="getShow()"/> <PUBLIC:METHOD NAME="getChange"/> <SCRIPT LANGUAGE="JScript"> function getShow() { element.blur(); //記錄當(dāng)前交互控件的ID effElement=element.id; //在頁面中加載輸入控件 ShowControl ("SelectColor"); }
function getChange() { //當(dāng)值發(fā)生變化時,對可視化樣式元素賦值 SetAttribute(element.id,element.value); } </SCRIPT>
其他
設(shè)計(jì)器中的值輸入模式框只是頁面中的幾個層,通過上面的htc組件觸發(fā)顯示出來,輸入后再把值傳入到樣式屬性控件中,同時也會設(shè)置可視化樣式元素。
另外還需要注意的是,XML文檔是可以自行擴(kuò)展或縮減的,但是在實(shí)際應(yīng)用中,不能完全依據(jù)CSS標(biāo)準(zhǔn)來定義,因?yàn)榭梢暬氐膕tyle屬性會自動格式化。例如如果你在XML中定義border-bottom-width屬性,在將值取出時會自動格式化為border-bottom,這樣會造成設(shè)計(jì)器中控件不能匹配。我在MSDN沒有查到相關(guān)文檔,所以只有經(jīng)過實(shí)際測試來驗(yàn)證。
OK,比較關(guān)鍵的代碼已經(jīng)差不多了……希望能對大家有所幫助。
參考
另外再列出部分技術(shù)參考,如果大家對其中的技術(shù)細(xì)節(jié)如HTC和XmlDom等有所疑問,可以再詳細(xì)研究一下,也歡迎大家來和我交流 linnchord@tom.com 。
MSDN關(guān)于JS操作XmlDom的文檔 這是英文文檔,網(wǎng)上沒有看到比較詳細(xì)的中文文檔,好在不復(fù)雜,大家將就一下吧 :) (最近MSDN不知道什么毛病,經(jīng)常訪問有問題,如果無法訪問,請先登錄msdn,再輸入地址瀏覽)
藍(lán)色理想的HTC教程 網(wǎng)上也沒看見比較全面的講述,這個簡單易學(xué),基本概念清楚了。
|