《DOM編程藝術(shù)》三、最佳實(shí)踐


title: 《DOM編程藝術(shù)》三、最佳實(shí)踐
date: 2017-06-03 10:10:16
tags: DOM編程藝術(shù)


1、平穩(wěn)退化和漸進(jìn)增強(qiáng)

什么是平穩(wěn)退化

不管你想通過javascript個(gè)改變哪個(gè)網(wǎng)頁的行為,都必須三思而后行,首先要確認(rèn),為這個(gè)網(wǎng)頁增加這種額外的行為是否有必要。

在所有的javascript特效當(dāng)中,最臭名昭著的莫過于那些在人們打開網(wǎng)頁時(shí)彈出的廣告窗口,不幸的是有不少用戶為此干脆徹底禁用了javascript,這是一個(gè)典型的濫用javascript的例子,從技術(shù)上講彈窗解決了如何向用戶發(fā)送信息,但在實(shí)踐中,頻繁彈出的廣告窗口卻讓用戶不勝其煩,令人欣慰的是這一問題已經(jīng)收到了所有人的關(guān)注,那些不遵守用戶至上原則的網(wǎng)站都在自取滅亡。

所以如果要使用javascript就要確認(rèn),這么做會(huì)對(duì)瀏覽體驗(yàn)產(chǎn)生怎樣的影響,最重要的是,如果用戶的瀏覽器不支持或禁用了javascript的情況下仍能順利瀏覽你的網(wǎng)址,這就是平穩(wěn)退化。雖然某些功能無法使用,但最基本的操作仍能順利完成。

舉個(gè)例子

以彈出窗口的例子來說明平穩(wěn)退化的思想。這里并不是指在加載網(wǎng)頁時(shí)彈出,而是點(diǎn)擊后彈出,例如服務(wù)條款,郵費(fèi)列表等等。

javascript使用window.open(url,name,features)來創(chuàng)建新的瀏覽器窗口。

  • 參數(shù)1:新窗口里頁面的url地址,省略這個(gè)參數(shù)就是一個(gè)空白網(wǎng)頁。

  • 參數(shù)2:新窗口的名字,代碼可以通過這個(gè)名字與新窗口交互。

  • 參數(shù)3:以逗號(hào)分隔的字符串,包括新窗口尺寸(工具條、菜單條、初始顯示位置等等)。

function popUp(winURL){
    window.open(winURL,"popup","width=320,height=480");
}

這個(gè)函數(shù)將打開一個(gè)320x480像素的新窗口"popup"。

使用popUp函數(shù)的一個(gè)辦法是使用偽協(xié)議。

真協(xié)議用來在因特網(wǎng)上的計(jì)算機(jī)之間傳輸數(shù)據(jù)包,比如HTTP、FTP協(xié)議等,協(xié)議則是一種非標(biāo)準(zhǔn)化的協(xié)議。

<a href = "javascript:popUp('http://www.example.com/');return false;">Example</a>

通過"javascript:"為協(xié)議調(diào)用popUp()函數(shù)。

<a href = "#" onclick = "popUp('http://www.example.com/');return false;">Example</a>

這是內(nèi)嵌式的事件處理函數(shù),這個(gè)鏈接的href沒什么用,所以用"#",表示一個(gè)空連接,實(shí)際工作由onclick完成。

但是以上兩種方法都很糟糕,因?yàn)樗鼈兌疾荒芷椒€(wěn)退化。有以下兩點(diǎn)原因。

  1. 用戶如果禁用了javascript功能,這樣的鏈接將毫無作用。

  2. 第二點(diǎn)是不利于搜索引擎排名,搜索機(jī)器人瀏覽web頁的目的是把各種網(wǎng)頁添加到搜索引擎的數(shù)據(jù)庫,很少有機(jī)器人能理解javascript代碼。

其實(shí)為javascript代碼預(yù)留退路很簡(jiǎn)單,給href設(shè)置真實(shí)的URL地址。

<a  onclick = "popUp('http://www.example.com/');return false;">Example</a> 

這樣即使javascript被禁用,這個(gè)鏈接也不是失效的,只是功能上打了點(diǎn)折扣,這是一個(gè)經(jīng)典的平穩(wěn)退化的例子。

漸進(jìn)增強(qiáng)

所謂"漸進(jìn)增強(qiáng)"就是用一些額外的信息層去包裹原始數(shù)據(jù),按照"漸進(jìn)增強(qiáng)"原則創(chuàng)建出來的網(wǎng)頁幾乎都符合"平穩(wěn)退化"原則,在一個(gè)網(wǎng)頁中,良好的內(nèi)容就是一切,只有正確的使用標(biāo)記語言才能對(duì)內(nèi)容做出準(zhǔn)確的描述,CSS指令構(gòu)成了一個(gè)表示層使文檔呈現(xiàn)出各種模式,但即使去掉這個(gè)表示層,文檔的內(nèi)容也依然可以訪問。

2、分離javascript

就像css那樣把style寫到html文檔中,雖然可以用,但是這種做法弊大于利,最好的方法是把樣式信息存入一個(gè)外部文件。在文檔的head部分用<link>標(biāo)簽調(diào)用這個(gè)文件,這樣更容易閱讀和理解,樣式信息也更容易更改,不用去文檔里逐一搜索和替換,這個(gè)結(jié)論同樣適用于javascript。

現(xiàn)在我要把上面彈窗例子中的onclick事件分離出來。具體步驟如下:

  1. 把文檔里的所有鏈接全放入一個(gè)數(shù)組里。

  2. 遍歷數(shù)組。

  3. 如果某個(gè)鏈接的class屬性等于popup,就表示這鏈接在被點(diǎn)擊時(shí)應(yīng)該調(diào)用popUp()函數(shù)

window.onload = function(){
    if(!document.getElementsByTagName) return false;
    var links = document.getElementsByTagName('a');
    if(links.length > 0){
        for(var i = 0;i < links.length;i++){
            if(links[i].getAttribute('class') == 'popup'){
                links[i].onlcick = function(){
                    popUp(this.getAttribute('href'));
                    return false;
                }
            }
        }
    }
}

以上代碼把調(diào)用popUp()函數(shù)添加到有關(guān)的鏈接上,存入一個(gè)外部javascript文件中。

這里使用了window.onload事件,當(dāng)onload事件觸發(fā)時(shí)代表整個(gè)文檔已經(jīng)加載完畢,當(dāng)然也包括DOM樹,我要讓HTML文檔先加載這樣才可以生成DOM樹,起碼要在DOM樹生成后才可以加載javascript文件,否則獲取不到文檔中的各個(gè)元素,即使把javascript文件放到body的底部,也不能保證哪個(gè)先加載結(jié)束,瀏覽器可能一次加載多個(gè)文件,因?yàn)閖avascript加載時(shí)文檔可能還沒加載完成,所以DOM也沒有加載完,很多功能會(huì)無法使用。

3、向后兼容性

上面的代碼中,針對(duì)訪問者可能未啟用javascript功能的情況,需要進(jìn)行對(duì)象檢測(cè),在這里用if語句檢測(cè)訪問者的瀏覽器是否支持document.getElementsByTagName方法。如果不支持,就不會(huì)再繼續(xù)執(zhí)行,直接return false;這是一種很常見的向后兼容的方法,適用于很多地方。

4、性能考慮

在上面案例的for循環(huán)開始前檢測(cè)是否獲取到了a元素,沒有的話后面的代碼也沒必要執(zhí)行,這里將所有a元素存入link變量。出入對(duì)性能考慮,我們應(yīng)該檢查查詢DOM中某些元素的操作,搜索整個(gè)DOM樹對(duì)性能并沒有好處,總之把搜索結(jié)果保存在一個(gè)全局變量里,或者把一組元素直接以參數(shù)形式傳遞給函數(shù),是最好的方法。

另外,js文件在HTML標(biāo)簽中的位置對(duì)頁面初次加載時(shí)間也有很大影響,通常我習(xí)慣放在head中,但位于head中的腳本會(huì)導(dǎo)致瀏覽器無法并行加載其他文件。
根絕HTTP規(guī)范,瀏覽器每次從一個(gè)域名中最多可能同時(shí)下載兩個(gè)文件,所以把script標(biāo)簽放到文檔末尾,</body>之前可以讓頁面加載更快

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 前言 歸根結(jié)底,代碼都是思想和概念的體現(xiàn)。沒人能把一種程序設(shè)計(jì)語言的所有語法和關(guān)鍵字都記住,可以查閱參考書來解決。...
    朱細(xì)細(xì)閱讀 2,979評(píng)論 4 14
  • 本章內(nèi)容 平穩(wěn)退化 確保網(wǎng)頁在沒有JS的情況下也能正常工作。 分離JS 把網(wǎng)頁的結(jié)構(gòu)和內(nèi)容與JS腳本的動(dòng)作行為分開...
    fumier閱讀 270評(píng)論 0 0
  • 前兩章的基礎(chǔ)內(nèi)容自己之前的JavaScript筆記已記錄過,就不再贅述,直接從第三章Dom開始,Dom內(nèi)容之前也有...
    我是劉高興閱讀 593評(píng)論 2 11
  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)...
    _Yfling閱讀 13,814評(píng)論 1 92
  • 看見人的故事——簡(jiǎn)評(píng)《看見》 新書《看見》的扉頁上,柴靜只用了簡(jiǎn)單的幾個(gè)字介紹自己:1976年生,主持過夜色溫柔、...
    唐三葬閱讀 186評(píng)論 0 0