編寫分離式(unobstrusive)代碼意味著對HTML內容的完全分離:資料來自伺服器端,javascript代碼用來動態化和互動。這種分離的好處是在不同瀏覽器之間使用是可以完全降級或升級運行,對於進階特性瀏覽器提供更豐富的互動,不支援進階特性的瀏覽器可以降級運行其所支援的部分。
一、DOM
DOM是表達XML文檔的應用最廣泛的方式,雖然可能未必是最快或者最輕量級和最易使用的,但是大部分web開發語言都提供了其實現。javascript最終的操作都是和網頁裡的HTML元素進行互動,而HTML是XML的一個子集,因此DOM是簡化操作的出色工具,是開發分離式javascript代碼的第一步,無非就是提供了以下幾個簡化的操作:擷取或修改特定HTML元素、對元素的屬性進行修改、綁定事件及編寫處理函數。
1、概念DOM(文件物件模型)是W3C制定的一個表達XML文檔的標準,可以把XML的DOM表達方式看做一棵導航樹,一切術語都與家譜術語類似(parent、child、sibling)。節點包含了nodeType、nodeValue、nodeName,每個節點有都包含指向父節點、子節點、相鄰兄弟節點的指標。2、處理空格使用while迴圈尋找是否為空白的節點,並測試節點類型nodeType是否為1、2、3等,否則就刪除繼續尋找下一個節點。3.、擷取和尋找元素
getElementById("id"):從所有元素中尋找屬性ID為id的元素,速度很快,定位準確,但是不能出現ID同名的元素。
getElementByTagName("tag"):運行於任何元素下,找出標籤名稱為tag的節點列表Nodelist,類似於數組,但是不支援push、pop、shift等javascript數組操作方法。
innerHTML:用來設定或擷取元素類的html,短小的代碼使用這個特性很快捷,但是會有一些瀏覽器不同的bug,IE中返回的都是大寫的元素字元,基於Mozilla的瀏覽器不會返回<style>元素等。
innerText:方便擷取元素下的所有文本類容,但是在由於在一些流行的瀏覽器不相容,因此有如下的替代方法
function text(e){ var t = ""; e = e.childNodes || e; for (var j = 0; j < e.length; j++){ t += e[j].nodeType != 1 ? e[j].nodeValue : text(e[j].childNodes); return t; }}
className:使用類名尋找元素,這是jquery提供的強大的選取器,同時也有css選取器,公開庫有cssQuery。
XPath:這是一種強大的純粹的XML定位方式,W3C的標準,DOM的實現也是肯定基於XPath,與CSS選取器相比運算式相對冗長,當時功能更加強大。4、等待HTML DOM載入瀏覽器渲染和操作的順序如下:html解析完畢 ——> 外部指令碼和樣式表載入 ——> 指令碼在文檔內解析並執行 ——> HTML DOM完全構造起來 ——> 圖片和外部內容載入 ——> 網頁載入完成網頁頭部的外部檔案載入後會在HTML真正構造起來之前執行,這對於某些重要的情形是不能滿足要求的。補救如下:
- 等待整個頁面載入:window.onload事件綁定一個函數在頁面完全載入後觸發。
- 等待大部分DOM載入:行內的腳步在DOM構造後就可以立即執行,執行到該位置上的腳步才真正執行,也就是在頁面中途嵌入的行內腳步只能訪問該位置之前的DOM。因此可以在body結尾標籤之前才執行指令碼。
- 判斷DOM合適載入完畢:監聽DOM載入狀態,是最有效但是也是實現起來最複雜的。可以綁定windows事件那樣簡單又能獲得行內腳步執行那樣的速度。檢查DOM元素和方法是否存在:檢查要點document、document.getElementById等函數、document.body等或其他特定元素。
二、事件
事件是把所有東西粘在一起的膠水,DOM和javascript事件的結合是現代web應用程式的根基。主要有以下幾種類型事件:
- 滑鼠事件:追蹤滑鼠定位、點擊事件
- 鍵盤事件:追蹤鍵盤敲擊和上下文
- UI事件:頁面的某一方面是否覆蓋了另一方面
- 表單事件:表單輸入元素上
- 載入和錯誤事件:監聽自身載入狀態
javascript目前不存線上程,完全是非同步。代碼的運行由其他動作觸發,綁定好一個回呼函數到特定事件即可。最近的就是類比線程的就是使用setInterval加遞迴類比。事件處理的階段包括從body元素向下到發生事件的元素的捕獲階段和從發生事件的元素到最外層元素的冒泡階段,組織冒泡可以為負責的程式提供益處,同時取消瀏覽器的預設行為會在需要處理的95%的情況中有效,不同的瀏覽器處理不同,因此是分離式DOM指令碼編程的重要部分。
- 傳統綁定:對象.事件 = function (){....} 有點事簡單和穩定,不同瀏覽器運作一致,this關鍵字引用當前元素。缺點是旨在事件冒泡中允許,而非捕獲和冒泡,同時一個元素一次只能綁定一個事件處理函數
- DOM綁定:W3C提供的標準是addEventListener函數,提供三個參數:事件名稱、處理函數、啟用禁用事件捕獲的布爾標記。優點是支援設定捕獲和冒泡階段,this指向當前元素,事件對象總是可以通過處理函數的第一個參數擷取,同時可以為一個元素繫結多個事件而不會覆蓋先前綁定的事件。
- IE綁定:可以綁定多個事件,但是僅支援冒泡階段,this指向了window對象,不是當前元素,事件對象僅存在window.event參數中。同時必須以on+事件名的方式,僅IE可用。
三、javascript與CSS
在DOM和事件的互動基礎上產生了DHTML,實質是javascript與DOM元素上的CSS屬性之間的互動。
上述所有問題的討論都是為了實現分離式指令碼編程以適應不同瀏覽器而做到預留退路。首先應用程式的所有功能都要檢查(if(document && document.getElementById)),其次是使用DOM遍曆尋找的通用方法來快速存取文檔中的元素,最後是使用DOM和attachEvent/addEvenetListener函數為元素添加事件處理函數,<a href="#" onclick="dosth()...">...</a>這樣的代碼是非常不好的。
- javascript禁用:如果禁用了javascript,所有的頁面都要能工作,最明顯的就是a連結的href屬性和onclick事件。
- 連結不依賴javascript:所有的連結都不應該有破壞性,通過連結可以刪除、編輯或者修改任何使用者資料的話都應該用表單實現。
- 監聽css合適禁用
- 事件的親和力:確保事件在不適用滑鼠的情況下依然具備親和力,可以對每個人都有好處。