掌握 Ajax,第 6 部分: 建立基于 DOM 的 Web 应用程序
| 在不刷新頁面的情況下使用 DOM 改變網頁界面 |
級別: 中級 Brett McLaughlin (mailto:brett@newInstance.com?subject=建立基于 DOM 的 Web 應用程序&cc=htc@us.ibm.com), 作家兼編輯, O'Reilly Media Inc. 2006 年 10 月 12 日 本系列的上一篇文章中考察了文檔對象模型(DOM)編程中涉及到的概念——Web 瀏覽器如何把網頁看作一棵樹,現在您應該理解了 DOM 中使用的編程結構。本期教程將把這些知識用于實踐,建立一個簡單的包含一些特殊效果的 Web 頁面,所有這些都使用 JavaScript 操縱 DOM 來創(chuàng)建,不需要重新加載或者刷新頁面。前面兩期文章已經詳細介紹了文檔對象模型或者 DOM,讀者應該很清楚 DOM 是如何工作的了。(前兩期 DOM 文章以及 Ajax 系列更早文章的鏈接請參閱參考資料。)本教程中將把這些知識用于實踐。我們將開發(fā)一個簡單的 Web 應用程序,其用戶界面可根據用戶動作改變,當然要使用 DOM 來處理界面的改變。閱讀完本文之后,就已經把學習到的關于 DOM 的技術和概念付諸應用了。 假設讀者已經閱讀過上兩期文章,如果還沒有的話,請先看一看,切實掌握什么是 DOM 以及 Web 瀏覽器如何將提供給它的 HTML 和 CSS 轉化成單個表示網頁的樹狀結構。到目前為止我一直在討論的所有 DOM 原理都將在本教程中用于創(chuàng)建一個能工作的(雖然有點簡單)基于 DOM 的動態(tài) Web 頁面。如果遇到不懂的地方,可以隨時停下來復習一下前面的兩期文章然后再回來。 從一個示例應用程序開始
我們首先建立一個非常簡單的應用程序,然后再添加一點 DOM 魔法。要記住,DOM 可以移動網頁中的任何東西而不需要提交表單,因此足以和 Ajax 媲美;我們創(chuàng)建一個簡單的網頁,上面只顯示一個普通的舊式大禮帽,還有一個標記為 Hocus Pocus! 的按鈕(猜猜這是干什么的?) 初始 HTML 清單 1 顯示了這個網頁的 HTML。除了標題和表單外,只有一個簡單的圖片和可以點擊的按鈕。 清單 1. 示例應用程序的 HTML
可以在本文后面的下載中找到這段 HTML 和本文中用到的圖片。不過我強烈建議您只下載那個圖片,然后隨著本文中逐漸建立這個應用程序自己動手輸入代碼。這樣要比讀讀本文然后直接打開完成的應用程序能夠更好地理解 DOM 代碼。 查看示例網頁 這里沒有什么特別的竅門,打開網頁可以看到圖 1 所示的結果。 圖 1. 難看的大禮帽 關于 HTML 的補充說明 應該 注意的重要一點是,清單 1 和圖 1 中按鈕的類型是 button 而不是提交按鈕。如果使用提交按鈕,單擊該按鈕將導致瀏覽器提交表單,當然表單沒有 action 屬性(完全是有意如此),從而會造成沒有任何動作的無限循環(huán)。(應該自己試試,看看會發(fā)生什么。)通過使用一般輸入按鈕而不是提交按鈕,可以把 javaScript 函數和它連接起來與瀏覽器交互而無需 提交表單。
向示例應用程序添加元素 現在用一些 JavaScript、DOM 操作和小小的圖片戲法裝扮一下網頁。 使用 getElementById() 函數 顯然,魔法帽子沒有兔子就沒有看頭了。這里首先用兔子的圖片替換頁面中原有的圖片(再看看圖 1),如圖 2 所示。 圖 2. 同樣的禮帽,這一次有了兔子 完成這個 DOM 小戲法的第一步是找到網頁中表示 img 元素的 DOM 節(jié)點。一般來說,最簡單的辦法是用 getElementById() 方法,它屬于代表 Web 頁面的 document 對象。前面已經見到過這個方法,用法如下:
為 HTML 添加 id 屬性 這是非常簡單的 JavaScript,但是需要修改一下 HTML:為需要訪問的元素增加 id 屬性。也就是希望(用帶兔子的新圖片)替換的 img 元素,因此將 HTML 改為清單 2 的形式。 清單 2. 增加 id 屬性
如果重新加載(或者打開)該頁面,可以看到毫無變化,增加 id 屬性對網頁的外觀沒有影響。不過,該屬性可以幫助 JavaScript 和 DOM 更方便地處理元素。 抓住 img 元素 現在可以很容易地使用 getElementById() 了。已經有了需要元素的 ID,即 topHat,可以將其保存在一個新的 JavaScript 變量中。在 HTML 頁面中增加清單 3 所示的代碼。 清單 3. 訪問 img 元素
現在打開或重新加載該網頁同樣沒有什么驚奇的地方。雖然現在能夠訪問圖片,但是對它還什么也沒有做。
修改圖片,麻煩的辦法 完成所需修改有兩種方法:一種簡單,一種麻煩。和所有的好程序員一樣,我也喜歡簡單的辦法;但是運用較麻煩的辦法是一次很好的 DOM 練習,值得您花點時間。首先看看換圖片比較麻煩的辦法;后面再重新分析一下看看有沒有更簡單的辦法。 用帶兔子的新照片替換原有圖片的辦法如下: 創(chuàng)建新的 img 元素 通過上兩期文章應該記住 DOM 中最關鍵的是 document 對象。它代表整個網頁,提供了 getElementById() 這樣功能強大的方法,還能夠創(chuàng)建新的節(jié)點?,F在要用到的就是這最后一種性質。 具體而言,需要創(chuàng)建一個新的 img 元素。要記住,在 DOM 中一切都是節(jié)點,但是節(jié)點被進一步劃分為三種基本類型:
還有其他類型,但是這三種可以滿足 99% 的編程需要。這里需要一個 img 類型的新元素。因此需要下列 JavaScript 代碼:
這行代碼可以創(chuàng)建一個 element 類型的新節(jié)點,元素名為 img。在 HTML 中基本上就是:
要記住,DOM 會創(chuàng)建結構良好的 HTML,就是說這個目前為空的元素包括起始和結束標簽。剩下的就是向該元素增加內容或屬性,然后將其插入到網頁中。 對內容來說,img 是一個空元素。但是需要增加一個屬性 src,它指定了要加載的圖片。您也許認為要使用 addAttribute() 之類的方法,但情況并非如此。DOM 規(guī)范的制定者認為程序員可能喜歡簡潔(的確如此!),因此他們規(guī)定了一個方法同時用于增加新屬性和改變已有的屬性值:setAttribute()。 如果對已有的屬性調用 setAttribute(),則把原來的值替換為指定的值。但是,如果調用 setAttribute() 并指定一個不 存在的屬性,DOM 就會使用提供的值增加一個屬性。一個方法,兩種用途!因此需要增加下列 JavaScript 代碼:
它創(chuàng)建一個圖片元素然后設置適當的資源屬性?,F在,HTML 應該如清單 4 所示。 清單 4. 使用 DOM 創(chuàng)建新圖片
可以加載該頁面,但是不要期望有任何改變,因為目前所做的修改實際上還沒有影響頁面。另外,如果再看看任務列表中的第 5 步,就會發(fā)現還沒有調用我們的 JavaScript 函數! 獲得原始圖片的父元素 現在有了要插入的圖片,還需要找到插入的地方。但是不能將其插入到已有的圖片中,而是要將其插入到已有圖片之前然后再刪除原來的圖片。為此需要知道已有圖片的父元素,實際上這就是插入和刪除操作的真正關鍵所在。 應該記得,前面的文章中曾經指出 DOM 確實把網頁看成一棵樹,即節(jié)點的層次結構。每個節(jié)點都有父節(jié)點(樹中更高層次的節(jié)點,該節(jié)點是它的一個子級),可能還有自己的子節(jié)點。對于圖片來說,它沒有子級 —— 要記住圖片是空元素,但是它肯定有父節(jié)點。甚至不需要知道父節(jié)點是什么,但是需要訪問它。 為此,只要使用每個 DOM 節(jié)點都有的 parentNode 屬性即可,比如:
確實非常簡單!可以肯定這個節(jié)點有子節(jié)點,因為已經有了一個:原來的圖片。此外,完全不需要知道它是一個 div、p 或者頁面的 body,都沒有關系! 插入新圖片 現在得到了原來圖片的父節(jié)點,可以插入新的圖片了。很簡單,有多種方法可以添加子節(jié)點:
因為希望把新圖片放在舊圖片的位置上,需要使用 insertBefore()(后面還要使用 removeChild() 方法)。可使用下面這行 JavaScript 代碼把新圖片元素插入到原有圖片之前:
現在原圖片的父元素有了兩個 子元素:新圖片和緊跟在后面的舊圖片。必須指出,這里包圍 這些圖片的內容沒有變,而且這些內容的順序也和插入之前完全相同。僅僅是這個父節(jié)點中增加了一個子節(jié)點,即舊圖片之前的新圖片。 刪除舊圖片 現在只需要刪除舊圖片,因為網頁中只需要新圖片。很簡單,因為已經得到了舊圖片元素的父節(jié)點。只要調用 removeChild() 并把需要刪除的節(jié)點傳遞給它即可:
現在,用新圖片替換舊圖片的工作已基本完成了。HTML 應該如清單 5 所示。 清單 5. 用新圖片替換舊圖片
連接 JavaScript 最后一步,可能也是最簡單的,就是把 HTML 表單連接到剛剛編寫的 JavaScript 函數。需要每當用戶點擊 Hocus Pocus! 按鈕的時候運行 showRabbit() 函數。為此只要向 HTML 中增加一個簡單的 onClick 事件處理程序即可。
這種簡單的 JavaScript 編程應該非常容易了。將其添加到 HTML 頁面中,保存它然后在 Web 瀏覽器中打開。頁面初看起來應該和圖 1 相同,但是點擊 Hocus Pocus! 后應該看到圖 3 所示的結果。 圖 3. 兔子戲法
替換圖片,簡單的辦法 如果回顧替換圖片的步驟,再看看節(jié)點的各種方法,可能會注意到方法 replaceNode()。該方法可用于把一個節(jié)點替換為另一個節(jié)點。再考慮一下前面的步驟: 使用 replaceNode() 可以減少需要的步驟數??梢詫⒌?3 步和第 4 步合并在一起: 這看起來不是什么大事,但確實能夠簡化代碼。清單 6 說明了這種修改:去掉了 insertBefore() 和 removeChild() 方法調用。 清單 6. 用新圖片替換舊圖片(一步完成)
當然這不是什么大的修改,但是說明了 DOM 編碼中一件很重要的事:執(zhí)行一項任務通常有多種方法。如果仔細審閱可用 DOM 方法看看是否有更簡單的方法可以完成任務,很多時候都會發(fā)現可以將四五個步驟壓縮為兩三個步驟。
替換圖片,(真正)簡單的辦法 既然指出了執(zhí)行一項任務幾乎總是有更簡單的方法,現在就說明用兔子圖片替換帽子圖片的簡單得多 的辦法。閱讀本文的過程中有沒有想到這種方法?提示一下:與屬性有關。 要記住,圖片元素很大程度上是由其 src 屬性控制的,他引用了某個地方的文件(不論是本地 URI 還是外部 URL)。到目前為止,我們一直用新圖片替換圖片節(jié)點,但是直接修改已有圖片的 src 屬性要簡單得多!這樣就避免了創(chuàng)建新節(jié)點、尋找父節(jié)點和替換舊節(jié)點的所有工作,只要一步就能完成了:
這樣就夠了!看看清單 7,它顯示了這種解決方案,包括整個網頁。 清單 7. 修改 src 屬性
這是 DOM 最棒的一點:更新屬性的時候網頁馬上就會改變。只要圖片指向新的文件,瀏覽器就加載該文件,頁面就更新了。不需要重新加載,甚至不需要創(chuàng)建新的圖片元素!結果仍然和圖 3 相同,只不過代碼簡單得多了。
把兔子藏起來 現在網頁看起來很漂亮,但是仍然有點原始。雖然兔子從帽子中跳出來了,但是屏幕下方的按鈕仍然顯示 Hocus Pocus! 和調用 showRabbit()。這就是說如果在兔子出來之后仍然點擊按鈕,就是在浪費處理時間。更重要的是,它毫無用處,而沒有用的按鈕不是好東西。我們來看看能否利用 DOM 再作一些修改,無論兔子在帽子里還是出來都讓這個按鈕派上用場。 修改按鈕的標簽 最簡單的是當用戶點擊按鈕之后改變它的標簽。這樣就不會看起來像還有什么魔法,網頁中最糟糕的就是暗示用戶錯誤的東西。在修改按鈕的標簽之前需要訪問該節(jié)點,而在此之前需要引用按鈕 ID。這是老套路了,清單 8 為按鈕增加了 id 屬性。 清單 8. 增加 id 屬性
現在用 JavaScript 訪問按鈕很簡單了:
當然,您可能已經輸入了下面這行 JavaScript 來改變按鈕的標簽值。這里再次用到了 setAttribute():
通過這個簡單的 DOM 操作,兔子跳出來之后按鈕的標簽馬上就會改變?,F在,HTML 和完成的 showRabbit() 函數如清單 9 所示。 清單 9. 完成的網頁
把兔子收回去 從此新的按鈕標簽中可能已經猜到,現在要把兔子收回帽子中去?;旧虾头磐米映鰜硗耆喾?#xff1a;將圖片的 src 屬性再改回舊圖片。創(chuàng)建一個新的 JavaScript 函數來完成這項任務:
實際上僅僅把 showRabbit() 函數的功能翻轉了過來。將圖片改為原來的沒有兔子的大禮帽,抓取按鈕,將標簽改為 Hocus Pocus!
事件處理程序 現在這個示例應用程序有一個大問題:雖然按鈕的標簽 改變了,但是單擊按鈕時的動作沒有 變。幸運的是,當用戶單擊按鈕時可以使用 DOM 改變事件或者發(fā)生的動作。因此,如果按鈕上顯示 Get back in that hat!,點擊的時候需要運行 hideRabbit()。相反,一旦兔子藏了起來,按鈕又返回來運行 showRabbit()。
查看 HTML 就會發(fā)現這里處理的事件是 onClick。在 JavaScript 中,可以通過按鈕的 onclick 的屬性來引用該事件。(要注意,在 HTML 中該屬性通常稱為 onClick,其中 C 大寫;而在 JavaScript 中則稱為 onclick,全部小寫。)因此可以改變按鈕觸發(fā)的事件:只要賦給 onclick 屬性一個新的函數。 但是有點細微的地方:onclick 屬性需要提供函數引用——不是函數的字符串名稱,而是函數本身的引用。在 JavaScript 中,可以按名稱引用函數,不需要帶括號。因此可以這樣修改點擊按鈕時執(zhí)行的函數:
因此在 HTML 中作這種修改很簡單??纯辞鍐?10,它切換按鈕觸發(fā)的函數。 清單 10. 改變按鈕的 onClick 函數
這樣就得到了一個完成的、可以使用的 DOM 應用程序。自己試試吧!
結束語 現在您應該非常熟悉 DOM 了。前面的文章介紹了使用 DOM 所涉及到的基本概念,詳細地討論了 API,現在又建立一個簡單的基于 DOM 的應用程序。一定要花點時間仔細閱讀本文,并自己嘗試一下。 雖然這是專門討論文檔對象模型的系列文章的最后一期,但肯定還會看到其他關于 DOM 的文章。事實上,如果在 Ajax 和 JavaScript 世界中不使用 DOM 就很難做多少事,至少在一定程度上如此。無論要創(chuàng)建復雜的突出顯示還是移動效果,或者僅僅處理文本塊或圖片,DOM 都提供了一種非常簡單易用的訪問 Web 頁面的方式。 如果對如何使用 DOM 仍然感覺沒有把握,花點時間溫習一下這三篇文章;本系列的其他文章在使用 DOM 的時候不再多作解釋,讀者也不希望迷失在這些細節(jié)之中而忽略關于其他概念的重要信息,比如 XML 和 JSON。為了保證能夠熟練地使用 DOM,自己編寫幾個基于 DOM 的應用程序試試,這樣就很容易理解后面將要討論的一些數據格式問題了。
下載
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
TrackBack:http://www.ibm.com/developerworks/cn/xml/wa-ajaxintro6/
轉載于:https://www.cnblogs.com/hdjjun/archive/2008/07/04/1235652.html
總結
以上是生活随笔為你收集整理的掌握 Ajax,第 6 部分: 建立基于 DOM 的 Web 应用程序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: strcpy和memcpy的区别 | s
- 下一篇: IOS 开发中判断NSString是否为