jacascript DOM節點——元素節點、屬性節點、文本節點

来源:http://www.cnblogs.com/sspeng/archive/2017/04/18/6680545.html
-Advertisement-
Play Games

前言:這是筆者學習之後自己的理解與整理。如果有錯誤或者疑問的地方,請大家指正,我會持續更新! 元素節點 元素節點就是HTML標簽元素,元素節點主要提供了對元素標簽名、子節點及屬性的訪問; 元素節點的三個node屬性:nodeType:1、nodeName/TagName:元素的標簽名大寫、nodeV ...


前言:這是筆者學習之後自己的理解與整理。如果有錯誤或者疑問的地方,請大家指正,我會持續更新!

 

元素節點

  元素節點就是HTML標簽元素,元素節點主要提供了對元素標簽名、子節點及屬性的訪問;

  元素節點的三個node屬性:nodeType:1、nodeName/TagName:元素的標簽名大寫、nodeValue:null;

  其父節點 parentNode 指向包含該元素節點的元素節點 Element 或文檔節點 Document;

  元素的 childNodes 屬性中包含了它的所有子節點,這些子節點可能是元素、文本、註釋、處理指令節點;

  childNodes 結合 NodeType 可以檢查有幾個元素子節點:

        <ul class="list" id="list">
            <li class="in"></li>
            <li class="in"></li>
        </ul>
        <script>
            var oList = document.getElementById('list');
            var children = oList.childNodes;
            var num = 0;
            for(var i = 0; i < children.length; i++){
                if(children[i].nodeType == 1){
                    num++;
                }
            }
            console.log(num);//2   有2個元素子節點   
        </script>

  

  操作屬性的方法主要有hasAttribute()、getAttribute()、setAttribute()、removeAttribute()四個,可以針對任何屬性使用,包括那些以HTMLElement類型屬性的形式定義的屬性;

  • obj.hasAttribute(attr)方法返回一個布爾值,表示當前元素節點是否包含指定屬性;
  • IE6/IE7不支持 hasAttribute() 方法;
  • obj.hasAttribute(attr)檢測 class 屬性時,直接用 class 就可以了,不要用className;
  • obj.hasAttribute(attr)檢測 for屬性時,直接用 for就可以了,不要用htmlFor;
        <div class="wrapper" id='test' for="nice" style="width:200px;height:100px;background:#f0f">123</div>
        
        <script type="text/javascript">
            var oTest = document.getElementById('test');
            //IE6/IE7不支持hasAttribute方法
            console.log(oTest.hasAttribute('class'));//true
            console.log(oTest.hasAttribute('className'));//false   
            console.log(oTest.hasAttribute('id'));//true
            console.log(oTest.hasAttribute('style'));//true
            console.log(oTest.hasAttribute('for'));//true
            console.log(oTest.hasAttribute('htmlFor'));//false
        </script>

 

  • obj.getAttribute(attr)方法用於取得屬性的值,如果給定名稱的屬性不存在或無參數則返回null;
  • obj.getAttribute(attr)獲取 class 時,直接用 class 就可以了;IE6/IE7除外,IE6/IE7的 getAttribute(attr) 方法要用 className;
  • obj.getAttribute(attr)獲取 for時,直接用 for就可以了;
  • obj.setAttribute(attr,value)方法接受兩個參數:要設置的屬性名和值,如果已經存在,則替換現有的值。如果屬性不存在,則創建該屬性並設置相應的值。該方法無返回值;
  • obj.setAttribute(attr,value)設置 class 時,直接用 class 就可以了;
  • obj.setAttribute(attr,value)設置 for 時,直接用 for 就可以了;
  • obj.setAttribute(attr,value)設置 style 時,直接用 style 就可以了;在 IE7及以下,用 obj.style.setAttribute("cssText",value);  這裡的 style 只是行間樣式;
  • 我們一般用 obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj)[attr]; 來獲取元素當前樣式;
        <script type="text/javascript">
            var oTest = document.getElementById('test');
            oTest.setAttribute('class','aaa'); //setAttribute直接用class就可以了
            oTest.setAttribute('className','bbb');
            console.log(oTest.class);//undefined  IE8及以下會報錯缺少標識符
            console.log(oTest.getAttribute('class'));//aaa  getAttribute直接用class就可以了
            console.log(oTest.className);//aaa
            console.log(oTest.getAttribute('className'));//bbb
            
            oTest.setAttribute('style','border:1px solid red;height: 100px;'); //setAttribute直接用 style 就可以了
            console.log(oTest.style);//所有的style設置,包括你沒有設置的,太多了,肯定不是你想要的
            console.log(oTest.getAttribute('style'));
            //border:1px solid red;height: 100px;  getAttribute直接用 style 就可以了
            
            oTest.setAttribute('for','eee'); //setAttribute直接用for就可以了
            oTest.setAttribute('htmlFor','fff')
            console.log(oTest.for);//undefined   IE8及以下會報錯缺少標識符
            console.log(oTest.htmlFor);//undefined
            console.log(oTest.getAttribute('for'));//eee  getAttribute直接用for就可以了
            console.log(oTest.getAttribute('htmlFor'));//fff
            console.log(oTest);
            //<div class="aaa" id="test" for="eee" style="ddd" classname="bbb" htmlfor="fff">123</div>
        </script>

 

  • obj.removeAttribute(attr)方法用於徹底刪除元素的屬性,這個方法不僅會徹底刪除元素的屬性值,還會刪除元素屬性。該方法無返回值;
        <div class="wrapper" id='test' for="nice" style="background:#f0f;height: 100px;">123</div>
        <script type="text/javascript">
            var oTest = document.getElementById('test');
            oTest.removeAttribute('class'); //removeAttribute直接用class就可以了
            oTest.removeAttribute('for');
            oTest.removeAttribute('style'); 
            console.log(oTest);// <div id="test">123</div>
        </script>

 

屬性節點

  屬性節點,有的叫特性節點,差不多一個意思;

  屬性節點的三個node屬性,nodeType:2、nodeName/name:屬性名稱、nodeValue/value:屬性值;

  屬性節點還有一個 specified 屬性,specified 是一個布爾值,用以區別特性是在代碼中指定的,還是預設的。這個屬性的值如果為true,則意味著在HTML中指定了相應特性,或者是通過 setAttribute() 方法設置了該屬性。在IE中,所有未設置過的特性的該屬性值都為false,而在其他瀏覽器中,所有設置過的特性的該屬性值都是true,未設置過的特性,如果強行為其設置 specified 屬性,則報錯。

  元素節點有一個 attributes 屬性,它包含一個 NamedNodeMap,包含當前元素所有的屬性及屬性值,與NodeList類似,也是一個動態的集合。元素的每一個屬性都由一個Attr節點表示,每個節點都保存在NamedNodeMap對象中,每個節點的 nodeName 就是屬性的名稱,節點的 nodeValue 就是屬性的值;

  createAttribute(attr) 創建新的屬性節點;

  attributes屬性包含以下四個方法:

  1. obj.attributes.setNamedItem(attr);  向列表中添加節點,該方法無返回值;要先創建屬性,在以nodeValue的形式賦屬性值,在傳入setNamedItem
  2. obj.attributes.getNamedItem(attr);  返回 nodeName 屬性等於 attr 的節點;以" attr=value " 形式返回;
  3. obj.attributes.removeNamedItem(attr); 從列表中移除 nodeName 屬性等於 attr 的節點,並返回該節點;
  4. obj.attributes.item(index); 返回位於下標 index 位置處的節點,也可以用[]代替, obj.attributes[index];
        <div class="wrapper" id='test' for="nice" style="background:#f0f;height: 100px;">123</div>
        <script type="text/javascript">
            var oTest = document.getElementById('test');
            console.log(oTest.attributes);// NamedNodeMap {0: class, 1: id, 2: for, 3: style, length: 4}
            console.log(oTest.attributes.item(1).specified);//true
console.log(oTest.attributes.getNamedItem(
'id'));//id='test' console.log(typeof oTest.attributes.getNamedItem('id'));//object console.log(oTest.attributes.removeNamedItem('for'));//id='test' console.log(oTest.attributes);// NamedNodeMap {0: class, 1: id, 2: style, length: 3} var abc = document.createAttribute("abc"); abc.nodeValue = "1234567"; oTest.attributes.setNamedItem(abc); //obj.attributes.setNamedItem(attr) 要先創建屬性,在以nodeValue的形式賦屬性值,在傳入setNamedItem console.log(oTest.attributes);// NamedNodeMap {0: class, 1: id, 2: style, 3: abc, length: 4} console.log(oTest.attributes.item(1));//id='test' console.log(oTest.attributes[1]);//id='test' </script>

  attributes屬性主要用於屬性遍歷。在需要將DOM結構序列化為HTML字元串時,多數都會涉及遍歷元素特性

        <div class="wrapper" id='test' for="nice" style="background:#f0f;height: 100px;">123</div>
        <script type="text/javascript">
            function outputAttributes(obj){
                var arr = [],
                    attrName,
                    attrValue,
                    i;
                for(i = 0; i < obj.attributes.length; i++){
                    attrName = obj.attributes[i].nodeName;
                    attrValue = obj.attributes[i].nodeValue;
                    arr.push(attrName + '=\"' + attrValue + '\"');
                }
                return arr.join(" ");
            }
            
            var oTest = document.getElementById('test');
            console.log(oTest.attributes);//NamedNodeMap {0: class, 1: id, 2: for, 3: style, length: 4}
            console.log(typeof oTest.attributes);//object
            
            console.log(outputAttributes(oTest));
            //class="wrapper" id="test" for="nice" style="background:#f0f;height: 100px;"
            console.log(typeof outputAttributes(oTest));//string
        </script>

 

文本節點

  文本節點的三個node屬性,nodeType:3、nodeName:'#text'、nodeValue:節點所包含的文本,其父節點 parentNode 指向包含該文本節點的元素節點,文本節點沒有子節點;

  關於文本節點,遇到最多的相容問題是空白文本節點問題。IE8及以下瀏覽器不識別空白文本節點,而其他瀏覽器會識別空白文本節點 ;所以有時候我們需要清理空白文本節點;

        <div id="test">
            <div>hello world!</div>
        </div>
        <script type="text/javascript">
            var oTest = document.getElementById('test');
            //第一個和最後一個都是空白文本節點
            console.log(oTest.firstChild);//" "   
            console.log(oTest.lastChild);//" "   
            
            console.log(oTest.childNodes);//[text, div, text]    
            //標準瀏覽器輸出[text, div, text],text表示空白文本節點
            //IE8及以下瀏覽器輸出[div],並不包含空白文本節點
            console.log(oTest.childNodes.length); //3
            //標準瀏覽器返回3
            //IE8及以下瀏覽器返回1,並不包含空白文本節點
            
            //清理空白文本節點
            function cleanWhitespace(oEelement){
                 for(var i = 0; i < oEelement.childNodes.length; i++){
                      var node = oEelement.childNodes[i];
                      if(node.nodeType == 3 && !/\S/.test(node.nodeValue)){
                          node.parentNode.removeChild(node);
                      }
                  }
            }
            cleanWhitespace(oTest);
            console.log(oTest.childNodes);//[div]
            console.log(oTest.childNodes.length); //1
        </script>

 

文本節點屬性:

  • 文本節點的 data 屬性與 nodeValue 屬性相同
  • wholeText 屬性將當前 Text 節點與毗鄰的 Text 節點,作為一個整體返回。大多數情況下,wholeText 屬性的返回值,與 data 屬性和 textContent 屬性相同;
  • 文本節點的 length 屬性保存著節點字元的數目,而且 nodeValue.length、data.length 也保存著相同的值;
        <div id="testData">hello world!</div>
        <div id="testWholeText">hello world!</div>
        <script type="text/javascript">
            var oTestData = document.getElementById('testData');
            //第一個和最後一個都是空白文本節點
            console.log(oTestData.firstChild);//"hello world!"   
            console.log(typeof oTestData.firstChild);//object   
            console.log(oTestData.childNodes.length); //1
            
            console.log(oTestData.firstChild.nodeValue);//"hello world!" 
            console.log(typeof oTestData.firstChild.nodeValue);//string
            console.log(oTestData.firstChild.data);//"hello world!" 
            //文本節點的data屬性與nodeValue屬性相同,都是 string 類型
            console.log(oTestData.firstChild.data === oTestData.firstChild.nodeValue);//true
            
            var oTestWholeText = document.getElementById('testWholeText');
            console.log(oTestWholeText.childNodes); //[text]
            console.log(oTestWholeText.childNodes.length); //1
            console.log(oTestWholeText.firstChild.wholeText);//hello world!
            console.log(oTestWholeText.firstChild.data);//hello world!   
            
            oTestWholeText.firstChild.splitText('or');
            console.log(oTestWholeText.childNodes); //[text, text]
            console.log(oTestWholeText.childNodes.length); //2
            console.log(oTestWholeText.firstChild);//#text
            console.log(oTestWholeText.firstChild.wholeText);//hello world!
            //wholeText屬性將當前Text節點與毗鄰的Text節點,作為一個整體返回。
            
            console.log(oTestData.firstChild.length);//12
            console.log(oTestData.firstChild.nodeValue.length);//12
            console.log(oTestData.firstChild.data.length);//12
        </script>

 

文本節點方法:

  文本節點的操作與字元串的操作方法相當類似。一般地,我們獲取文本都用 innerHTML,然後再去字元串的操作方法去操作。

  • document.createTextNode(text); 方法用於創建文本節點,這個方法接收一個參數,要插入節點中的文本插入的是文本,就算寫的是標簽,也是當做文本來插入的
  • splitText(index) 方法將一個文本節點分成兩個文本節點,即按照 index 指定的位置分割 nodeValue 值。原來的文本節點將包含從開始到指定位置之前的內容。這個方法會返回一個新文本節點,包含剩下的文本;
  • appendData(text) 方法將 text 添加到節點的末尾,該方法無返回值;
  • deleteData(index,count) 方法從 index指定的位置開始刪除 count 個字元,無返回值;
  • insertData(index,text) 方法在 index 指定的位置插入 text,無返回值;
  • replaceData(index,count,text) 方法用 text 替換從 index 指定位置開始到 index+count 為止的文本,無返回值;
  • substringData(index,count) 方法提取從 index 指定的位置開始到 offset+count 為止處的字元串,並返回該字元串。原來的文本節點無變化;

 

參考資料

  大神的講解更清晰,他的其他隨筆也很好, http://www.cnblogs.com/xiaohuochai/p/5819638.html


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

-Advertisement-
Play Games
更多相關文章
  • 請允許我用22種編程語言,向各位親們祝福…… C:printf("祝大家聖誕節快樂"); C++ : cout<<"祝大家聖誕節快樂"; QBasic : Print "祝大家聖誕節快樂" Asp : Response.Write "祝大家聖誕節快樂" PHP : echo "祝大家聖誕節快樂"; ...
  • 對於RBAC的一些思考 RBAC : Role Based Access Control 基於角色的訪問控制 問:引入 的目的是什麼? 答: 1. 在沒有role的時候,要決定一個角色有沒有許可權我們必須把角色和許可權綁定起來,引入role是為瞭解耦角色和許可權。 2. 解耦的好處表現在角色和許可權的變化比 ...
  • spring的MVC執行原理 優點: 1.使用Spring的IOC容器,將對象之間的依賴關係交給Spring,降低組件之間的耦合性,讓我們更專註於應用邏輯 2.可以提供眾多服務,事務管理,WS等。 3.AOP的很好支持,速食麵向切麵編程。 4.對主流的框架提供了很好的集成支持,如Hibernate, ...
  • 在gulpfile.js里添加var ejs = require('gulp-ejs') 命令行中執行: npm install gulp-ejs gulp.task('gulp-ejs', function(){ gulp.src(模版目錄 + '/**/*.html') .pipe(data(f ...
  • display || visibility list style : list style type || list style position || list style image position top || right || bottom || left z index clear fl ...
  • <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title></title> <style> /*跟運動相關的模塊都需要絕對定位*/ #idv1 {background: #CCCCCC;display: none;width: 50px;p ...
  • 說到ES6的 變數聲明,我估計很多人會想起下麵幾個主要的特點: 沒有變數聲明提升 擁有塊級作用域 暫時死區 不能重覆聲明 很多教程和總結基本都說到了這幾點(說實話大部分文章都大同小異,摘錄的居多),習慣性我還是去看了MDN上的文檔,立馬發現一個問題: In ECMAScript 2015, let ...
  • SVN
    [1]安裝 [2]配置 [3]基本操作 [4]協作 [5]常見問題 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...