標籤:

DOM【介紹、HTML中的DOM、XML中的DOM】

什麼是DOM?

DOM(Document Object Model)文檔對象模型,是語言和平台的中立介面。。

允許程序和腳本動態地訪問和更新文檔的內容

為什麼要使用DOM?

Dom技術使得用戶頁面可以動態地變化,如可以動態地顯示或隱藏一個元素,改變它們的屬性,增加一個元素等,Dom技術使得頁面的交互性大大地增強

HTML的DOM

HTML的DOM是一個內存對象樹,在瀏覽器中只保存一份,HTML的DOM修改HTML的內容會直接反應到瀏覽器中

API

NODE對象API

在DOM眼中,HTML是由不同類型的節點組成的,這些節點都屬性NODE對象。

NODE對象有一個nodeType的屬性可用於判斷節點類型

HTML不同類型的節點之間都是有聯繫的:

  • 位於一個節點之上的節點是該節點的父節點(parent)
  • 一個節點之下的節點是該節點的子節點(children)
  • 同一層次,具有相同父節點的節點是兄弟節點(sibling)
  • 一個節點的下一個層次的節點集合是節點後代(descendant)
  • 父、祖父節點及所有位於節點上面的,都是節點的祖先(ancestor)

於是乎,NODE對象也有訪問節點的屬性和方法

屬性:

總的來說就是:得到節點的信息(節點名字、節點值)以及訪問節點的兄弟、父親

方法:

總的來說就是:添加、替換、刪除子節點,判斷是否有子節點,克隆子節點

document

HTML的DOM中我們提到並大量使用了document這個Javascirpt的內置對象,請注意這個對象僅僅可以表示HTML的根節點

document的屬性:

  • documentElement【可以獲取得到<html>這個節點】

document方法:

  • createElement()【創建一個元素節點】
  • createComment()【創建注釋】
  • createAttribute()【創建屬性節點】
  • createTextNode()【創建文本節點】
  • getElementById()【通過id得到該元素節點】
  • getElementsByTagName()【通過標籤名,得到所有標籤名的數組】

Element介面

Element代表的是元素節點,是我們經常用到的一個介面!

Element屬性:

  • tagName【返回的是元素標籤的大寫名稱

Element方法:

  • getAttribute(String name)【得到屬性的值】
  • setAttribute(String name,String value)【設置屬性的名稱和值,不存在則創建】
  • getElementsByTabName()【返回該元素節點的子孫節點的數組
  • removeAttribute()【移除屬性】

當我們設置屬性的時候,我們不是調用方法來設置,而經常會這樣做:

var input = document.createElement("input"); input.value = "aa"; input.name = "bb";

XML的DOM

我們可能會用XML文件作為客戶端和伺服器的傳輸文件。於是我們需要學習在JavaScript代碼中通過DOM操作XML文檔

XML和HTML的API是十分類似的,這裡就不贅述了。

裝載XML

客戶端和服務端如果是通過XML文件或者XML字元串進行交互數據的話。那麼,我們需要裝載伺服器的XML文件或XML字元串到JavaScript中的DOM對象。

現在問題就是,IE和fireFox的裝載XML方式是不一樣的。因此,我們最好封裝成一個方法來裝載XML

/** * @param flag true代表的是文件,false代表的是字元串 * @param xmldoc 要封裝成DOM對象的字元串或文件 * @return 返回的是根節點的元素節點 * 重點放在高版本上!! * */function loadXML(flag, xmldoc) { //瀏覽器是低版本的IE var objXml; if (window.ActiveXObject) { //是IE的話,有兩種方式來創建ActiveXObject對象 var name = ["MSXML2.DOMDocument", "Miscrosoft.XmlDom"]; for (var i = 0; i < name.length; i++) { objXml = new ActiveXObject(name); break; } //設置為同步【裝載XML文件成DOM對象,我們都是同步操作】 objXml.async = false; //如果是字元串 if (flag == false) { objXml.loadXML(xmldoc); } else { //如果是文件 objXml.load(xmldoc) } return objXml.documentElement; //瀏覽器是fireFox或者高版本的IE } else if (document.implementation.createDocument) { //字元串 if (flag == false) { //創建對象,解析XML字元串 objXml = new DOMParser(); //解析到根節點 var root = objXml.parseFromString(xmldoc, "text/xml"); return root.documentElement; } else { //由於安全問題,想要得到XML文件,需要通過XMLHttpRequest對象來獲取 objXml = new XMLHttpRequest(); //同步 objXml.open("GET", "1.xml", false); objXml.send(null); //返回XML數據 return objXml.responseXML.documentElement; } //解析不了啦 } else { alert("解析不了了"); }}

測試

去除空白字元

如果有需要就加這段功能吧!

function removeBlank(xml) { if (xml.childNodes.length > 1) { for (var loopIndex = 0; loopIndex < xml.childNodes.length; loopIndex++) { var currentNode = xml.childNodes[loopIndex]; if (currentNode.nodeType == 1) { removeBlank(currentNode); } if (((/^s+$/.test(currentNode.nodeValue))) && (currentNode.nodeType == 3)) { xml.removeChild(xml.childNodes[loopIndex--]); } } }}

XPATH

XPATH技術其實我們已經接觸過了,在講解XML的時候,我們已經使用過了XPATH技術了。

可以參考我之前的XML博文:blog.csdn.net/hon_3y/arti…

XPATH總體可分為三種搜索:

  • 絕對路徑搜索(/根節點/子節點)
  • 相對路徑搜索(子節點/子節點)【與絕對路徑搜索的差別就是開頭有無"/"】
  • 全文搜索(//子節點)

如果我們要查找屬性節點、文本節點、多條件的節點是這樣寫XPATH的

  • 屬性節點:(先找到元素節點/@屬性名)
  • 文本節點:(先找到元素節點/test())
  • 有條件查詢節點:(先找到元素節點/[條件])
  • 多條件查詢節點:(先找到元素節點/[條件][條件])【兩個條件同時吻合】
  • 多條件查詢節點:(先找到元素節點/[條件]|先找到元素節點/[條件])【或關係】

我們之前使用dom4j的時候,是調用selectSingleNode()和selectNodes()方法來獲取任意深度的節點或多個節點

我們想要在JavaScript中使用XPATH技術,那麼我們也實現這兩個方法,調用它就行了!

selectSingleNode()

IE10,IE11下無法使用selectSingleNode()方法。解決參考:wenda.so.com/q/145845351…

但是,我沒有解決掉該問題。。。。。

下面是JavaScript代碼:

/** * * @param xmldoc 代表的是XML的根節點 * @param xpath 給出的XPATH表達式 * @return 返回的是對應的節點或多個節點 * * * */function selectSingleNode(xmldoc,xpath) { //如果是IE,IE10,IE11解決不了....會的人告訴我一聲!! if(navigator.userAgent.indexOf(".NET")>0) { var value = xmldoc.selectNodes(xpath) return value; }else { //如果是fireFox var xpathObj = new XPathEvaluator(); var value = xpathObj.evaluate(xpath, xmldoc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); return value.singleNodeValue; }}

  • 測試代碼:

<script type="text/javascript" src="loadXML.js" ></script> <script type="text/javascript" src="xpath.js" ></script> <script type="text/javascript"> function test() { var file = loadXML(true, "1.xml"); var xpathValue = selectSingleNode(file, "//dd"); var value = xpathValue; alert(value); } </script>

  • 在fireFox,Chrome瀏覽器可以正常獲取得到節點

selectNodes()

由於上面IE問題我到現在還沒有解決,所以下面直接測試FireFox瀏覽器了

等我複習到Jquery的時候,再把這裡的坑填了吧。。。

  • javaScript代碼:

/** * * @param xmldoc 代表的是XML的根節點 * @param xpath 給出的XPATH表達式 * @return 返回的是節點數組 */function selectNodes(xmldoc,xpath) { var xpathObj = new XPathEvaluator(); //如果是多節點,返回的是迭代器 var iterator = xpathObj.evaluate(xpath, xmldoc, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null); //把迭代器的數據寫到數組中 var arr = new Array(); var node; while ((node=iterator.iterateNext())!=null) { arr.push(node); } return arr;}

  • 測試代碼:

function test() { var file = loadXML(true, "1.xml"); var xpathValue = selectNodes(file, "//aa"); var value = xpathValue; alert(value); }

  • 效果:

如果文章有錯的地方歡迎指正,大家互相交流。習慣在微信看技術文章,想要獲取更多的Java資源的同學,可以關注微信公眾號:Java3y

推薦閱讀:

為什麼DOM不提供insertAfter()方法?
querySelectorAll 方法相比 getElementsBy 系列方法有什麼區別?
children.length和childElementCount?
如何理解js高程里的document對象是HTMLDocument的實例?
DOM真的很慢嗎?如果真的是,為什麼不去改進它?

TAG:DOM | HTML |