《DOM編程藝術(shù)》六卦绣、充實(shí)文檔內(nèi)容


title: 《DOM編程藝術(shù)》六诀黍、充實(shí)文檔內(nèi)容
date: 2017-06-03 10:28:24
tags: DOM編程藝術(shù)


這一章將繼續(xù)在實(shí)踐中應(yīng)用動(dòng)態(tài)創(chuàng)建標(biāo)記

1满钟、不應(yīng)該做什么

從技術(shù)上講嘴拢,可以把任何內(nèi)容動(dòng)態(tài)添加到網(wǎng)頁上桩盲,但重要的內(nèi)容不要這么做,因?yàn)檫@樣一來席吴,javascript就沒有任何空間去平穩(wěn)退化赌结,如果缺乏javascript的支持,用戶會(huì)永遠(yuǎn)看不到重要的內(nèi)容孝冒,而且各大搜索引擎也不支持javascript柬姚。

漸進(jìn)增強(qiáng)和平穩(wěn)退化兩項(xiàng)原則要牢記在心,在這里再次總結(jié)一下這兩項(xiàng)重要的原則迈倍。

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

應(yīng)該從最核心的部分伤靠,也就是從內(nèi)容開始,應(yīng)該根據(jù)內(nèi)容使用標(biāo)記實(shí)現(xiàn)良好的結(jié)構(gòu)啼染,然后再逐步加強(qiáng)這些內(nèi)容宴合,這些增強(qiáng)工作既可以是通過css改進(jìn)呈現(xiàn)效果,也可以是通過DOM添加各種行為迹鹅,如果你正在使用DOM添加核心內(nèi)容卦洽,那么添加的時(shí)機(jī)未免太遲,核心內(nèi)容應(yīng)在剛開始寫文檔時(shí)就成為文檔的組成部分斜棚。

平穩(wěn)退化

漸進(jìn)增強(qiáng)的實(shí)現(xiàn)必然支持平穩(wěn)退化阀蒂,如果你按照漸進(jìn)增強(qiáng)的原則去充實(shí)內(nèi)容,你為文檔添加的樣式和行為自然就支持平穩(wěn)退化弟蚀。那些缺乏必要的css和DOM支持的訪問者仍可以訪問到你的核心內(nèi)容蚤霞,如果用javascript去添加這些內(nèi)容,它就沒法支持平穩(wěn)退化义钉,不支持javascript就看不到內(nèi)容昧绣。

2、內(nèi)容

和往常一樣捶闸,任何網(wǎng)頁都以內(nèi)容為出發(fā)點(diǎn)夜畴,現(xiàn)在拿下面這段內(nèi)容作為出發(fā)點(diǎn)拖刃。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>解釋文檔DOM</title>
    <style>
        body {
            font-family:'Helvetica','Arial',sans-serif;
            font-size: 10pt;
        }
        abbr {
            text-decoration: none;
            border: 0;
            font-style: normal;
        }
    </style>
</head>
<body>
    <h1>什么是DOM</h1>
    <p><abbr title="萬維網(wǎng)聯(lián)盟">W3C</abbr>將<abbr title="文檔對(duì)象模型">DOM</abbr>定義為:</p>
    <blockquote cite="http://www.w3.org/DOM/">
        <p>一個(gè)平臺(tái)和語言中立的接口,將允許程序和腳本動(dòng)態(tài)訪問和更新的內(nèi)容贪绘,結(jié)構(gòu)和風(fēng)格的文檔兑牡。</p>
    </blockquote>
    <p>這是一個(gè)<abbr title="應(yīng)用程序設(shè)計(jì)接口">API</abbr>可以用來瀏覽<abbr title="超文本標(biāo)記語言">HTML</abbr>和<abbr title="可擴(kuò)展標(biāo)記語言">XML</abbr>文檔。</p>
</body>
</html>
image

<abbr>標(biāo)簽用于縮略語的顯示税灌,默認(rèn)情況會(huì)顯示為帶有下劃線或下劃點(diǎn)均函,但是通過css的設(shè)置已經(jīng)代替了瀏覽器的默認(rèn)樣式。

<abbr>的title屬性在瀏覽器里是隱藏的垄琐,有些瀏覽器會(huì)在你把鼠標(biāo)指針懸停在縮略語上時(shí)边酒,將它的title屬性顯示為一個(gè)彈出式的提示消息,這也是瀏覽器所使用的默認(rèn)行為狸窘,而不同瀏覽器的默認(rèn)樣式也不盡相同。所以就像剛才用css樣式去代替瀏覽器默認(rèn)樣式那樣坯认,我們也可以用DOM去改變?yōu)g覽器的默認(rèn)行為翻擒。

3、顯示縮略語

下面我要做的是將<abbr>標(biāo)簽中的title屬性集中起來顯示在一個(gè)頁面牛哺,我希望得到的定義列表是這個(gè)樣子:

<dl>
    <dt>W3C</dt>
    <dd>萬維網(wǎng)聯(lián)盟</dd>
    <dt>DOM</dt>
    <dd>文檔對(duì)象模型</dd>
    <dt>API</dt>
    <dd>應(yīng)用程序設(shè)計(jì)接口</dd>
    <dt>HTML</dt>
    <dd>超文本標(biāo)記語言</dd>
    <dt>XML</dt>
    <dd>可擴(kuò)展標(biāo)記語言</dd>
</dl>

用DOM來具體實(shí)現(xiàn)這個(gè)定義列表的步驟如下:

  1. 遍歷這份文檔中的所有<abbr>元素陋气。

  2. 保存每個(gè)<abbr>元素的title屬性。

  3. 保存每個(gè)<abbr>元素包含的文本引润。

  4. 創(chuàng)建一個(gè)<dl>自定義列表元素巩趁。

  5. 遍歷剛才保存的title屬性和<abbr>元素的文本。

  6. 創(chuàng)建一個(gè)<dt>標(biāo)題元素淳附。

  7. <abbr>元素的文本插入到這個(gè)<dt>元素议慰。

  8. 創(chuàng)建一個(gè)<dd>列表項(xiàng)元素。

  9. 把title屬性插入到這個(gè)<dd>元素奴曙。

  10. <dt>元素追加到第4步創(chuàng)建的<dl>元素上别凹。

  11. <dd>元素追加到第4步創(chuàng)建的<dl>元素上。

  12. <dl>元素追加到explanation.html文檔的body元素上洽糟。

按照上面的思路我將編寫一個(gè)displayAbbreviations函數(shù)炉菲,并存入Enrich_document_content.js中。

function displayAbbreviations(){
    if(!document.getElementsByTagName || !document.createElement || !document.createTextNode){
        return false;
    }
    // 取得所有縮略詞
    var abbreviations = document.getElementsByTagName('abbr');
    if(abbreviations.length < 1) return false;
    var defs = new Array();
    // 便利這些縮略詞
    for(var i = 0;i < abbreviations.length; i++){
        var current_abbr = abbreviations[i];
        var definition = current_abbr.getAttribute('title');
        var key = current_abbr.lastChild.nodeValue;
        defs[key] = definition;
    }
    // 創(chuàng)建定義列表
    var dlist = document.createElement('dl');
    // 遍歷定義
    for(key in defs){
        var definition = defs[key];
        // 創(chuàng)建定義標(biāo)題
        var dtitle = document.createElement('dl');
        var dtitle_text = document.createTextNode(key);
        dtitle.appendChild(dtitle_text);
        // 創(chuàng)建定義描述
        var ddesc = document.createElement('dd');
        var ddesc_text = document.createTextNode(definition);
        ddesc.appendChild(ddesc_text);
        // 把它們添加到定義列表
        dlist.appendChild(dtitle);
        dlist.appendChild(ddesc);
    }
    // 創(chuàng)建標(biāo)題
    var header = document.createElement('h2');
    var header_text = document.createTextNode('縮略詞');
    header.appendChild(header_text);
    // 把標(biāo)題添加到頁面主體
    document.body.appendChild(header);
    // 把定義列表添加到頁面主體
    document.body.appendChild(dlist);
}
image

現(xiàn)在已經(jīng)可以在頁面顯示出這個(gè)定義列表坤溃,不要忘記使用addLoadEvent函數(shù)加載拍霜。下面解析一下這個(gè)函數(shù)。

第一步仍然是檢查我用到的DOM方法是否被支持薪介。

第二步是遍歷獲取到的所有<abbr>元素祠饺,為了防止html中沒有<abbr>元素,所以在遍歷之前也做了檢查昭灵,避免javascript報(bào)錯(cuò)吠裆。

第三步用數(shù)組保存<abbr>元素的文本和title屬性伐谈,當(dāng)一個(gè)元素中只有一個(gè)子節(jié)點(diǎn),用lastChild獲取其子節(jié)點(diǎn)是一個(gè)好的方法试疙,這里將文本作為數(shù)組的下標(biāo)使用诵棵,將字符串作為數(shù)組的下標(biāo)也是一種常用的方式,不要被數(shù)組的下標(biāo)通常為數(shù)字就被禁錮住想法祝旷。

第四步用for...in循環(huán)履澳,去遍歷之前的數(shù)組,for...in是遍歷用字符串作為下標(biāo)的數(shù)組的首選怀跛,將下標(biāo)(key)和下標(biāo)對(duì)應(yīng)的值(value)添加到<dt><dl>元素中距贷。

第五步是將這個(gè)定義列表和標(biāo)題插入到body中,這一步?jīng)]什么特別的吻谋。

4忠蝗、displayAbbreviations函數(shù)的兼容性問題

按理說這個(gè)函數(shù)即檢查了方法、又全部使用的DOM方法漓拾,應(yīng)該不存在兼容性問題阁最,但問題還是有,就是有的瀏覽器不支持<abbr>元素骇两,如果是這樣那么不僅沒有縮略語列表速种,還會(huì)導(dǎo)致javascript報(bào)錯(cuò)。

出現(xiàn)這個(gè)隱患低千,如果現(xiàn)在去替換<abbr>元素太過麻煩配阵,不論何時(shí),要替換html中的元素都不應(yīng)該作為首選示血。所以保證displayAbbreviations函數(shù)在IE中能夠平穩(wěn)退化沒這個(gè)方案實(shí)現(xiàn)起來最簡單棋傍,也就是如果瀏覽器不支持<abbr>元素就可以提前退出。

接下來要解決這個(gè)兼容性問題矾芙,做到平穩(wěn)退化舍沙,我要在第一個(gè)for循環(huán)中加入一個(gè)判斷。if(current_abbr.childNodes.length < 1) continue;這條語句會(huì)讓當(dāng)前元素沒有子節(jié)點(diǎn)的話就進(jìn)入下一次循環(huán)剔宪,不支持<abbr>元素的瀏覽器在統(tǒng)計(jì)<abbr>元素的子節(jié)點(diǎn)個(gè)數(shù)總會(huì)返回錯(cuò)誤值拂铡。

此時(shí)因?yàn)閐efs數(shù)組是空的,所以它將不會(huì)創(chuàng)建出任何<dt><dd>元素葱绒,在for...in循環(huán)之后感帅,寫一個(gè)函數(shù)出口,if(dlist.childNodes.length < 1) return false;如果dlist沒有子節(jié)點(diǎn)地淀,那么直接跳出函數(shù)失球,這樣就避免了報(bào)錯(cuò)的可能性。以下是改進(jìn)后的代碼

function displayAbbreviations(){
    if(!document.getElementsByTagName || !document.createElement || !document.createTextNode){
        return false;
    }
    // 取得所有縮略詞
    var abbreviations = document.getElementsByTagName('abbr');
    if(abbreviations.length < 1) return false;
    var defs = new Array();
    // 便利這些縮略詞
    for(var i = 0;i < abbreviations.length; i++){
        var current_abbr = abbreviations[i];
        if(current_abbr.childNodes.length < 1) continue;
        var definition = current_abbr.getAttribute('title');
        var key = current_abbr.lastChild.nodeValue;
        defs[key] = definition;
    }
    // 創(chuàng)建定義列表
    var dlist = document.createElement('dl');
    // 遍歷定義
    for(key in defs){
        var definition = defs[key];
        // 創(chuàng)建定義標(biāo)題
        var dtitle = document.createElement('dl');
        var dtitle_text = document.createTextNode(key);
        dtitle.appendChild(dtitle_text);
        // 創(chuàng)建定義描述
        var ddesc = document.createElement('dd');
        var ddesc_text = document.createTextNode(definition);
        ddesc.appendChild(ddesc_text);
        // 把它們添加到定義列表
        dlist.appendChild(dtitle);
        dlist.appendChild(ddesc);
    }
    if(dlist.childNodes.length < 1) return false;
    // 創(chuàng)建標(biāo)題
    var header = document.createElement('h2');
    var header_text = document.createTextNode('縮略詞');
    header.appendChild(header_text);
    // 把標(biāo)題添加到頁面主體
    document.body.appendChild(header);
    // 把定義列表添加到頁面主體
    document.body.appendChild(dlist);
}

如果瀏覽器不支持<abbr>標(biāo)簽,也不會(huì)出任何錯(cuò)誤实苞,但是也會(huì)看不到縮略語列表豺撑,不過縮略語列表也算不上頁面必不可少的組成部分,如果真的是必不可少的內(nèi)容黔牵,從一開始就應(yīng)該把它包括在標(biāo)記里聪轿。

5、顯示文獻(xiàn)來源鏈接表

在這個(gè)案例中猾浦,還有另一個(gè)增強(qiáng)文檔的例子陆错,先來看看html中這段標(biāo)記。

<blockquote cite="http://www.w3.org/DOM/">
    <p>一個(gè)平臺(tái)和語言中立的接口金赦,將允許程序和腳本動(dòng)態(tài)訪問和更新的內(nèi)容音瓷,結(jié)構(gòu)和風(fēng)格的文檔。</p>
</blockquote>

<blockquote>元素包含一個(gè)cite屬性夹抗,它可以是一個(gè)URL地址绳慎,告訴人們<blockquote>元素的內(nèi)容引自哪里,從理論上講這是一個(gè)文獻(xiàn)資料與縣官網(wǎng)頁鏈接起來的好辦法兔朦。但實(shí)際上瀏覽器會(huì)完全忽略cite屬性偷线,所以我要把這些信息收集起來,以一種更有意義的方式把它們顯示在網(wǎng)頁上沽甥。

按照以下步驟完成displayCitetions函數(shù),并存入Enrich_document_content.js文件中乏奥。

  1. 遍歷這個(gè)文檔里所有<blockquote>元素摆舟。

  2. <blockquote>元素提取出cite屬性的值。

  3. 創(chuàng)建一個(gè)標(biāo)識(shí)文本是source的鏈接邓了。

  4. 把這個(gè)鏈接賦值為<blockquote>元素的cite屬性值恨诱。

  5. 把這個(gè)鏈接插入到文獻(xiàn)節(jié)選的末尾。

function displayCitetions(){
    if(!document.getElementsByTagName || !document.createElement || !document.createTextNode){
        return false;
    }
    // 取得所有引用
    var quotes = document.getElementsByTagName('blockquote');
    // 遍歷引用
    for(var i = 0;i < quotes.length;i++){
        // 如果沒有cite屬性骗炉,繼續(xù)循環(huán)
        if(!quotes[i].getAttribute('cite')) continue;
        // 保存cite屬性
        var url = quotes[i].getAttribute('cite');
        // 取得引用中的所有元素節(jié)點(diǎn)
        var quoteChildren = quotes[i].getElementsByTagName('*');
        // 如果沒有元素節(jié)點(diǎn)進(jìn)入下一次循環(huán)
        if(quoteChildren.length < 1) continue;
        // 取得引用中的最后一個(gè)元素節(jié)點(diǎn)
        var elem = quoteChildren[quoteChildren.length - 1];
        // 創(chuàng)建標(biāo)記
        var link = document.createElement('a');
        var link_text = document.createTextNode('source');
        link.appendChild(link_text);
        link.setAttribute('href',url);
        var superscript = document.createElement('sup');
        superscript.appendChild(link);
        // 把標(biāo)記添加到引用中的最后一個(gè)元素節(jié)點(diǎn)
        elem.appendChild(superscript)
    }
}
image

函數(shù)執(zhí)行完畢后這個(gè)<blockquote>元素的引用將會(huì)添加到段落最后的source上標(biāo)中照宝。下面來解析一下這個(gè)函數(shù)。

第一部分是篩選出cite屬性句葵,再去獲取<blockquote>元素的最后一個(gè)子節(jié)點(diǎn)厕鹃,這里<blockquote>的lastChild有可能是個(gè)換行符,所以在函數(shù)中是獲取的<blockquote>下的所有元素對(duì)象乍丈,這樣就可以方便的獲取<blockquote>的最后一個(gè)子元素剂碴。

第二部分是創(chuàng)建鏈接和插入鏈接,最終讓<sup>元素包含<a>元素轻专,而<a>元素href屬性保存了cite的屬性值忆矛,也就是一個(gè)url地址。最后將<sup>元素插入到<blockquote>元素的最后请垛。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末催训,一起剝皮案震驚了整個(gè)濱河市洽议,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌漫拭,老刑警劉巖亚兄,帶你破解...
    沈念sama閱讀 211,348評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異嫂侍,居然都是意外死亡儿捧,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門挑宠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來菲盾,“玉大人,你說我怎么就攤上這事各淀±良” “怎么了?”我有些...
    開封第一講書人閱讀 156,936評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵碎浇,是天一觀的道長临谱。 經(jīng)常有香客問我,道長奴璃,這世上最難降的妖魔是什么悉默? 我笑而不...
    開封第一講書人閱讀 56,427評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮苟穆,結(jié)果婚禮上抄课,老公的妹妹穿的比我還像新娘。我一直安慰自己雳旅,他們只是感情好跟磨,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,467評(píng)論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著攒盈,像睡著了一般抵拘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上型豁,一...
    開封第一講書人閱讀 49,785評(píng)論 1 290
  • 那天僵蛛,我揣著相機(jī)與錄音,去河邊找鬼偷遗。 笑死厉膀,一個(gè)胖子當(dāng)著我的面吹牛囤屹,可吹牛的內(nèi)容都是我干的悄雅。 我是一名探鬼主播愤兵,決...
    沈念sama閱讀 38,931評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了泪电?” 一聲冷哼從身側(cè)響起般妙,我...
    開封第一講書人閱讀 37,696評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎相速,沒想到半個(gè)月后碟渺,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,141評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡突诬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,483評(píng)論 2 327
  • 正文 我和宋清朗相戀三年苫拍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片旺隙。...
    茶點(diǎn)故事閱讀 38,625評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡绒极,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蔬捷,到底是詐尸還是另有隱情垄提,我是刑警寧澤,帶...
    沈念sama閱讀 34,291評(píng)論 4 329
  • 正文 年R本政府宣布周拐,位于F島的核電站铡俐,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏妥粟。R本人自食惡果不足惜审丘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,892評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望勾给。 院中可真熱鬧备恤,春花似錦、人聲如沸锦秒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽旅择。三九已至,卻和暖如春侣姆,著一層夾襖步出監(jiān)牢的瞬間生真,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國打工捺宗, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留柱蟀,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓蚜厉,卻偏偏與公主長得像长已,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,492評(píng)論 2 348

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

  • 前言 歸根結(jié)底术瓮,代碼都是思想和概念的體現(xiàn)康聂。沒人能把一種程序設(shè)計(jì)語言的所有語法和關(guān)鍵字都記住,可以查閱參考書來解決胞四。...
    朱細(xì)細(xì)閱讀 2,920評(píng)論 4 14
  • 重要原則 漸進(jìn)增強(qiáng) 從核心部分恬汁,內(nèi)容開始。根據(jù)內(nèi)容使用標(biāo)記實(shí)現(xiàn)良好的結(jié)構(gòu)辜伟,然后通過CSS改進(jìn)呈現(xiàn)效果氓侧,或者通過DO...
    fumier閱讀 228評(píng)論 0 0
  • 本篇筆記是本書的第七、八导狡、九章內(nèi)容约巷,前六章知識(shí)可查看JavaScript Dom編程藝術(shù)學(xué)習(xí)筆記1 第七章 動(dòng)態(tài)創(chuàng)...
    我是劉高興閱讀 427評(píng)論 1 2
  • 1.JQuery 基礎(chǔ) 改變web開發(fā)人員創(chuàng)造搞交互性界面的方式。設(shè)計(jì)者無需花費(fèi)時(shí)間糾纏JS復(fù)雜的高級(jí)特性烘豌。 1....
    LaBaby_閱讀 1,167評(píng)論 0 1
  • 連續(xù)半個(gè)月载庭,我把自己鬧鐘調(diào)為5點(diǎn),希望這個(gè)時(shí)候起來可以做一些自己想做的事廊佩。并希望能夠在連續(xù)這樣做了3個(gè)月之后囚聚,可以...
    七素_閱讀 133評(píng)論 0 0