從原型鏈看DOM--Comment,CDATASection,DocumentType,DocumentFragment,Attr類型

来源:http://www.cnblogs.com/venoral/archive/2016/04/17/5360730.html
-Advertisement-
Play Games

這次總結的是剩下的這些DOM類型節點,可能你見過卻不經常使用但是瞭解一下總是好的,可以加深對DOM體系的整體理解~。本篇要介紹的是Comment,CDATASection,DocumentType,DocumentFragment,Attr類型。Comment類型 原型鏈繼承關係為comment實例 ...


這次總結的是剩下的這些DOM類型節點,可能你見過卻不經常使用但是瞭解一下總是好的,可以加深對DOM體系的整體理解~。本篇要介紹的是Comment,CDATASection,DocumentType,DocumentFragment,Attr類型。

Comment類型

原型鏈繼承關係為comment實例.__proto__->Comment.prototype->CharacterData.prototype->Node.prototype->EventTarget.prototype->Object.prototype。

與Text節點類似,也可以通過nodeValue或data訪問註釋的內容。

var com=document.createComment('I am comment');
com;// <!--I am comment-->
com.data;// "I am comment"
com.nodeValue;// "I am comment"

註釋在DOM中通過Comment類型來表示的,Comment節點具有以下特征:

  • nodeType值為8
  • nodeName值為"#comment"
  • nodeValue值是註釋內容
  • parentNode可能為Document或Element
  • 沒有子節點

1.使用document.createComment()併為其傳遞註釋文本可創建註釋節點。createComment繼承自Document.prototype。

2.瀏覽器對於註釋節點的處理有些差距
(1).當註釋位於HTML元素外 :Chrome,<=IE9處理HTML元素之前的註釋節點,FF和>IE9 處理之外的所有節點。  

<!--I am first comment-->
<!DOCTYPE html>
<html>
<head>
  <title></title>
</head>
<body>
</body>
</html>
<!--I am last comment-->

Chrome46.0.2490.80:只處理出現在HTML元素之前的的註釋節點,忽略出現在HTML元素之後的註釋節點。

FF44.0.2:出現在HTML元素之前之後的註釋節點都會處理。

>IE9:出現在HTML元素之前之後的註釋節點都會處理。

<=IE9:只處理HTML元素之前的註釋節點。 

註意:IE8中註釋節點和文檔聲明被當作標簽名為"!"的元素,開啟IE8模擬模式後,由於IE8不支持訪問DOM中一些API原生對象,所以通過使用getElementsByTagName()(繼承自Document.prototype)可以取得被當作元素節點的註釋節點和文檔聲明節點。


IE9沒有把註釋和文檔聲明當成元素節點,但卻將文檔聲明節點<!Doctype html>視作註釋節點。本圖測試於IE9模擬

(2).當註釋位於HTML元素內

<!DOCTYPE html>
<html>
<head>
  <title></title>
  <!-- I am comment-->
</head>
<body>
  <!-- I am comment too-->
</body>
</html>

三大瀏覽器均能解釋成註釋節點。

 

CDATASection類型

  • 瞭解XHTML

說起CDATASection類型節點,就先說起XHTML(可擴展超文本標記語言),它是將HTML作為XML的應用而重新定義的一個標準,編寫XHTML代碼的規則要比HTML嚴格很多,比如

  1. XHTML元素必須被正確嵌套
  2. XHTML元素必須被正確關閉,即使是空標簽也必須被正確關閉比如<br />,<img />,註意/與元素之間留有空格保證XHTML文檔與當今瀏覽器相容
  3. 標簽名必須用小寫字母
  4. XHTML文檔必須擁有根元素
  5. 屬性值必須加引號
  6. 屬性不能簡寫
  7. 用id屬性代替name屬性,如<a />,<img />等
  8. XHTML DTD定義了強制使用的HTML元素
  9. 所有XHTML文檔必須進行文檔類型聲明。

以下麵代碼塊為例,它們在HTML中是有效的,但是在XHTML中是無效的

<script type="text/javascript">
    function compare(a, b){
        if(a < b){
           console.log("A is less than B");
        }else if(a > b){
           console.log("A is greater than B");
        }else{
           console.log("A is equal to B");
        }
    }
</script>

在HTML中有特殊規則用以確定<script>元素中哪些內容可以被解析,但這些規則在XHTML中不適用。這裡比較語句a < b的小於號在XHTML中將被當作開始一個新標簽來解析,但作為標簽來說小於號後面又不能跟空格,因此就會導致語法錯誤如下“不合法的元素名”,所以JS代碼後面就解析不了原樣顯示在頁面上。

即使將代碼中a < b間的空格去掉變為a<b,也會提示出錯“解析屬性出錯”,畢竟b後面跟的是“)”。

避免出現這種情況的解決方式有兩種:
(1).應用相應的HTML實體(&lt;),替換代碼中所有的小於號(<),替換後一切正常

(2).用一個CData片段來包含JS代碼,因為在XHTML(XML)中CData片段是文檔中一個特殊區域,這個區域可以包含不需要解析的任意格式的文本內容。很明顯CDATA被解析為了一個節點。

<script type="text/javascript"><![CDATA[
   function compare(a, b){
      if(a < b){
         console.log("A is less than B");
      }esle if(a > b){
         console.log("A is greater than B");
      }else{
         console.log("A is equal to B");
      }
   }
]]></script>


在相容XHTML的瀏覽器中這個辦法可行,但實際上還有不少瀏覽器不相容XHTML因而不支持CData片段。這種情況下使用JS註釋將CData標記註釋掉就可。

<script type="text/javascript">
//<![[
   function compare(a, b){
      if(a < b){
      
      }else if(a >b){

      }else{

      }
   }
//]]>
</script>
  • CDATASection類型

用JS也可以創建CData片段:

CDATASection只針對基於XML的文檔,表示的是CDATA區域,原型鏈的繼承關係為CDATASection實例.__proto__=>CDATASection.prototype=>Text.prototype=>CharacterData.prototype=>Node.protoype=>EventTarget.prototype。

CDATASection節點具有下列特征:

  • nodeType值為4
  • nodeName值為"cdata-section"
  • nodeValue值是內容區域的內容
  • parentNode可能是Document或Element
  • 不支持子節點

(1).相容性:CDATA區域只會出現在XML/XHTML文檔中,對於HTML文檔會把CDATA區域錯誤地解析為註釋節點或過濾掉,>=IE10和FF和Chrome會解析為Comment類型節點。<IE10會忽略該節點,因為IE9之前的版本中不支持CDATASection類型。

(2).在真正XML文檔中,可以使用document.createCDATASection(text)創建CDATA區域,只需傳入節點內容即可。在HTML文檔上使用document.createCDATASection()會報錯說不支持HTML文檔。CDATA節點不能插入document節點中,只能插進標簽中。

var cd=document.createCDATASection('mycdata');
cd;// <![CDATA[mycdata]]>
document.appendChild(cd);/*Uncaught DOMException: Failed to execute 'appendChild' on 'Node': 
Nodes of type '#cdata-section' may not be inserted inside nodes of type '#document'.*/

CDATA區段不能進行嵌套,CDATA區段包含了不會被解析器解析的文本,CDATA中的標簽不會被視為標簽同時實體也不會被展開,主要目的是為了包含註入XML片段之類的材料,無需轉義所有分隔符。


DocumentType類型

DocumentType節點包含著與文檔的doctype有關的信息,原型鏈繼承關係為document.doctype.__proto__=>DocumentType.prototype=>Node.prototype=>EventTarget.prototype。

它具有下列特征: 

  • nodeType值為10
  • nodeName值為doctype名稱,保存文檔類型的名稱即當前文檔最外層標簽頂級元素,document.doctype.name也可獲取,就是出現在<!DOCTYPE 之後的文本(不包括後面那些PUBLIC...DTD版本號和文件路徑)獲取的為小寫內容(不論之前代碼中是否大小寫)。這兩種方式都是不可寫的,因為nodeName和name的訪問器屬性set為undefiend。

註:有點疑問,經測試document.doctype只能在HTML文檔中獲取到DocumentType節點,在XML/XHTML中均為null(表明document.doctype是一個空指針)。

  • nodeValue值為null
  • parentNode是Document
  • 沒有子節點

在DOM1級中,DocumentType對象不能動態創建,只能通過解析文檔代碼的方式創建,支持它的瀏覽器會把DocumentType對象保存在document.doctype中。DOM1級描述了DocumentType對象的三個屬性:name,entities,notations(它們都是DocumentType.prototype對象上的三個屬性,但Chrome中好像已經沒有後兩個屬性了,反正沒獲取到這兩個屬性)。

 

DocumentFragment類型

在所有節點類型中,只有DocumentFragment在文檔中沒有對應標記。原型鏈關係為: 文檔片段實例.__proto__=>DocumentFragment.prototype=>Node.prototype=>EventTarget.prototype

註意文檔片段類型只支持getElementById獲取元素,沒有getElementsByTagName那系列的,不過可以通過querySelector獲取,畢竟很萬能~
DOM規定文檔片段是一種輕量級的文檔,可以包含和控制節點,但不會像完整的文檔那樣占用額外的資源。DocumentFragment節點具有下列特征:

  • nodeType值為11
  • nodeName值為"#document-fragment"
  • nodeValue值為null
  • parentNode值為null
  • 子節點可以是Element,ProcessingInstruction,Comment,Text,CDATASection,EntityReference

可以把文檔片段當作一個倉庫來使用,可以在裡面保存將來可能會添加到文檔中的節點。創建文檔片段使用document.createDocumentFragment()方法。
如果將文檔中本身存在的節點添加到文檔片段中,就會從文檔樹中移除該節點。


可以通過appendChild或insertBefore將文檔片段中內容添加到文檔中(其實還是繼承自Node.prototype那些方法),在將文檔片段作為參數傳遞給這兩個方法時,實際上只會將文檔片段的所有子節點添加到相應位置,文檔片段節點本身永遠不會成為文檔樹的一部分。假設想為ul元素添加三個列表項,如果逐個地添加列表項,將會導致瀏覽器反覆渲染新信息。我們可以將所有列表項加到文檔片段中,最後再一次性將它們添加到文檔中。

var df = document.createDocumentFragment();
var ul= document.createElement('ul');
var li=null;
for(var i=0;i<3;i++){
  li = document.createElement('li');
  li.appendChild(document.createTextNode("Item"+(i+1)));
  df.appendChild(li);
}
ul.appendChild(df);

現在看ul和df元素,說明文檔片段節點並沒加到ul中去,而是它裡面的內容加進去了。


Attr類型

元素的特性在DOM中以Attr類型來表示,在除了<=IE7之外的所有瀏覽器都可以訪問Attr類型的構造函數和原型。特性節點就是一種對象,就是存在於元素的attributes屬性(繼承自Element.prototype)中的節點。某元素的attributes屬性指向的是一個NamedNodeMap類型的實例集合。在該集合中的每一項才是我們需要的屬性節點對象。

原型鏈繼承關係為:attrNode.__proto__=>Attr.prototype=>Node.prototype=>EventTarget.prototype

特性節點具有下列特征

  • nodeType值為2
  • nodename值是特性的名稱
  • nodeValue值是特性的值
  • parentNode值為null
  • 在HTML中不支持子節點
  • 在XML中子節點可以是Text或EntityReference

儘管特性節點也是節點,但卻不認為是DOM文檔樹中的一部分。開發人員最常使用的是getAttribute(),setAttribute(),removeAttribute()很少直接引用特性節點(這些方法繼承自Element.prototype)。
(1).Attr對象有三個屬性:name,value,specified
name :特性名稱,與nodeName值相同
value :特性的值,與nodevalue值相同
specified :是一個布爾值,用以區別特性是在代碼中指定的還是預設的

(2).創建新的特性節點:document.createAttribute()


當在調用createAttribute()時已經為name屬性賦了值,所以後面就不需要給它賦值,在將特性節點添加到元素中時必須使用setAttributeNode。添加後可以通過attributes,getAttributeNode,getAttribute方法訪問。不過不建議直接訪問特性節點,使用getAttribute,setAttribute,removeAttribute比操作特性節點方便多。

參考

《JavaScript高級程式設計》


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 數據綁定是在應用程式 UI 與數據源建立連接的過程。如果綁定正確數據,則當數據更改其值時,綁定到數據的UI屬性值會自動反映更改。DeviceOne支持靈活的數據綁定,使UI展示和數據可以清晰的分離。目前還不支持雙向綁定,只支持數據到展示的傳遞。使用DeviceOne開發App,你可以不使用任何數據b ...
  • 幾個知識點: HTML 指的是超文本標記語言 (Hyper Text Markup Language) HTML框架結構: <!DOCTYPE html> <html> <head> </head> <body> 此處為標簽內容 </body> </html> HTML屬性: class=“XXX” ...
  • 一、引言 之前這個系列文章已經介紹Bootstrap。由於最近項目中,前端是Asp.net MVC + KnockoutJs + Bootstrap來做的。所以我又重新開始寫這個系列。今天就讓我們來看看Web前端的MVVM框架——KnockoutJs。 二、KnockoutJs是什麼? 做.NET開 ...
  • 由於我所在的項目組一直在用gulp構建工具,而我只是在前人搭好的環境下每次運行gulp packJs來打包js,對裡面的東西全然不知,剛好最近有些時間就想自己從學學將gulp怎麼用於構建前端項目中,這樣也會對這個構建工具有一些深刻的理解。 首先,gulp是什麼?gulp是基於nodejs的自動任務運 ...
  • React是什麼?React.js 是 Facebook 推出的一個用來構建用戶界面的 JavaScript 庫。Facebook開源了React,這是該公司用於構建反應式圖形界面的JavaScript庫,已經應用於構建Instagram網站及 Facebook部分網站。最近出現了AngularJS ...
  • AngularJS 表達式 AngularJS 表達式寫在雙大括弧內:{{expression}} AngularJS 表達式把數據綁定到HTML,這與ng-bind 指令有異曲同工之妙 AngularJS 將在表達式書寫的位置輸出數據。 AngularJS 表達式很像JavaScript表達式:他 ...
  • 前兩天跟著葉小釵的博客,看了下RequireJS的源碼,大體瞭解了其中的執行過程。不過在何時進行依賴項的載入,以及具體的代碼在何處執行,還沒有搞透徹,奈何能力不夠,只能先記錄一下了。 RequireJS的初探 看源碼從頭開始看,肯定是不切實際的。按照葉小釵的方法,是從data main開始的,所以我 ...
  • 效果體驗:http://hovertree.com/texiao/css3/8/效果圖: 點擊這裡下載:http://hovertree.com/h/bjaf/8d5vmddq.htm 更多特效:http://www.cnblogs.com/roucheng/p/texiao.html ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...