Ext Core是一款和jQuery媲美的輕型JS庫,基於MIT許可。對於Dom的操作,我個人還是比較喜歡用jQuery。當然如果項目中用的是ExtJS框架,也就沒必要多引用一個jQuery,Ext Core是ExtJS框架的一個小子集。如果僅僅使用Ext Core的功能,則只需引入builds文件夾下的一個ext-core.js就可以了,無需css等其他文件。
由於瀏覽器DOM操作的差異,為了實現Web框架的跨瀏覽器特性,每個JS框架都會構建一個新類來操作DOM,在Ext Core中實現該功能的類就是Ext.Element。Ext.Element類中的方法很多,主要方法大致可歸為這么幾類:DOM查詢和遍歷、DOM操作、大小與定位和CSS樣式操作。對於這些,我們可以在實際開發用到的時候去查看Ext Core API。為了開發效率,應該對Ext Core的一些常用功能函數做一個大致的了解。下面將分別進行簡單介紹。
獲取元素
第一種方式是Ext.get方法,它獲取html節點並會創建Ext.Element實例:
var el = Ext.get("elId");
使用Ext.get會創建元素實例,並可在后期引用時使用。
另一種方式稱為享元模式(Flyweight Design Pattern),是一種省內存的模式。如果是對元素的一次性操作,可使用Ext.fly方法。Ext.fly方法不會創建Ext.Element實例,實際它是利用全局共享的Ext.Element實例進行操作。一般在對元素的某個屬性一次性的取值或設值時使用:
Ext.fly("elId").getHeight(); //下面將div1存儲起來是無效的。 var div1 = Ext.fly('div1'); Ext.fly('div2').frame(); //下面代碼改變的是div2的高度。 div1.setHeight(200);
另外,有一個容易與上面兩個方法混淆的是Ext.getCmp方法,該方法用來取得Ext組件。如:
var text = new Ext.form.TextField({ id: "text", renderTo: Ext.getBody() }); Ext.getCmp("text").setWidth(200);
Ext的組件是Ext對一個或多個html元素進行封裝的集合,組件和元素有着本質的區別。
對於Ext容器組件(如Ext.Toolbar、Ext.form.FormPanel等)必須通過Ext.getCmp()獲取。但對於非容器組件,可以根據Ext組件Id通過Ext.get和Ext.fly獲取該組件對應的Ext.Element實例。如:
var text = new Ext.form.TextField({ id: "text", renderTo: Ext.getBody() }); Ext.fly("text").setWidth(200);
雖然能通過fly或get獲取到Ext組件對於的Ext.Element實例,但顯然這實例不具有Ext組件的功能,比如上面代碼Ext.fly("text")不能調用setValue()方法。關於Ext組件,我會在后續文章中對其進行專門的講解。
上面三種獲取元素的方法,不管是Ext組件編程還是DOM編程,都會經常用到。
還有一種Ext.getDom,它是用來獲得普通dom元素的,也是將Ext.Element轉換為普通dom元素的一種方式。它的參數可以是元素id,也可以是Ext.Element對象。
var div = Ext.get('div1'); var el = Ext.getDom('div1'); var el = Ext.getDom(div);
操作DOM和CSS
Ext.Element的查詢和遍歷方法不多,下面簡要介紹幾個方法,了解一下即可。
is:判斷當前元素是否與選擇器選擇的元素匹配。
if (Ext.get('test').is('div.cls')) { alert("test is div.cls"); }
findParent:從當前節點開始查找與選擇器匹配的父節點(包含當前節點)。要注意該方法默認返回的是HTMLElement對象,不是Ext.Element對象。如果需要返回Ext.Element對象,則需要設置第3個參數為true。
//返回HTMLElement var el = Ext.fly('elId').findParent('div'); //定位到在當前節點的第4層父節點 var el = Ext.fly('elId').findParent('div', 4); //返回Ext.Element var el = Ext.fly('elId').findParent('div', null, true);
up:是findParentNode方法的縮寫,不過該方法返回的是Ext.Element對象。
select:通過選擇器選擇當前節點下的子節點,該方法的返回值是Ext.CompositeElement對象。
Ext.fly('elId').select('div'); //如果希望返回的節點是Ext.Element對象,需要設置第2個參數為true Ext.fly('elId').select('div',true);
注意,Ext.CompositeElement對象是不允許直接通過索引訪問其內部元素的,要訪問內部元素需要使用item方法。注意,是item方法,不是屬性,要使用括號(而不是中括號)包含索引,要遍歷對象中的元素可使用each方法。通過getCount方法可獲取元素的總數。要定位元素可使用indexOf方法。
query:通過選擇器選擇DOM節點,該方法返回包含DOM節點的數組。
Ext.fly('elId').query('div'); // 上面這句也可以使用以下語句代替 Ext.query('div', Ext.getDom('elId'));
child:通過選擇器返回一個當前節點的子節點,默認返回的是Ext.Element對象,如果需要返回HTMLElement對象,第2個參數需要設置為true。
Ext.fly('elId').child('div'); //返回Ext.Element對象 Ext.fly('elId').child('div',true); //返回HTMLElement對象
down:通過選擇返回一個當前節點的直接子節點,該方法與child方法類似,唯一不同的是,選擇器不能包含節點id,其使用方法可參考child方法。
parent:返回當前節點的父節點。該方法通過設置第 2 個參數可控制返回的是Ext.Element對象還是HTMLElement對象。
Ext.fly('elId').parent(); //返回Ext.Element對象 Ext.fly('elId').parent('',true); //返回HTMLElement對象 //也可以通過選擇器選擇 Ext.fly('elId').parent('div');
另外還有 next、prev、first、last等方法,具體可以查看Ext Core API文檔。
Ext.Element提供操作CSS樣式很方便,來看幾個常用的方法。
addClass:為元素增加樣式類。
//只增加一個樣式類 Ext.fly('elId').addClass('cls1'); //增加多個樣式類 Ext.fly('elId').addClass(['cls1', 'cls2',..., 'clsN']);
toggleClass:樣式類開關。如果element已存在某個樣式類,執行該方法將移除該樣式類;如果不存在,則增加該樣式類。
Ext.fly('elId').toggleClass('elCss');
setStyle:設置樣式屬性。
//只設置一個屬性 Ext.fly('elId').setStyle('color', '#FFFFFF'); //設置多個屬性 Ext.fly('elId').setStyle({ color: 'red', background: 'yellow', font-weight: 'bold' })
其它方法,有hasClass、replaceClass、getStyle、getColor等,用起來都很簡單,就不一一介紹了。
Ext.DomHelper操作DOM
Ext.DomHelper是一個用來生成HTML片段的類,它主要通過定義一個JSON格式的數據生成HTML片段,對開發人員來說,非常靈活方便。它的數據結構主要包括以下4個屬性:
tag:元素的標簽,例如div、span之類。
children:由元素的子元素組成的數組,可以通過該屬性不斷增加子元素。
cls:元素的CSS類名。
html:元素的innerHTML屬性,如果不想使用children屬性定義元素的內部HTML內容,可使用該屬性代替。
來看一個示例:
//JSON格式的數據 //也可以將下面的children屬性替換成 html: '<li>1</li><li>2</li><li>3</li>' var list = { id: 'itemList', tag: 'ul', cls: 'list', children: [ { tag: 'li', html: '1' }, { tag: 'li', html: '2' }, { tag: 'li', html: '3' } ] }; var a = { id: 'link1', tag: 'a', href: 'url', target: '_blank', html: '鏈接' } //生成代碼片段,將ul標簽添加到body標簽內 Ext.DomHelper.append(Ext.getBody(), list); //在ul標簽后插入a標簽 Ext.DomHelper.insertAfter('itemList', a);
上面代碼會生成下面這樣一段html代碼片段:
<ul id='itemList' class='list'> <li>1</li> <li>2</li> <li>3</li> </ul> <a target='_blank' href='url' id='link1'>鏈接</a>
使用Ext.DomHelper的優點是代碼簡單明了、容易維護。Ext.DomHelper操作DOM的方法還有appendChild、appendTo、insertBefore、insertFirst等,這些方法的意義與jQuery中操作Dom的方法是一樣的。
尺寸與大小
對於某個元素在頁面上的位置和元素尺寸大小的操作,Ext Core也封裝了很多方法,用起來也很方便。這些沒什么好介紹的,直接看例子吧。
尺寸大小:
//以默認的動畫設置元素高度 Ext.fly('elId').setHeight(200, true); //以自定義動畫設置元素的高度 Ext.fly('elId').setHeight(200, { duration: 0.5, //持續半秒 //動畫過后做一些操作 callback: function () { this.update("結束"); } }); //得到某個元素的高度 var height = Ext.fly('elId').getWidth();
還有一些方法,如getPadding、getBorderWidth等極少用的方法。
定位的設置和取值方法和尺寸設置取值基本一樣:
Ext.fly('elId').setX(200, { duration: 0.5, //持續半秒 //動畫過后做一些操作 callback: function () { this.update("結束"); } });
和定位有關的方法還有getX、getY、getXY、getTop、getLeft等等。具體可查看Ext Core API。
結束語
其實真正用ExtJS框架開發B/S應用的時候,很少會對Dom進行直接操作。ExtJS是基於組件的,本身有着強大的布局功能。比如要做一個彈出的登錄界面,一個Window組件幾個TextField組件再加兩個按鈕組件就做好了,而且畫面風格統一,整齊美觀,基本上不需要用到Div+CSS布局,也不會在一個Ext容器組件中加個html元素如<input type='button'/>。也就是說,實際應用中,Ext Core中的大部分功能不會和Ext組件混合使用。
但如果選擇了ExtJS框架開發B/S應用,還是有必要了解和學習一下ExtJS框架的Ext Core部分的。
參考:
《Ext JS 高級編程》
《Ext Core 手冊》
http://docs.sencha.com/core/