天天看點

《Ext JS實戰》——2.2 Ext.Element類

本節書摘來自異步社群《ext js實戰》一書中的第2章,第2.2節,作者:【美】jesus garcia著,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視

所有使用了javascript的web應用程式都會圍繞着一個核心,也就是html的element。javascript對dom節點的通路能力讓我們能夠随意、靈活地操作dom,包括增加、删除、美化或者修改文檔中的任意節點内容。通過id引用一個dom節點的傳統方法是:

《Ext JS實戰》——2.2 Ext.Element類

這個getelementbyid方法很好用,可以執行一些類似改變innerhtml的内容,或者美化和配置一個css類這樣的基本任務。不過要是想對該節點做更多的事情,例如管理它的事件,在有滑鼠點選時應用某個樣式,或者替換一個css類?必須自己管理全部代碼,還要不斷地對代碼進行更新,以保證能夠全部浏覽器的相容性。老實說,我想不起還有什麼事情會比這個更費勁了。幸運的是,ext都替我們完成了這些任務。

2.2.1 架構的核心

先看一下ext.element這個類,ext js社群公認這個類是ext js的核心,架構中的每個ui部件中都有它的身影,通過getel()方法或者el屬性都可以得到它。

ext.element類是一個完整的dom元素管理包,包含了許多寶貴的工具,正是因為它的存在,才使得架構能夠對dom施展魔法,并提供健壯的ui供我們使用。這個工具集及其全部的功能對于最終的開發人員都是可用的。

按照ext js的設計理念,這個類不僅僅是對dom元素的簡單管理,還能處理各種複雜的任務,例如能夠很容易地管理大小、對齊以及坐标。也可以很容易地利用ajax更新一個元素,管理子節點、動畫,使用完整的事件管理以及更多的内容。

2.2.2 與ext.element的第一次親密接觸

ext.element是很容易上手的,而且可以簡化一些最困難的任務,為了練習ext.element,需要配置一個基本頁面。按照第1章介紹的方法,配置一個包含了ext javascript和css的頁面。接下來,要包含下面的css和html:

《Ext JS實戰》——2.2 Ext.Element類

這些隻是給我們的示例搭建一個舞台,確定div标簽有明确的大小和邊框,這樣在頁面上能夠清晰地看到效果。這裡用了一個id是'div1'的div,它就是要操作的目标。如果頁面設定正确無誤,應該可以清楚地看到這個樣式化的,如圖2-2所示。這幅圖檔展示的是一個普通的html框,下面就用它來練習基本的ext.element方法。

《Ext JS實戰》——2.2 Ext.Element類

注意:

所有的關于ext.element的示例代碼都會引用剛剛配置的基本頁面。如果想真切地看到dom發生的改變,建議用firefox内置的多行的firebug文本編輯器。相反,可以把這些示例放在一般的腳本塊中。隻是記住要使用ext.onready()。

按照這個css定義,屬于mudiv類的div都會是35個像素高和200個像素寬,看起來有點怪異。我們要做的就是,通過把高度改成200個像素,讓這個div變成一個完美的正方形。

《Ext JS實戰》——2.2 Ext.Element類

上面這兩行代碼的執行非常重要。第一行使用的是ext.get,傳給這個方法一個字元串'div',傳回的結果是一個ext.element的執行個體,傳回的執行個體通過變量mydiv1進行引用。ext.get使用的也是document.getelementbyid,隻不過是按照ext的元素管理方法對它進行了包裝而已。

得到這個ext.element執行個體mydiv1之後,通過調用它的setheight方法,并傳入一個整數值200,就把這個方框的高度增加到了200個像素。類似地,也可以用setwidth方法改變元素的寬度,不過下面會跳到一些更有趣的内容。

“一個完美的正方形。不錯!”好了,再把大小改變一下,這次使用的是setsize。把width和height都設成350個像素。還是利用已經建立好的引用,mydiv1:

《Ext JS實戰》——2.2 Ext.Element類

執行這行代碼會發生什麼呢?是不是動起來了,有一種生動的效果?更好了!

實際上,setsize方法是setheight和setwidth方法的組合。對這個方法,傳遞的是寬度,高度以及一個帶有兩個屬性的對象,這兩個屬性是duration和easing。如果定義了第3個屬性,會讓setsize以動畫的效果展現元素大小的改變。如果不在乎動畫效果,那就可以忽略第3個參數,這個框的大小立刻會發生改變,就像之前改變高度那樣。

設定大小還隻是通過element類管理元素的衆多功能之一。ext.element更強大的能力展現在輕松地處理元素的crud操作(建立、讀取、更新和删除)。

2.2.3 建立子節點

javascript的好處之一就是操縱dom的能力,這其中就包括dom節點的建立。javascript中的有很多原生方法也具有這個能力。ext js用ext.element類很友善地把這些方法包裝起來。下面看看如何建立子節點。

要想建立一個子節點,要用的是element的createchild方法:

《Ext JS實戰》——2.2 Ext.Element類

這段代碼給目标div的innerhtml添加了一個字元串節點。如果想建立一個元素該怎麼做呢?很簡單:

《Ext JS實戰》——2.2 Ext.Element類

createchild會給div1的innerhtml追加一個内容是字元串'element from a string'的子div。我不喜歡用這種方法追加子元素,因為這種用字元串代表元素的形式太混亂了。ext通過接收一個配置對象而不是一個字元串幫我們解決了這個問題:

《Ext JS實戰》——2.2 Ext.Element類

這裡是通過配置對象來建立子元素的。将tag屬性設成'div',給html屬性指定了一個字元串。單從技術的角度來看,這個方法和之前的createchild實作是一樣的,不過看起來更清晰,更能說明我們的意圖。如果想注入一個嵌套的标簽又該怎麼做呢?還是通過配置對象的方法,可以很容易地實作:

《Ext JS實戰》——2.2 Ext.Element類

在這段代碼中,建立了最後一個子元素,它有一個id、一些樣式以及一個子元素,這個子元素是一個帶有更多樣式的div。圖2-3顯示了div所發生的變化。

《Ext JS實戰》——2.2 Ext.Element類

在圖2-3中,可以看到添加到mydiv1的全部内容,以及firebug所展示的一副生動的dom視圖,這裡增加了一個字元串節點和3個子div,其中一個還有它自己的子div。

如果想在清單的頂端插入一個子元素,還可以使用好用的insertfirst方法,例如:

《Ext JS實戰》——2.2 Ext.Element類

element.insertfirst總是在位置0插入一個新的元素,即使dom結構中還沒有一個子元素也一樣。

如果想在一個特定的位置插入一個子節點,createchild方法也可以完成這個任務。我們所要做的就是把新建立節點的位置傳進去,例如:

《Ext JS實戰》——2.2 Ext.Element類

在這段代碼中,我們給createchild傳入了兩個參數。第一個參數是個配置對象,代表着新建立的dom元素,第二個參數是目标節點的引用,createchild用它作為建立節點的容身之所。記住你給這個新建立元素指定的id;我們很快就會用到它。

注意,這裡用到了mydiv1.dom.childnodes。ext.element的dom屬性讓我們具有了利用通用浏覽器元素管理優雅性的機會。

element.dom屬性和document.getelementbyid()傳回的是同樣的dom元素引用。

圖2-4顯示了在頁面上看到的插入節點的樣子,以及在firebug的dom探測工具中看到的dom層次結構。從圖2-4中可以看到,節點插入的結果和我們設想的一樣。用insertfirst在清單的頂端插入一個新節點,用createchild在子節點3的上面插入一個節點。記住,對子節點的計數總是從數字0開始的,而不是從1開始的。

《Ext JS實戰》——2.2 Ext.Element類

作為一名web開發人員,添加元素對我們來說是家常便飯。畢竟,這是dhtml的一部分。不過删除也同樣重要。下面再看看如何用ext.element删除一些子元素。

2.2.4 删除子節點

節點的删除看起來要比添加簡單一些。我們所需要做的就是通過ext找到該節點,然後調用節點自己的remove方法就行了。為了練習子節點的删除操作,以一個幹淨的畫闆開始。請建立一個頁面,然後輸入下面的html代碼:

《Ext JS實戰》——2.2 Ext.Element類

檢查這段html代碼,看到了一個id是'div1'的父div。它有5個直系的後代,第1個的id是'child1'。第2個和第3個沒有id,不過其css類分别是'child2'和'child3'。第4個子元素的id是'child4',并且其css類是'sameclass'。類似地,它也有一個id是'nestedchild1'的直系後代,并且用的是和父親相同的css類。div1的最後一個孩子沒有id,也沒有css類。之是以準備這些素材,是因為要先從css選擇器1開始,然後再到直接利用元素的id。

在添加子節點的例子中,一直是把父div(id='div1')包裝成ext.element後加以引用,然後用它的create方法建立節點。要想删除一個節點,就要用不同的方法了,因為需要明确地定位到要删除的節點。對于這個新的dom結構,我們會用幾種方法來實作。

要嘗試的第一個方法是通過一個已經包裝好的dom元素删除一個子節點。先要建立一個包裝div1的ext.element執行個體,然後再用css選擇器找到它的第一個子節點。

《Ext JS實戰》——2.2 Ext.Element類

這個例子中,通過ext.get得到了對div1的引用。然後又調用了element.down方法,傳給這個方法的是一個僞類選擇器,這會讓ext沿着這棵dom樹向下查找,一直到找到第一個孩子,它是一個div,然後ext把它包裝成一個ext.element的執行個體,最終得到的就是對第一個子元素的引用,即firstchild的引用。

element.down方法查找的是給出的ext.element的一級dom節點。找到的結果恰好是一個id是'child1'的div。然後調用firstchild.remove,這個節點就從dom中删除了。

下面是通過選擇器删除清單中的最後一個節點:

《Ext JS實戰》——2.2 Ext.Element類

這個例子和前一個類似,最大的差別在于用的是選擇器'div:last-child',這個選擇器找到div1的最後一個childnode,然後再用一個ext.element的執行個體把它封裝起來。最後,再調用lastchild.remove,這個節點就沒有了。

如果想根據id找到目标元素該怎麼辦呢?可以讓ext.get完成這個工作。這次,沒有必要建立引用,用鍊(chaining)完成這個工作就可以了:

《Ext JS實戰》——2.2 Ext.Element類

執行這行代碼會把id是'child4'的子節點删掉,包括該節點的子節點。記住,如果一個節點有子節點,那麼删除這個節點的同時,它的所有子節點也都會被删除。

關于ext.element要了解的最後一項内容就是執行ajax請求,從伺服器遠端加載html片段并把它們注入到dom中。

2.2.5 ext.element與ajax一起使用

ext.element類具有執行ajax的能力,可以取得遠端的html片段,并把這些片段注入到它自己的innerhtml中。做練習之前,先寫一個将要被加載的html片段:

《Ext JS實戰》——2.2 Ext.Element類

這個html片段中,隻放了一個簡單的div,還嵌入了一個script腳本,裡面調用的是ext.getbody,然後又通過鍊調用它的highlight方法。要想得到對document.body的引用,ext.getbody非常好用,現在把這個檔案儲存成htmlfragment.html。

接着,要加載以下内容。

《Ext JS實戰》——2.2 Ext.Element類

這段代碼中,調用的是ext.getbody所傳回的對象的load方法,并給這個方法傳入一個配置對象,其中url指定的要加載的目标htmlfragment.html,scripts被設為true。這段代碼執行起來會怎麼樣呢?可以參見圖2-5。

《Ext JS實戰》——2.2 Ext.Element類

這段代碼執行後,可以看到文檔體通過ajax請求擷取了htmlfragment.html檔案。在擷取這個檔案的過程中,會一直顯示一個代表正在加載的訓示符,一旦請求完成,這段html片段就被插入到dom中了。接着會看到整個内容區都用黃色高亮顯示,這就意味着javascript代碼得到了執行。現在,應該知道ext.element.load方法要比手工調用ext.ajax.request友善多了。

看到了吧,用ext.element給dom添加内容或者删除内容就是小菜一碟。ext還有更簡單的辦法添加元素,尤其是當要增加的是那種重複的dom結構。這就要用到template和xtemplate兩個輔助工具類。

繼續閱讀