第44節 DocumentType、文檔片段及Attr節點

2021-02-07 開發者之路

本內容是《Web前端開發之Javascript視頻》的課件,請配合大師哥《Javascript》視頻課程學習。

DocumnetTyp類型:

包含著與文檔的doctype有關的所有信息,被保存在document.doctype對象中;

該類型繼承自Node類;

特徵:

nodeType的值為10;nodeName的值為doctype的名稱;nodeValue的值為null;parentNode是Document;沒有子節點;console.log(document.doctype); // <!DOCTYPE html>console.log(document.doctype.nextSibling); // <html>console.log(document.doctype.nodeType); // 10 DOCUMENTTYPE_NODE類型console.log(document.doctype.nodeName); // htmlconsole.log(document.doctype.nodeValue); // nullconsole.log(document.doctype.parentNode); // #documentconsole.log(document.childNodes); console.log(document.childNodes[0]); // <!DOCTYPE html>DOM1級中,DocumentType對象不能動態創建,而只能通過解析文檔的方式來創建;並把DocumentType對象保存在document.doctype中;

DOM1描述了解DocumentType對象的3個屬性:

name:表示文檔類型的名稱,即出現在<!DOCTYPE之後的文本;

console.log(document.doctype.name); // htmlentities:是由文檔類型描述的實體的NamedNodeMap對象;

notations:是由文檔類型描述的符號的NamedNodeMap對象

entities和notations均為NamedNodeMap類型,一般在XML中使用,在HTML中entities和notations都是空列表,所以通常為null或undefined;

DocumentFragment類型:

文檔片段類型,在所有節點類型中,只有它在文檔中沒有對應的標識;

DOM規定文檔片段(document fragment)稱為「輕量級」的文檔,它是一種特殊的Node,作為其他節點的臨時的容器,可以包含和控制節點,但不會像完整的文檔那樣佔用額外的資源;

特徵:

nodeType的值為11;nodeName的值為#document-fragment;nodeValue的值為null;parentNode的值為null;雖然文檔片段就跟標準的document一樣,裡面存儲了由節點組成的文檔結構,但因為文檔片段是獨立的,不屬於文檔的一部分,所以它的parentNode總是為null,並且,它的變化不會觸發DOM樹的重新渲染,也不會導致性能等問題;

文檔片段的子節點可以是Element、ProcessingInstruction、Comment、Text、CDATASection或Entity-Reference;

文檔片段類型本身沒有定義屬性和方法,其繼承了Node的所有方法,通常用於執行那些針對文檔的DOM操作;主要用其來保存將來可能會添加到文檔中的節點;

利用document.createDocumentFragment()方法創建片段;

var fragment = document.createDocumentFragment();console.log(fragment);console.log(fragment.nodeType); // 11console.log(fragment.nodeName); // #document-fragmentconsole.log(fragment.nodeValue); // nullconsole.log(fragment.parentNode); // nullconsole.log(fragment.childNodes); // NodeList另外,其提供了文檔片段的構造函數DocumentFragment(),使用它也可以返回一個文檔片段對象,但IE不支持;

var fragment = new DocumentFragment();可以通過appendChild()或insertBefore()將文檔片段中的內容添加到文檔中,同時,文檔片段被清空;

var fragment = document.createDocumentFragment();fragment.appendChild(document.createTextNode("零點程式設計師"));console.log(fragment); // 有text節點document.body.appendChild(fragment);console.log(fragment); // 沒有text節點,fragment已經被清空如果將文檔中的節點添加文檔片段中,就會從文檔樹中移除該節點;var fragment = document.createDocumentFragment();var mydiv = document.getElementById("mydiv");fragment.appendChild(mydiv); // mydiv會從文檔樹中被移除console.log(fragment);利用片段可以一次性的把多個節點添加到文檔中,可以節省資源;

<ul id="myList"></ul><script>var myList = document.getElementById("myList");var fragment = document.createDocumentFragment();for(var i=0; i<3; i++){ var li = document.createElement("li"); li.appendChild(document.createTextNode("課程:" + (i + 1))); fragment.appendChild(li);}myList.appendChild(fragment);// 或者var courseArr = ["HTML","CSS","Javascript"];var fragment = document.createDocumentFragment();courseArr.forEach(function(c){ var li = document.createElement("li"); li.innerHTML = c; fragment.appendChild(li);});myList.appendChild(fragment);</script>如:倒序排列一個節點的子節點:

function reverse(node){ var fragment = document.createDocumentFragment(); // 從後至前循環子節點,將每個子節點移動到文檔片段中 // 如此,node的最後一個節點變成fragment的第一個節點 while(node.lastChild) fragment.appendChild(node.lastChild); // 把fragment的所有子節點一次性移加node中 node.appendChild(fragment);}var mylist = document.getElementById("mylist");reverse(mylist);文檔片段其實在一個叫<template>元素中特別有用,該元素屬於HTMLTemplateElement類型,其有個content 屬性,就包含了一個DocumentFragment;只是可惜IE不支持;

在瀏覽器中會被渲染成

<template id="courseList"> #document-fragment</template> --><template id="courseList"> <h2>Web前端開發</h2> <ul> <li>HTML</li> <li>CSS</li> <li>Javascript</li> </ul></template><script>var courseList = document.getElementById("courseList");console.log(courseList.content); // #document-fragmentvar p = document.createElement("p");p.innerHTML = "該課程由大師哥王唯主講";courseList.content.appendChild(p);document.body.appendChild(courseList.content);</script>Attr類型:

元素的特性在DOM中以Attr類型表示,就是存在於元素的attributes屬性中的節點;其繼承自Node類;儘管它也是節點,但特性卻不被認為是DOM文檔樹的一部分;

特徵:

nodeType的值2;nodeName的值為特性的名稱;nodeValue的值就是特性的值;parentNode的值為null;在HTML沒有子節點;在XML中子節點可以是Text或EntityReference;var mydiv = document.getElementById("mydiv");var attr = mydiv.getAttributeNode("name");console.log(attr);console.log(attr.nodeType); // 2console.log(attr.nodeName); // nameconsole.log(attr.nodeValue); // mydivconsole.log(attr.parentNode); // nullAttr對象有3個屬性:

name、value和specified;

console.log(attr.name); // nameconsole.log(attr.value); // mydivconsole.log(attr.specified); // trueAttr對象的相關方法:

document.createAttribute(name)方法:

創建並返回特性節點,傳入特性的name名稱;創建後可以通過為該節點的nodeValue屬性設置該屬性節點的屬性值,也可以使用常用的 setAttribute()方法來替代該方法;

var attr = document.createAttribute("style");attr.nodeValue = "color:red;";setAttributeNode(attribute)方法:

為指定的Element添加屬性節點,注意,該法是Element元素方法;創建特性節點後,必須使用元素的setAttributeNode()方法將特性節點添加到元素特性中;該方法會返回一個Attr屬性節點;

var stylArr = mydiv.setAttributeNode(attr);該特性對象不能被復用,一旦被添加到某個元素特性中,其他元素就不能再使用,但可以克隆,如:

var h2 = document.getElementsByTagName("h2")[0];// h2.setAttributeNode(attr); // 異常h2.setAttributeNode(attr.cloneNode());這個方法很少使用,一般都是使用setAttribute()方法;

getAttributeNode(attrName)方法:返回指定元素的指定Attr節點;

用以上方法添加Attr節點後,可以通過attributes屬性,getAttributeNode()方法,getAttribute()方法來訪問;其中,attributes和getAttributeNode()會返回對應特性的Attr節點,而getAttribute()返回特性的值;

var mydiv = document.getElementById("mydiv");var attr = document.createAttribute("style");attr.nodeValue = "font-size:20px; color: blue;";mydiv.setAttributeNode(attr);console.log(mydiv.getAttribute("style"));console.log(mydiv.getAttributeNode("style"));console.log(mydiv.getAttributeNames());這個方法也很少使用,一般使用getAttribute()方法;

removeAttributeNode(attrNode)方法:從當前的element(元素節點)刪除指定的屬性;

var delAttr = mydiv.removeAttributeNode(attr);console.log(delAttr);console.log(attr);console.log(delAttr === attr);// 注意,要先注釋前面幾行if(mydiv.hasAttribute("style")){ var delAttr = mydiv.getAttributeNode("style"); delAttr = mydiv.removeAttributeNode(delAttr); console.log(delAttr);}一般最常使用的是getAttribute()、setAttribute()和removeAttribute()方法,很少直接引用特性節點;

NodeList及HTMLCollection:

getElementsByName()返回的是NodeList,getElementsByTagName()返回是的HTMLCollection,document對象的集合也是HTMLCollection類型的;

理解NodeList及NamedNodeMap和HTMLCollection,是從整體上透徹理解DOM的關鍵所在;

這些對象都是類數組對象,都有length屬性,也可以像真正的數組一樣索引,但只能讀不能寫;

forEach():迭代;IE不支持;

nodelist.forEach(function(v,k,p){ console.log(v);});但可以藉助數組的forEach()方法;

Array.prototype.forEach.call(nodelist, function(v,k,p){ console.log("k:" + k, "v:" + v, "p:" + p);});HTMLCollection接口屬性和方法:

length:只讀,返回集合中子元素的數目;

item():根據給定的索引,返回具體的節點;如果索引超出了範圍,則返回 null;

namedItem():根據Id或name返回指定節點,根據name匹配只能作為後備,並且只有當被引用的元素支持name屬性時才能被匹配,如果不存在符合給定name的節點,則返回null;

NodeList和HTMLCollection接口都定義了item()方法,接收一個整數,返回此索引處的元素;在實際開發中,沒有必要使用這個方法,因為直接使用索引顯得更加簡單;

HTMLCollection定義了namedItem()方法,返回指定屬性名的值,但也不常用,因為也是可以直接使用索引或常規屬性來訪問;

以上三個集合都是「動態的」,換句話說,每當文檔結構發生變化時,它們都會得到更新;因此,它們始終都會保存著最新、最準確的信息;

從本質上說,所有NodeList對象都是在訪問DOM文檔時實時運行的查詢;

如,以下代碼會導致無限循環:

var divs = document.getElementsByTagName("div"), i, div;for(i=0; i<divs.length; i++){ div = document.createElement("div"); document.body.appendChild(div);}如果想要迭代一個NodeList,最好是使用length屬性初始化第二個變量,然後將迭代器與該變量進行比較,如:

var divs = document.getElementsByTagName("div"), i, len, div;for(i=0, len=divs.length; i<len; i++){ div = document.createElement("div"); document.body.appendChild(div);}或者直接對NodeList和HTMLCollection對象生成一個副本,在副本上進行一系列操作;

var snapshot = Array.prototype.slice.call(nodelist,0);不要使用for...in或者for each...in來遍歷一個NodeList對象中的元素,因為它們會把NodeList 對象中的 length 和 item 屬性也遍歷出來,這可能會導致腳本運行出錯;此外,for...in也不能保證訪問這些屬性的順序;

一般來說,應該儘量減少訪問NodeList的次數,因為每次訪問NodeList,都會運行一次基於文檔的查詢,所以,從一開始,可以將NodeList中取得的值緩存起來,然後再使用;

但NodeList也並不總是動態的,比如document.querySelectorAll就會返回一個靜態 NodeList;

Web前端開發之Javascript-零點程式設計師-王唯

相關焦點

  • 第41節 Document文檔節點-Javascript
    (document.nodeName); // #documentconsole.log(document.nodeValue); // nullconsole.log(document.parentNode); // nullconsole.log(document.childNodes.length); // 2文檔的子節點:DOM標準規定Document節點的子節點可以是DocumentType
  • jQuery的attr()、append()、after()和before()方法操作HTML元素
    01第1節:jQuery操作Html屬性和值如:<input id=」txtId」 type=」text」/>,在此標記中,id和type都是屬性名,賦值號(=)後面用雙引號括起來的是屬性值。在jQuery中,使用封裝好的attr()方法可以獲取Html元素的屬性的值和給Html屬性設置值。
  • HTML文檔的訪問埠DOM (Document Object Model)
    這節內容是「VBA信息獲取與處理」教程中第八個專題「VBA與HTML文檔」的第五節。,希望想掌握這方面知識的朋友能參考我的教程學習。第五節 HTML文檔的訪問埠DOM (Document Object Model)大家好,我們繼續對HTML文檔進行學習,在前幾節中我們認識了網頁文檔上面的各種元素,那麼我們又該怎麼訪問他們呢,是如何實現呢?
  • 第六篇:DOM對象與Document
    對象模型結構DOM的英文全稱是Document Object Model,即文檔對象模型。文檔一般是指HTML文檔,DOM對象模型將HTML文檔組織為以Node對象為節點的層次結構。一個節點是一個Node對象。Node對象按照節點類型分為元素節點、屬性節點、文本節點和注釋節點。
  • 第43節 Text、Comment及CDATASection
    ;也就是說,在向DOM文檔中插入文本之前,會先對其進行HTML編碼;text.nodeValue = "零點程式設計師<strong>王唯</strong>";// 會轉義為<strong>console.log(text.nodeValue);document.write(text.nodeValue);註:瀏覽器已自動修正;如果使用document.write
  • python-docx節的添加、定位和分節符的設置
    筆者將新建一個文檔並列印節的數量和段落對數量,代碼如下:document = Document() # 新建文檔print('默認節的數量:', len(document.sections)) # 列印默認節對數量print('默認段落的數量:', len(document.paragraphs)) # 列印默認段落數量document.save('test.docx') #
  • jquery1.6中的.prop()和.attr()異同
    這意味著下面的代碼: Js代碼  $(「:checkbox」).attr(「checked」, true);  $(「option」).attr(「selected」, true);  $(「input」).attr(「readonly」, true);  $(「input」).attr(「disabled」, true
  • Jquery attr()方法 屬性賦值和屬性獲取
    ()方法</title><script src="js/jquery-1.4.2.min.js" language="javascript" type="text/javascript" ></script><style>p{color:red}li{color:blue;}.lili{font-weight:bold
  • JS | document.write
    document.write 幹嘛用的?顧名思議:向 html 文檔中寫入東西。寫入內容隨意,可以是 html 片段,也可以是字符串、腳本等,如下:<script> document.write('a', 'b', 'c') <script>如果到這裡也就結束了,但問題是 html 文檔是自上而下加載的,如水流一樣,形成文檔流。
  • 《css3入門到精通系列》第一節:強大的css3選擇器
    >1、基本選擇器,2、層次選擇器3、偽類選擇器(動態偽類、UI元素狀態偽類、結構為類、否定偽類選擇器)4、偽元素5、屬性選擇器基本選擇器:* :通配選擇器,選擇文檔中所有的HTML元素節點,如「 *{} 」 或者「 E *{}」等;E :元素選擇器,選擇指定類型的HTML元素, 如「div{},ul{}」;#id :id選擇器,選擇指定id屬性值為"id"的任意類型元素,具有唯一性;如「#id」;.class :類選擇器,選擇指定class屬性值為「
  • 跟jQuery那樣簡單方便操作Html文檔的Java工具類,今天我必須要告知你!
    神器介紹今天我要介紹一款操作Html文檔非常好用的Java插件,強烈安利!因為實在太好用了!「Jsoup 是一款純Java實現,可以非常方便讀取和操作Html文檔的一款插件。她的API跟jQuery非常相似。我都甚至懷疑創造者是否是jQuery的忠實粉絲。」讀完本文,你能做哪些「壞事」?
  • 第299天:React中JSX的理解
    const name = "Josh Perez";const element = <h1>Hello, {name}</h1>;ReactDOM.render( element, document.getElementById("root"));
  • 你用對 hasattr 了嘛?
    >如果它有可能會異常,那麼應該用getattr(讓異常發生):In [4]: getattr(vs, 'redirect_url', None)IndexError Traceback (most recent call last)<ipython-input-4-08e45e416015&
  • 利用模板批量生成文檔--成績單、工資條、合同
    def read_excel_file(srcPath):    '''    讀取 excel文檔    :param srcPath         :excel文檔路徑        :type: string    :return dataFrame        : excel表格內容
  • 前端學習:jQuery中的prop和attr如何操作?
    在JQuery中,對CheckBox的操作分兩個階段,一個是JQuery1.6之前的版本,一個是1.6之後的版本在1.6之前,我們這麼做:但是細心的同學會發現,在jQuery1.6之後,如果還像上面這麼做,那肯定會出問題: $('#checkbox').attr
  • 第64天:XPath 和 lxml
    XPath 和 lxml XPath 全稱為 Xml Path Language,即 Xml 路徑語言,是一種在 Xml 文檔中查找信息的語言。它提供了非常簡潔的路徑選擇表達式,幾乎所有的節點定位都可以用它來選擇。XPath 可以用於 Xml 和 Html,在爬蟲中經常使用 XPath 獲取 Html 文檔內容。