日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

从原型链看DOM--Node类型

發(fā)布時間:2025/3/13 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 从原型链看DOM--Node类型 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言:

本系列從原型,原型鏈,屬性類型等方面下手學(xué)習(xí)了DOM文檔對象模型,旨在弄清我們在DOM中常用的每一個屬性和方法都清楚它從哪里來要到哪里做什么事,這樣對于理解代碼有一定啟發(fā)。全靠自己在總結(jié)中摸索,所以對于一個問題要是深究還真能挖出許多有意思的東西,現(xiàn)在覺得JavaScript這個東西簡直越來越有意思了。

?

正文:
DOM(文檔對象模型)是針對HTML和XML文檔的一個API(應(yīng)用程序編程接口)。DOM描繪了一個層次化的節(jié)點樹,允許開發(fā)人員添加,移除,修改頁面某一部分,現(xiàn)在它已成為表現(xiàn)和操作頁面標(biāo)記的真正的跨平臺,語言中立的方式。
DOM1為基本文檔結(jié)構(gòu)及查詢提供了接口。本系列主要討論JavaScript對DOM1級的實現(xiàn),但是還會穿插一點DOM2和DOM3的內(nèi)容。

?

節(jié)點層次

DOM可以將任何HTML和XML文檔描繪成一個由多層節(jié)點構(gòu)成的結(jié)構(gòu)。節(jié)點分為好幾種不同的類型,每種類型分別表示文檔中不同的信息及標(biāo)記。每個節(jié)點都有各自特點,屬性和方法,及和其他節(jié)點存在的關(guān)系。節(jié)點之間的關(guān)系構(gòu)成了層次,而所有頁面標(biāo)記則表現(xiàn)為一個以特定節(jié)點為根節(jié)點的樹形結(jié)構(gòu)。節(jié)點比元素的概念大,元素只是節(jié)點的一種類型。

文檔節(jié)點:每個文檔的根節(jié)點。HTML文檔中文檔節(jié)點(?window.document=>#document?)只有一個子節(jié)點即?HTML?元素。

文檔元素:文檔中最外層元素,文檔中的其他元素都包含在文檔元素中,每個文檔只能有一個文檔元素。在HTML頁面中,文檔元素始終都是?HTML?元素。XML中,沒有預(yù)定義的元素,任何元素都能成為文檔元素。

每一段標(biāo)記都可通過樹中一個節(jié)點表示:HTML元素通過元素節(jié)點表示,特性通過特性節(jié)點表示,文檔類型通過文檔類型節(jié)點表示,注釋通過注釋節(jié)點表示...共有12種節(jié)點類型,這些類型都繼承自一個基類型Node類型。下面來挨個看這些節(jié)點類型,但是本篇著重學(xué)習(xí)Node類型,其他類型和DOM操作技術(shù)在后續(xù)系列的總結(jié)中。

  • Node類型
  • Document類型
  • Element類型
  • Text類型
  • Comment類型
  • CDATASection類型
  • DocumentType類型
  • DocumentFragment類型
  • Attr類型
  • DOM操作技術(shù)

  • 動態(tài)腳本
  • 動態(tài)樣式
  • 操作表格
  • 使用NodeList



  • Node類型:

    DOM1級定義了一個Node接口,該接口將由DOM中所有節(jié)點類型實現(xiàn)。這個Node接口在JavaScript中作為Node類型實現(xiàn),JavaScript中所有節(jié)點類型(Element,Attr,Text,CDATASection,Comment,Document,DocumentType,DocumentFragment等)都繼承自Node類型(?Element.prototype instanceof Node;// true?),因此所有節(jié)點類型的實例都共享著原型鏈(某類型實例->某類型.prototype->Node.prototype->EventTarget.prototype->Object.prototype)上的屬性和方法,?document instanceof Node;// true?比如文檔節(jié)點?#document?就是Document類型實例也是Node類型的實例,文檔元素?html?是HTMLElement類型的實例是Element類型實例也是Node類型的實例。

    下面這段可以略過,只是我的一個小思考:

    document.documentElement.__proto__==HTMLElement.prototype;// false //居然是false,這個html元素節(jié)點實例的原型指向的不是HTMLElement構(gòu)造函數(shù)的prototype??但是... HTMLElement.prototype.isPrototypeOf(document.documentElement);// true //判斷HTMLElement.prototype確實是在html元素的原型鏈上啊

    有沒有覺得很奇怪,?__proto__?不是指向構(gòu)造這個實例的函數(shù)的原型嗎??為什么會是?false?,而且?document.documentElement.__proto__?和?HTMLelement.prototype?竟然不是同一類型的,按理說?html?元素作為HTMLElement的實例,默認它們指向同一個?HTMLElement.prototype?對象的。

    百思不得其解,一度認為我對?__proto__?這個東西是不是理解有誤,查看相關(guān)文檔MDN Object.prototype.__proto__后受了點啟發(fā),

    是不是?document.documentElement.__proto__?被JS引擎重寫了!!?讓其重新指向一個為HTMLElement類型的實例對象(假設(shè)就叫?HTMLEleObj?吧,其實是?HTMLHtmlElement.prototype?),查看?HTMLEleObj?的?__proto__?,發(fā)現(xiàn)這個東西類型為Element類型實例,想到?HTMLElement.prototype?也是Element類型的,那這兩個是不是同一個對象?

    好像是這樣的:?document.documentElement.__proto__.__proto__==HTMLElement.prototype;// true?。這也就能解釋為什么html元素改變了?[[prototype]]?指向但還仍在原來的原型鏈上,JS引擎是給這個本身默認的原型鏈(?html.__proto__->HTMLElement.prototype->Element.prototype->Node.prototype->EventTarget.prototype->Object.prototype?)又增加了一個對象,現(xiàn)在原型鏈變成(?html.__proto__->HTMLEleObj;HTMLEleObj.__proto__->HTMLElement.prototype->Element.prototype->Node.prototype->EventTarget.prototype->Object.prototype?)。還是畫個圖比較好理解點。但是還是不明白為何JS引擎要在原型鏈上增加這么個對象,有什么用處?發(fā)現(xiàn)html元素身上有兩個屬性,版本和構(gòu)造器,然而并不能直接通過?HTMLHtmlElement.prototype.version?訪問?version?屬性(每個元素的?__proto__?除了?constructor?屬性外其余的這些屬性還都不一樣,不過都是HTML5之前元素上的屬性),需要通過它的實例(html元素)訪問。?constructor?指向?HTMLHtmlElement?接口。

    ---補充---
    通過?document.documentElement.__proto__.constructor?訪問得到,HTMLEleObj對象其實是HTMLHtmlElement接口的原型對象,雖然以上思考有些誤解,但是還是留下這個思考的過程吧。真正的原型鏈?zhǔn)??某元素.__proto__->HTML某元素Element.prototype->HTMLElement.prototype->Element.prototype->Node.prototype->EventTarget.prototype->Object.prototype ?。比如對于html元素就是?document.documentElement.__proto__->HTMLHtmlElement.prototype->HTMLElement.prototype->Element.prototype->Node.prototype->EventTarget.prototype->Object.prototype?。對于body元素就是?document.body.__proto__->HTMLBodyElement.prototype->HTMLElement.prototype->Element.prototype->Node.prototype->EventTarget.prototype->Object.prototype?。其實都是可以通過?某元素.__proto__.constructor?屬性訪問到其對應(yīng)的構(gòu)造器。

    扯遠了,回歸主題來看Node類型:

    Node.prototype上的屬性及方法

    注意到?Node.prototype?是?EventTarget?類型的實例對象,怪不得?Node.prototype.__proto__?會指向?EventTarget.prototype?。

    Object.getOwnPropertyNames(EventTarget.prototype);// ["addEventListener", "removeEventListener", "dispatchEvent", "constructor"]

    所有這些關(guān)系總結(jié)來說就是Node和EventTarget是JavaScript中兩種類型,用組合繼承模式實現(xiàn)的話就內(nèi)部實現(xiàn)可能是這樣子:

    function EventTarget(){//初始化實例的屬性和方法 }function Node(){//初始化實例的屬性和方法 }Node.prototype=new EventTarget(); Node.prototype.construct=Node;
    //以Element類型舉例 Element.prototype
    =new Node(); Element.construct=Element; ...

    ?Node.prototype?指向?EventTarget.prototype?,并且?Node.prototype?會被初始化上一些屬性和實例。不過事實上我們并不能成功構(gòu)造?Node?和?EventTarget?類型的實例,控制臺會提示報錯不合法的構(gòu)造。那應(yīng)該是JS引擎內(nèi)部自己實現(xiàn)的吧,不然誰都能構(gòu)造這種底層接口的實例那就亂套了。

    ?

    Node.prototype常見屬性和方法:

    這些關(guān)系指針屬性大部分都是只讀的因為訪問器屬性的?set?被設(shè)置為?undefiend?了,即使?set?不為?undefiend?,但?set?方法能被使用的前提是該節(jié)點的對應(yīng)要訪問的那個屬性不為?null?。所以DOM提供了一些操作節(jié)點的方法(從第9小點開始總結(jié),這些方法都是可寫的,并且在Node.prototype上可以重寫這些方法)

  • nodeType屬性:

    每個節(jié)點(Node原型鏈上的實例對象)都可繼承該屬性(通過?Node.prototype?原型鏈訪問),用于表明節(jié)點類型。
    節(jié)點類型:由在Node類型中定義的下列12個數(shù)值常量表示,任何節(jié)點類型必是其一。這些類型屬性是定義在Node構(gòu)造函數(shù)身上的(靜態(tài)屬性),可以看到上面的圖有輸出Node上面的屬性。加*為重點講解。
    * Node.ELEMENT_NODE; 1
    * Node.ATTRIBUTE_NODE; 2
    * Node.TEXT_NODE; 3
    * Node.CDATA_SECTION_NODE; 4
    ? ?Node.ENTITY_REFERENCE_NODE; 5
    ? ?Node.ENTITY_NODE; 6
    ? ?Node.PROCESSING_INSTRUCTION_NODE; 7
    * Node.COMMENT_NODE; 8
    * Node.DOCUMENT_NODE; 9
    * Node.DOCUMENT_TYPE_NODE; 10
    * Node.DOCUMENT_FRAGMENT_NODE; 11
    ? ?Node.NOTATON_NODE; 12
    但這些屬性值表示的具體什么類型節(jié)點也可通過直接在?Node.prototype?對象上訪問或通過原型鏈訪問。比如要訪問注釋Comment類型節(jié)點,三種方式均可
    Node.prototype.COMMENT_NODE==Node.COMMENT_NODE;// true Node.prototype.COMMENT_NODE;// 8 Node.COMMENT_NODE;// 8 document.COMMENT_NODE;// 8 應(yīng)用:通過利用節(jié)點類型屬性可以確定節(jié)點的類型,為了兼容那些沒有公開Node類型的構(gòu)造函數(shù)的瀏覽器,我們就不用Node.ELEMENT_NODE形式訪問類型值,而是直接通過數(shù)字值判斷
    if(someNode.nodeType==1){console.log("這是一個元素節(jié)點"); }
  • ?nodeName和nodeValue屬性:

    表示節(jié)點具體信息。
    (1).對于Element元素節(jié)點:原型鏈繼承關(guān)系為:某元素節(jié)點.__proto__->HTML某元素Element.prototype->HTMLElement.prototype->Element.prototype->Node.prototype->EventTarget.prototype。

    nodeName保存的為元素的標(biāo)簽名,nodeValue的值為null。

    var someNode=document.documentElement;// 獲取HTML元素 if(someNode.nodeType==1){console.log(someNode.nodeName+"是元素節(jié)點名");console.log("它的nodeValue:"+someNode.nodeValue); } /*HTML是元素節(jié)點名它的nodeValue:null */ (2).對于Attr類型節(jié)點:原型鏈繼承關(guān)系為:某特性節(jié)點.__proto__->Attr.prototype->Node.prototype->EventTarget.prototype。

    nodeName值是特性的名稱,nodeValue值是特性的值。
    var html=document.documentElement; //獲取特性實例所在的對象 html.attributes;//attributes屬性是Element.prototype上的屬性

    ?
    這個對象是NamedNodeMap類型的實例,這個對象的原型鏈關(guān)系為html.attributes.__proto__->NamedNodeMap.prototype->Object.prototype。這個對象里面又有幾個屬性,這幾個屬性才是我們需要的真正特性對象。

    html.attributes["0"];// lang="zh-cn" 是一個特性節(jié)點 html.attributes["1"];// style="overflow:hidden;" 是另一個特性節(jié)點 html.attributes["lang"].nodeName;// "lang" lang特性節(jié)點的nodeName值 html.attributes["lang"].nodeValue;// "zh-cn" html.attributes["0"] instanceof Attr;// true (3).對于Text類型節(jié)點:原型鏈的繼承關(guān)系為:某文本節(jié)點.__proto__->Text.prototype->CharacterData.prototype->Node.prototype->EventTarget.prototype。

    nodeName值為"#text",nodeValue值為節(jié)點所包含的文本。
    (4).對于CDATASection類型節(jié)點:該類型只針對基于XML文檔。原型鏈的繼承關(guān)系為:CDATASection實例._proto__->CDATASection.prototype->Text.prototype->CharacterData.prototype->Node.prototype->EventTarget.prototype。

    nodeName值為"#cdata-section",nodeValue值為CDATA區(qū)域中的內(nèi)容。
    (5).對于Comment類型節(jié)點:原型鏈的繼承關(guān)系為:Comment類型實例.__proto__->Comment.prototype->CharacterData.prototype->Node.prototype->EventTarget.prototype。

    nodeName值為"#comment",nodeValue值為注釋的內(nèi)容。
    (6).對于Document類型節(jié)點:原型鏈的繼承關(guān)系為(以瀏覽器中document為例):document.__proto__->HTMLDocument.prototype->Document.prototype->Node.prototype->EventTarget.prototype。

    可以看到Document.prototype上的屬性和方法很多有176個,返回這個數(shù)組是Array類型的實例。







    發(fā)現(xiàn)了document節(jié)點對象和element元素節(jié)點對象的事件屬性還不是統(tǒng)一繼承的,是在各自原型鏈上繼承的事件屬性。
    NodeName值為"#document",NodeValue值為null。
    (7).對于DocumentType類型節(jié)點:原型鏈的繼承關(guān)系為:document.doctype.__proto__->DocumentType.prototype->Node.prototype->EventTarget.prototype。

    nodeName的值為doctype的名稱,nodeValue的值為null。
    (8).對于DocumentFragment類型的節(jié)點:原型鏈的繼承關(guān)系為:文檔片段實例.__proto__->DocumentFragment.prototype->Node.prototype->EventTarget.prototype。

    注意到這也和Document.prototype上的方法重合了。
    nodeName的值"#document-fragment",nodeValue的值為null。
  • childNodes屬性:

    每個節(jié)點都可繼承該屬性,其中保存著NodeList對象。
    區(qū)別NodeList接口和HTMLCollection接口:
    (1).NodeList接口是為節(jié)點的childNodes屬性提供的,原型鏈的關(guān)系為:某節(jié)點.childNodes.__proto__->NodeList.prototype->Object.prototype。
    符合的有g(shù)etElementsByName,childNodes,querySelectorAll等

    對于原型上的item方法,返回NodeList對象中指定索引的節(jié)點,如果索引越界,則返回?null?。等價的寫法是?nodeList[idx]?, 不過這種情況下越界訪問將返回?undefined?(因為是以數(shù)組形式訪問的)。
    對arguments對象使用Array.prototype.slice()方法將其轉(zhuǎn)換為數(shù)組,采用同樣方法也可以將NodeList類型集合轉(zhuǎn)換為數(shù)組類型,其實就是就是在類數(shù)組對象的上下文中調(diào)用原生的slice方法。
    function transToArr(collections,start,end){var length=arguments.length;if(length==0){return;}else if(length==1){return Array.prototype.slice.call(collections); }else{//判斷start,end類型if(typeof arguments[1]=='number'){if(typeof arguments[2]=='number'){return Array.prototype.slice.call(collections,start,end);}else{//end參數(shù)不是number類型時,slice返回length之前的項end=collections.length;return Array.prototype.slice.call(collections,start,end);}}} } (2)HTMLCollection接口是為一個包含了元素的通用集合,原型鏈的關(guān)系為:通過某用法(比如getElementsByTagName,getElementsByClassName,getElementsByTagNameNS,document.forms等)獲取的節(jié)點集合.__proto__->HTMLCollection.prototype->Object.prototype

    (3)NodeList類型集合大部分時候和HTMLCollection類型集合都是即時更新的,當(dāng)其所包含的文檔結(jié)構(gòu)發(fā)生改變時,它會自動更新。以下圖片為示例,nodechilds集合和lis集合雖然保存的內(nèi)容一樣,但它兩不相等,是因為nodechilds保存的引用地址和lis保存的引用地址不一樣,但這兩引用地址所指向的內(nèi)存堆中各的自集合對象里的每一項引用都是同一個element節(jié)點對象。所以刪除一個li節(jié)點后,nodechilds和lis集合都會發(fā)生變化。


    正是因為動態(tài)集合,childNodes.length會實時變化,因而 //刪除childNodes中的所有文本節(jié)點,因為child.length是動態(tài)變化的,所以分情況i++ var child=parent.childNodes; for(var i=0;i<child.length;){if(child[i].nodeType==3){ul.removeChild(child[i]); //不用i=0回歸到開時就用上次的i就可 }else{i++;} } 但NodeList也有時候表現(xiàn)為靜態(tài)集合,以意味著對文檔對象模型任何改動都不會影響集合內(nèi)容。querySelectorAll就是靜態(tài)的

    所以當(dāng)你選擇遍歷NodeList中所有項,或緩存列表長度時候,考慮要用哪種。
  • parentNode屬性:

    該屬性指向文檔樹中的父節(jié)點(可能是Document類型也可能是Element類型)
  • previousSibling和nextSibling屬性:

    childNodes列表中第一個節(jié)點的previousSibling屬性值為null,列表中最后一個節(jié)點的nextSibling屬性也為null。
  • firstChild和lastChild屬性:

    父節(jié)點的這兩個屬性分別指向其childNodes的第一個和最后一個節(jié)點,在只有一個子節(jié)點情況下,firstChild和lastChild指向同一個節(jié)點。若沒有子節(jié)點,這兩屬性為null。
  • hasChildNodes():

    這個函數(shù)的writable屬性看來是允許可寫的,那就重寫該方法試試,我是重寫在節(jié)點實例對象上了,當(dāng)然你也可以在原型Node.prototype上重寫該方法是可以的。

    在節(jié)點包含一個或多個子節(jié)點情況下返回true,在判斷時這比childNodes.length更簡便。
  • ownerDocument:

    該屬性指向表示整個文檔的文檔節(jié)點。這種關(guān)系表示的是任何節(jié)點都屬于它所在的文檔,任何節(jié)點都不能同時存在兩個或兩個以上文檔中。當(dāng)我們不必在節(jié)點層次中通過層層回溯到達頂端而是可以直接?節(jié)點對象.ownerDocument?訪問,但要注意?document.ownerDocument;// null?文檔節(jié)點本身的文檔節(jié)點為null。
  • parentNode.appendChild():返回新增節(jié)點。
    又是偶然我發(fā)現(xiàn)一個好玩的現(xiàn)象,當(dāng)重寫Node.prototype.appendChild方法后,發(fā)現(xiàn)只要可獲得焦點的區(qū)域(比如a元素,input元素,button元素等)獲得焦點后就會執(zhí)行appendChild函數(shù),但是當(dāng)輸入內(nèi)容期間并不觸發(fā)該函數(shù),然后刪除內(nèi)容的時候又會觸發(fā)該函數(shù)執(zhí)行。每次執(zhí)行就執(zhí)行吧它還很奇怪的執(zhí)行4次。由此可以猜想當(dāng)在文檔中獲得一個焦點后就相當(dāng)于觸發(fā)了appendChild事件??因為DOM文檔結(jié)構(gòu)本來靜態(tài)的,突然插進來一個光標(biāo),DOM結(jié)構(gòu)被改動了所以才會觸發(fā)appendChild?因為光標(biāo)一直在DOM結(jié)構(gòu)中的某個位置如果沒有移出的話,在原地方編輯內(nèi)容因為還是在原地方改動所以并不觸發(fā)appendChild。就是不理解為什么每次觸發(fā)要執(zhí)行4次該函數(shù)(對于博客園這個編輯頁面來說是4次,其他頁面測試也有3次的)。而我們平常之所以插入光標(biāo),輸入內(nèi)容,刪除內(nèi)容,離開光標(biāo)感覺瀏覽器對此并沒什么反應(yīng)我估計是JS引擎實現(xiàn)appendChild方法內(nèi)部給做了妥善處理,其實應(yīng)該還是觸發(fā)這個DOM級的事件了吧。

    再次回歸主題:appendChild()用于向childNodes列表的末尾添加一個節(jié)點,添加后,childNodes的新增節(jié)點,父節(jié)點及以前的最后一個子節(jié)點的關(guān)系指針都會得到相應(yīng)更新。如果傳入到appendChild()中的節(jié)點已經(jīng)是文檔中的一部分了,那結(jié)果就是將該節(jié)點從原來位置移動到新位置。
    var a=document.body.firstChild; document.body.appendChild(document.body.firstChild)==a;// true a==document.body.lastChild;// true
  • parentNode.insertBefore(要插,參照):插入到childNodes列表中某個特定位置,參數(shù)一為要插入的節(jié)點,參數(shù)二為作為參照的節(jié)點。插入節(jié)點后被插入的節(jié)點會變成參照節(jié)點的前一個同胞節(jié)點(previousSibling),返回被插入的節(jié)點。如果參照節(jié)點是null,則insertBefore的效果和appendChild()一樣,可以這么理解:把源節(jié)點插入到目標(biāo)節(jié)點null之前,那誰是null節(jié)點呢,不就是父節(jié)點的最后一個子節(jié)點的nextSibling嗎,所以插到這個null節(jié)點之前就相當(dāng)于插入父節(jié)點的最后一個子節(jié)點之后。基于這個思路可以實現(xiàn)我們自己的insertAfter()
    //要插入到desEle之后,相當(dāng)于插入desEle.nextSibling之前,返回被插入的srcEle Node.prototype.insertAfter=function(srcEle,desEle){this.insertBefore(srcEle,desEle.nextSibling);return srcEle; }
  • parentNode.replaceChild(newNode,parentNode.child):參數(shù)為要插入的新節(jié)點,要替換的節(jié)點。要替換的節(jié)點將由這個方法返回并從文檔樹中移除,要插入的節(jié)點占據(jù)其位置。新節(jié)點的所有關(guān)系指針都會從被它替換的節(jié)點復(fù)制過來。盡管從技術(shù)上講被替換的節(jié)點仍然還在文檔中,但它在文檔中已經(jīng)沒有自己的位置。
    var parent=$('#hdtb-msb'); var first=parent.firstChild; var last=parent.lastChild; var firstnode=parent.replaceChild(last,first); firstnode;// <div class=?"hdtb-mitem hdtb-msel hdtb-imb">?全部?</div>? firstnode.ownerDocument;// #document 節(jié)點 證明還在文檔樹
  • removeChild():參數(shù)為要移除的節(jié)點,返回被移除的節(jié)點。被移除的節(jié)點仍然為文檔所有,但在文檔中已經(jīng)沒有自己的位置。
  • node.cloneNode():用于創(chuàng)建調(diào)用這個方法的節(jié)點的一個完全相同的副本。參數(shù)為true表示進行深復(fù)制(復(fù)制節(jié)點及其整個子節(jié)點樹),參數(shù)為false進行淺復(fù)制(只復(fù)制節(jié)點本身)。復(fù)制后返回的節(jié)點屬于文檔所有但并沒有為它指定父節(jié)點,可通過appendChild(),insertBefore(),replaceChild()將它添加到文檔中。
    var clone1=last.cloneNode(true); clone1;// <a class=?"hdtb-tl" id=?"hdtb-tls" role=?"button" tabindex=?"0" data-ved=?"0ahUKEwiYht2SptbLAhVDao4KHSbJBqIQ2x8ICigF">?搜索工具?</a>? var clone2=last.cloneNode(false); clone2;// <a class=?"hdtb-tl" id=?"hdtb-tls" role=?"button" tabindex=?"0" data-ved=?"0ahUKEwiYht2SptbLAhVDao4KHSbJBqIQ2x8ICigF">?</a>? clone1.ownerDocument==clone2.ownerDocument // true

    cloneNode()方法不會復(fù)制添加DOM節(jié)點的JavaScript屬性,例如事件處理程序。這個方法只復(fù)制特性(包括通過特性綁定的事件處理程序?<h1 onclick="console.log('xxx')">xxx</h1>?會將事件復(fù)制成功),子節(jié)點(深復(fù)制情況下),其他一切都不會復(fù)制。?

  • normalize():處理文檔樹中的文本節(jié)點。由于解析器或DOM操作等原因,可能會出現(xiàn)文本節(jié)點不包含文本,或者接連出現(xiàn)兩個文本節(jié)點的情況。當(dāng)在某個節(jié)點上調(diào)用這個方法時,就會在該節(jié)點的后代節(jié)點中查找上述兩種情況,如果找到空文本節(jié)點就刪除它,如果找到相鄰文本節(jié)點則將它合并為一個文本節(jié)點。
    空文本節(jié)點指的是內(nèi)容為空才能被刪除,比如 document.createTextNode(''); document.createTextNode(' '); document.createTextNode(' '); ...

    ?也就是看該文本節(jié)點的data(ChacterData.prototype上的屬性)值就可以了,圖片上的data值是回車雖然在呈現(xiàn)上和空文本節(jié)點一樣,但并不是空所以不能被刪除了,所以注意這樣編代碼ul的childNodes里的文本節(jié)點其實是回車符。

    <ul><li></li><li></li> </ul>
  • ?

    參考:
    《JavaScript高級程序設(shè)計》

    MDN HTMLCollection
    MDN NodeList

    轉(zhuǎn)載于:https://www.cnblogs.com/venoral/p/5293575.html

    總結(jié)

    以上是生活随笔為你收集整理的从原型链看DOM--Node类型的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。