2016年3月15日 星期二

dojo/dom-class

dojo/dom-class

簡介

dojo/dom-class 是另一個可以改變節點樣式的模組。但和 dojo/dom-attr, dojo/dom-prop 及 dojo/dom-style 不同的是:dojo/dom-class 是透過改變節點中 class 屬性值的方式來改變節點的樣式;如果規劃得宜,這種方式顯得更有條理且效率更高,程式也比較易讀及維護。但有一點要特別注意:如果該元件在樣式表中有透過 #id 設定的樣式,則透過 .class 的設定無法改變透過 #id 的設定,必須使用 dojo/dom-style 模組才能改變在 #id 中的設定值。

contains(node, class)
檢查 node 節點中是否含有 class 類別,若有,傳回 true;若無,則傳回 false。class為樣式類別的名稱字串。
add(node, class)
將名為 class 樣式類別加到 node 節點中。class 會被加到 node 節點之樣式類別的最後一個。但如果兩個不同的樣式類別都設定了相同樣式屬性,哪一個樣式類別的設定會被採用,則決定於這兩個樣式類別在樣式表中的先後次序,在樣式表中較後面的樣式類別,具有較高的權限。於如果節點的 class 屬性中己具有要加入的樣式類別,則不會重複加入。參數 class 可以是一個字串值,或一個字串陣列;若傳入值為一字串陣列,會依序將陣列中的字串值逐一加入到節點的 class 屬性值之中。
remove(node, class)
在 node 節點中移除名為 class 的樣式類別。如果該類別不存在,也不會發生錯誤。參數 class 也可以是一個字串陣列,當傳入字串陣列時,陣列串所有的樣式類別都會被移除。
replace(node, toAdd, toRemove)
將 node 節點中的 toRemove 樣式類別替換成 toAdd 樣式類別,其實就是 .remove(toRemove) 加上 .add(toAdd) 的組合。toAdd 和 toRemove 這兩個參數都可以是一個字串陣列。
toggle(node, class)
如果 node 節點中己有名為 class 的樣式類別,則移除;若無,則加入。

範例

範例中建立了一個方塊,每兩秒透過程式改變方塊的樣式設定一次。記得開啟「開發者工具」,觀察 html 原始碼的變化。

CSS

<style>
html {
 width:100%;
 height:100%;
}
body {
 margin: 0 auto;
 width:1000px;
 height:100%;
 padding-top:20px;
}
.original {
 width:200px;
 height:200px;
 border:1px solid black;
}
.red {
 background-color:red;
 border: 5px solid black;
}
.blue {
 background-color: blue;
 border: 5px solid silver;
}
.big {
 width:200px;
 height:200px;
}
.small {
 width:100px;
 height:100px;
}
</style>

樣式表中分別定了五個樣式類別給方塊使用,.original{} 是預設的樣式,.red{} 和 .blue{} 設定方塊的背景和邊框的顏色,.big{} 和 .small{} 則設定方塊的大小。

HTML

<body class="claro">
    
</body>

html 中用 <div> 建立一個方塊,樣式類別為 .original{}。

Script


程式的部份淺顯易懂,就不多做解釋了。

2016年3月14日 星期一

dojo/dom-style

dojo/dom-style

簡介

dojo/dom-style 是用來改變節點樣式 (style) 的模組。雖然利用 dojo/dom-attr 和 dojo/dom-prop 也可以改變節點的樣式,但不若使用 dojo/dom-style 來的直覺和方便。

使用 dojo/dom-style 時需注意下列幾點:

  1. HTML 中的樣式屬性名以連字符號 (hyphen) 分隔單字,在 dojo/dom-sytle 模組中,樣式屬性的名稱的命名則為駝峰式 (CamelCased)。例: font-size 在dojo/dom-style 中要寫成 fontSize,background-color 則要寫成 backgroundColor。
  2. 所有的顏色屬性,在設定時雖然還是可以使用各種表示式,但在讀取時的傳回值時都會被正規化 (normalized) ,一律以 rgb(r, g, b) 的方式表逹。
  3. 有些具有組合值的樣式屬性,只會傳回一個字串。例如: border 含有 border-width, border-style, border-color,其中各個又含有 border-top-*, border-left-*, border-right-* 及 border-bottom-* ,使用時,最好明確的分別讀取各值,否則很容易搞混,不方便作業。這時可能就要用到 .getComputedStyle() 取得樣式最終的計算結果來處理。但如果你很清楚自己在做什麼,就另當別論了。

getComputedStyle(node)
這是少數參數只能傳入節點,而不能傳入節點的 id 字串的函式。參數一定先得透過 dom.byId("idString") 取得節點,再當成參數傳入,才能呼叫該函式。函式則會傳回一個包含所有樣式屬性的龐大物件,這個函式會消耗很多資源,要小心使用。
get(node, name)
取得 node 節點中名為 name 樣式屬性的設定值。第一個參數可以傳入節點,或該節點 id 的字串值。
set(node, name, value)
設定節點 node 的 name 樣式屬性為 value 值。第一個參數可以傳入節點,或該節點 id 的字串值。

範例

範例中建立了一個黑框黃底的方塊, 2 秒後改變邊框色為銀色,再過 2 秒改變底色為藍色,再過 2 秒縮小方塊面積成為原面積的 1/4。記得開啟開發者工具,在主控台中觀察 console.log() 的輸出。

CSS

<style>
html {
    width:100%;
    height:100%;
}
body {
    margin: 0 auto;
    width:1000px;
    height:100%;
    padding-top:20px;
}
.boxStyle {
    width:200px;
    height:200px;
    border:5px solid black;
    background-color: yellow;
}
</style>

樣式表中先以 .boxStyle{} 建立方塊的基本樣式。

HTML

<body class="claro">
    
</body>

html 裡簡單的建立一對 <div> 標記,使用樣式做成一個方塊。

Script


第 11 行呼叫 dom.byId() 以取得節點物件,因為第 12 行的 domStyle.getComputedStyle() 只能用節點做為參數值。其它各行程式的作用都顯而易見,就不多做解釋了。

2016年3月13日 星期日

dojo/dom-prop

dojo/dom-prop

簡介

dojo/dom-prop 是一個提供函式用來改變節點各屬性的模組。和另一個名為 dojo/dom-attr 的模組功能很相似,但 dojo/dom-attr 很可能在未來退役(根據網路傳言),而完全由 dojo/dom-prop 負責這一部份的功能。之後, dojo 可能就不再區分 attribute 和 property 在定義上的細微差異,一視同仁由 dojo/dom-prop 來處理。

dojo/dom-prop 只提供了二個函式如下:

get(node, prop):
取得並傳回節點 node 在 prop 屬性的設定值。這裡有三個重點要特別注意:
  1. 當 prop 是 node 在定義中擁有的屬性時,例如 class,但卻沒有設定值時,會傳回空字串 "" ,而非 null。
  2. 當 prop 並非 node 在定義中已有的屬性時,例如:<p> 標記並不具有 width 及 height 屬性 (attribute),因此預設不具有這兩個屬性,更不會有設定值,此時會傳回 undefined。透過 dojo/dom-prop 還是可以設定其值,只是沒有作用。透過這個特性,可以用來判定某一屬性是否為某節點所在定義上即擁有的屬性。
  3. 當 get() 在讀取像 <img> 的基本屬性 width 及 height 值時,只會傳回數值的部份,卻不會傳回設定的單位或是百分比。例如: 50px, 50em 和 50% 都只會傳回 50,這點還滿令人抓狂的。建議使用 dojo 時,在任何地方只要有設定到 width 和 height 時,最好都在樣式表 (style) 中設定,也只用 dojo/dom-style 來操作這些屬性。
另外,get() 還可以傳入兩個並不算是屬性的值:
  • "innerHTML" : 傳入 "innerHTML" 做為屬性名稱時,會傳回節點內含的 HTML 片段。
  • "textContent" : 傳入 "textContent" 做為屬性名稱時,會傳回內含所有的文字部份,像是 <span> 和 <br> 等這些 in-line 的標記都會被拿掉。特別要注意的是 <br> 這個標記並不會用換行或是空白字元來取代,使用時要特別小心。
set(node, prop, value):
將 node 中的 prop 屬性設定為 value 值。即使 prop 不是 node 定義擁有的屬性,還是可以設定,只是沒有作用,在下載的 html 原始碼中也看不到;設定完了之後,用 get() 還可以讀得到值。為什麼要這麼做,我也是百思不得其解。

範例

範例中定義了一個文字段落,然後用程式去改變文字段落的屬性。記得開啟開發者工具,在主控台中觀察結果。

CSS

<style>
html {
    width:100%;
    height:100%;
}
body {
    margin: 0 auto;
    width:1000px;
    height:100%;
    padding-top:20px;
}
</style>

定義 html 及 body 的樣式,讓顯示文字比較容易看到。

HTML

<body class="claro">
    

First line.< br >Second line.

</body>

html 裡只簡單的定義了一個文字段落以供修改屬性值。

Script


程式的部份就是 get 和 set ,也不用多費唇舌解釋了。注意一下第 10~20 行的執行的結果。

dojo/dom-attr

dojo/dom-attr

簡介

dojo/dom-attr 可以用來修改節點的 attribute,(因為在中文裡,attribute 和 property 都譯為「屬性」,在 HTML 裡兩者的定義其實並不完全相同,因此在文中直接使用英文,避免混淆。)在 HTML 中,各種不同的節點各自擁用不同的 attribute。例如:<p> 標記就沒有 width 和 height 兩個 attribute,而 <img> 標記則有,如果寫成 <p width="50px" height="50px">;,其中的 width 和 height 雖然設定了,但並不會有作用,流覽器會忽略這些設定。而在<img> 中設定 width 和 height,則會改變圖片的寬和高。在 dojo 中,有 dojo/dom-attr 和 dojo/dom-prop 兩個模組,都可以用來修改各節點的 attribute。根據未確認的網路說法,dojo/dom-attr 可能在將來會被淘汰,而由 dojo/dom-prop 擔當修改所有 attribute 和 property 的責任;屆時,在 dojo 中也就不再區分 attribute 和 property 在定義上的不同了。只有一點要注意,設定樣式 (style) 的部份,dojo 另有一個模組 dojo/dom-style 來處理,dojo/dom-prop 和 dom/dom-prop 都不負責這部份。

dojo/dom-attr 有三個函式可供使用,用法也很簡單:

has(node, attr):
用來偵測 node 中是否有定義名為 attr 的 attribute。這裡並非指 node 這個節點在 HTML 定義中是否具有 attr,而是在 node 中是否定義了 attr。以 <img> 為例,雖然在 HTML 的定義中並不具有 width 這個 attribute,但只要有設定值,has() 便會傳回 true ;即便流覽器會忽略這個設定。如果沒有設定,則傳回 false。
get(node, attr):
取得在 node 中的 attr 設定值。若不曾設定,則傳回 null。
set(node, attr, value):
在 node 中設定 attr 的值為 value。不論在 HTML 中 node 標記的定義是否含有 attr 這個 attribute,只要呼叫了 set(),這個設定便會被加到 node 之中,在呼叫 has() 偵測時,也會傳回 true。流覽器則依據 HTML 的對該節點的定義是否具有該 attribute ,決定是否處理或忽略該設定。基本上 set() 就是要 attr 和 value 組合成一個字串,然後加到 node 標記中。

範例

範例中簡單的定義了一個段落標記,然後藉著 dojo/dom-attr 模組所提供的功能,以程式的方式修改該段落的 attribute。記得開啓主控台觀看輸出結果,從開發者工具中,也可以觀看 HTML 碼的變化。

CSS

<style>
</style>

沒有 CSS 的設定。

HTML

<body class="claro">
    

A paragraph

</body>

HTML 中,簡單的建立一個文字段落做為測試用。

Script


第 4 行之所以會傳回 true,是因為在第 3 行設定了 width 。
第 6 行傳回 null ,因為並沒有設定 height 值。
也可以用第 8 行的方式改變段落的樣式,但最好用 dojo/dom-style 來處理會比較方便。如果將來 dojo/dom-attr 真的被淘汰了,也不用再修改程式。

2016年3月11日 星期五

dojo/dom

dojo/dom

簡介

dojo/dom 是 dojo 在操作 DOM Tree 時,最基本的模組。可供呼叫的函式不多,只有三個:

byId(name)
依據傳入參數的字串,找到屬性 id="name" 的節點,這個函式用到的機會很高,畢竟要針對某一個節點運作時,總得先尋找並鎖定該節點。但在 dojo 中很有意思的是,在許多需要傳入節點做為參數的地方,可以直接傳入作為 id 名稱的字串, dojo 的函式會自行判斷,如果是傳入的是節點,則開始運作,如果傳入的是字串,則先自行呼叫 dom.byId() 函式,在取得節點後再行運算。所以有時候,也完全可以不去用這個函式。
isDescendant(node, ancestor)
用來測試 node 是否為 ancestor 的子節點,node 不限制一定要是 ancestor 的直接子節點,即使是好幾代之後的子節點,傳回值也是 true,若不是任何一代的子節點,則傳回 false 。
setSelectable(node, boolean)
若 boolean 值為 true,設定 node 節點為可選取,若 boolean 值為 false,則設定 node 節點為不可選取。

範例

CSS

<style>
html {
    width:100%;
    height:100%;
}
body {
    margin: 0 auto;
    width:1000px;
    height:100%;
    padding-top:20px;
}
.box {
    width:300px;
    height:200px;
    padding:10px;
    border: 2px solid black;
}
</style>

CSS 中用 .box{} 設定方塊的外觀屬性。

HTML

<body class="claro">
  • One
  • Two
  • Three
  • Four
</body>

Html 中建立一個方塊,在方塊中包含一個無序數的清單。

Script


第 12 行和第 13 行的執行結果是一樣的,兩種寫法都可以,就看各人喜好了。

第 15 行將整份文件都設定為不可選取;因此第 16 行的設定也沒有效果了。

dojo/dom-construct

dojo/dom-construct

簡介

dojo 針對 Javascript 的擴充其中很大一部份是在對 DOM 的操作上。相對於 Javascript 在操作 DOM 時所使用冗長的 API 函式名稱,dojo 不僅僅提供了一組比較簡單的語法,同時也處理了不同流覽器間相容性的問題。

dojo/dom-construct 的主要作用在透過程式以改變 DOM Tree 的結構,可以增加、減少或替換節點 (node)。主要的函式如下:

toDom(htmlString)
將參數中的 htmlString 字串值轉換成一個節點,並傳回該節點。
place(node, refNode, position)
置於 refNode 的 position 位置; node 參數也可以用 HTML 片段來取代,直接將該 HTML 片段加入 refNode 的 position 位置。positon 的值為字串或數值,預設為 "last"。允許值如下:
before
將 node 置於 refNode 之前。
after
將 node 置於 refNode 之後。
first
將 node 加入,成為 refNode 的第一個子節點。
last
將 node 加入,成為 refNode 最後一個子節點。
only
將 node 加入,成為 refNode 唯一的子節點;此時,refNode 原先所有的子節點都會被清除。
replace
用 node 來替換 refNode。替換後,refNode 節點就不存在了。
number
當 position 的值為一個數值時,dojo 會將 node 加入成為 refNode 的第 number 個子節點。在加入 <ul> 及 <ol> 的清單項目 <li> 時相當便利;計數時由 0 開始。要特別注意的是:refNode 的文字節點 (text node) 也在計數之中,而 0 所代表的便是這個 refNode 的文字節點。以本文的這一段 <ul> 清單為例: 「positon 的值為字串或數值,允許值如下:」這一段文字,便是節點 0。 寫一段小程式測一下便很容易理解了。如果 number 遠大於子節點的個數,則自動成為 refNode 的最後一個子節點。

create(tag, attrs, refNode, position)
這個函式可以一次做完:建立節點、設定節點的屬性及加入節點到 refNode 的 position 的位置。實際使用狀況,看下列例子比較清楚。
empty(node)
將 node 所有的子節點清除。
destroy(node)
將 node 節點本身及其所有子節點都清除。

範例

範例中先建立一個方塊,兩秒後,程式會在方塊中加入 "Now you see me!" 這行文字,再過兩秒會在方塊下方,加入底色為淡藍色的 "New" 字樣。

CSS

<style>
html {
    width:100%;
    height:100%;
}
body {
    margin: 0 auto;
    width:1000px;
    height:100%;
    padding-top:20px;
}
.box {
    width:300px;
    height:200px;
    padding:10px;
    border: 2px solid black;
}
.child {
    color:blue;
}
</style>

CSS 中設定一個方塊的外觀屬性,及用 .child{} 設定方塊中三個段落中字體的顏色。

HTML

<body class="claro">

    

Wait for a few seconds

here

I am the First child node

I am the Second child node

I am the Third child node

</body>

Html 中建立一個具有三個 <p> 標記的 <div>。

Script


第 18 行的效果等於第 15~16 行兩行的效果。

2016年3月4日 星期五

dojo/Deferred, dojo/when

dojo/Deferred, dojo/when

簡介

dojo/Deferred 是 dojo 中實作 dojo/promise/Promise 的類別,也是使用 promise 的基礎元件。當一個作業要在非同步狀態下執行,而其它作業有可能必須在此作業完成後方能執行時;該作業在實作時便應宣告且產生一個 Deferred 類別的實體 (instance),並傳回一個 promise。後繼要執行的作業則作為 promise.then() 的參數,在 promise 被「滿足」(fulfilled) 時執行。因為 promise.then() 也會傳回一個 promise;所以,整個程序可以一直串接下去,形成一個執行鏈。
dojo/when 只是 promise.then() 的一個簡單寫法。

範例


範例中建立了兩個圓形,點按左邊的圓形以模擬非同步的作業,右邊的圓形則顯示作業的進度,及顯示最終的結果。設定為點按三次左邊圓形便完成作業。修改一下程式碼可以產生「拒絕」(reject) 的結果。

CSS

<style>
html {
    width:100%;
    height:100%;
}
body {
    margin: 0 auto;
    width:1000px;
    height:100%;
    padding-top:20px;
}
#counter {
    margin:20px;
    height:100px;
    width:100px;
    border:10px solid black;
    border-radius: 50%;
    font-size: 48px;
    text-align: center;
    line-height: 100px;
    float:left;
}
#response {
    margin:20px;
    height:100px;
    width:100px;
    border:10px solid black;
    border-radius: 50%;
    font-size: 48px;
    text-align: center;
    line-height: 100px;
    background-color: white;
    float:left;
}
</style>

#counter 設定左邊圓形的屬性。
#response 設定右邊圓形的屬性。

HTML

<body class="claro">
  
0
0
</body>

HTML 則建立兩個 <div>,用來顯示左、右兩個圓形。

Script


取消第 36 ~ 40 行的註解並註解第 43 ~ 47 行;在點按左邊圓形三次後,會產生「拒絕」的結果,此時會執行第 62 ~ 70 行的程式。

第 54 ~ 80 用 when 的語法寫,則如下所示:


2016年3月2日 星期三

dojo/promise/Promise

dojo/promise/Promise

簡介

Promise(議決、承諾)是一種程式撰寫的模式 (Template),其主要功能在協調非同步執行緒 (Asynchronous Thread) 作業之間的前後順序。為了協調各執行緒執行時的先後次序,首先要在先執行的執行緒中產生並傳回一個 Promise 物件,再利用這個 Promise 物件來控制後續要執行的作業。先執行的執行緒則在完成作業時,傳回「解決」(resolved) 的訊號;或因執行條件不足或執行條件錯誤時,傳回「拒絕」(rejected) 的訊號。而 Promise 的狀態則在「未完成」 (unfulfilled)的起始狀態,依據先執行的作業結果轉換至「完成」(fulfilled)或「拒絕」(rejected) 兩個狀態之中的一個;Promise 則依不同的狀態再去執行對應的作業。

在 dojo 中,dojo/promise/Promise 是一個只定義了應用呼叫介面 (API)抽象物件,並未進行物件模組的實作;實作 dojo/promise/Promise 介面的物件模組是 dojo/Deferred。透過 dojo/Deferred 則另外實作了 dojo/promise/all, dojo/promise/first 及 dojo/when 三個物件模組。

範例

Script


then():傳入三個函式作為參數,

  1. callBack() 是在狀態為「完成」(resolved)時所要執行的作業。
  2. errBack() 則是在狀態為「拒絕」(rejected) 時所要執行的作業。
  3. progBack() 則是在作業進行時,進度改變時所要執行的作業。

cancel():為收到「取消」信號時,所要執行的作業。
isResolved(), isRejected(), isFulfilled() 及 isCanceled() 則傳回 true 或 false,表示該 Promise 在呼叫這些函式時,當時所處於的狀態。