HTML DOM 探索

HTML DOM 探索

2017年2月10日20:54:11 CHJ_1993

1、前言

? 因為最近比較忙,好久沒有寫博客了,記得我第一篇自我介紹的博客說經(jīng)常給大家分享一些我學(xué)習(xí)的知識,但是時間過去這么久了,也沒有更新幾篇本章,可能剛開始寫的文章也很爛。作為博客新手,希望大家原諒一下。

? 今天有點時間, 我就來跟大家探討一下 HTML DOM 的一些知識。好了下面開始正文.....

2、DOM的概念

DOM 是 (Document Object Model) 的縮寫

  • DOM 是針對 XML 和 HTML 文檔的一個 api (應(yīng)用程序接口)
  • DOM 中描述了一個層級化的節(jié)點樹
  • DOM 中允許開發(fā)人員對頁面的某一部分內(nèi)容進行修改,移除,添加

W3C 中 DOM標(biāo)準(zhǔn)化分類分成三種:

  • 核心 DOM ==== 針對任何結(jié)構(gòu)化文檔的標(biāo)準(zhǔn)模型
  • XML DOM ==== 針對XML文檔的標(biāo)準(zhǔn)模板
  • HTML DOM ==== 針對HTML 文檔的標(biāo)準(zhǔn)模板

DOM標(biāo)準(zhǔn)分化分為三種,那么前面兩種我們今天不進行探索,我們今天主要來了解的是HTML DOM

3、HTML DOM 的探索

3.1 什么是HTML DOM ?

HTML DOM 是HTML的標(biāo)準(zhǔn)對象模型,也是HTML的標(biāo)準(zhǔn)編程接口

HTML DOM 定義了所有HTML元素的對象 ** 和 屬性,以及訪問他們的方法**

換句話說, HTML DOM 是關(guān)于如何獲取、修改、添加或者刪除HTML元素的標(biāo)準(zhǔn)

3.2 HTML DOM的節(jié)點

根據(jù)W3C(萬維網(wǎng)) 的HTML DOM標(biāo)準(zhǔn),HTML文檔中所有的內(nèi)容都是節(jié)點

  • 整個文檔 是一個文檔節(jié)點
  • 每個HTML元素都是元素節(jié)點
  • HTML 元素內(nèi)的文本是文本節(jié)點
  • 每個 HTML 屬性是屬性節(jié)點
  • 注釋是注釋節(jié)點

下面我們引用網(wǎng)上的一張圖來描述一下: (HTML DOM 的節(jié)點樹結(jié)構(gòu))

3.2.1 HTML DOM 節(jié)點分類

HTML DOM 中個一共存在12 個節(jié)點類型,任何一個節(jié)點類型都屬于這12個節(jié)點類型之一

如下表:

屬性名稱 代表中文含義
Node.ELEMENT_NODE 元素
Node.ATTRIBUTE_NODE 元素中的屬性
Node.TEXT_NODE 純文本(沒有子節(jié)點)
Node.CDATA_SECTION_NODE 子節(jié)點是TextNode
Node.ENTITY_REFERENCE_NODE 文檔中的實體引用
Node.ENTITY_NODE DTD中的實體定義
Node.PROCESSING_INSTRUCTION_NODE 一個文檔處理程序中使用的特有指令
Node.COMMENT_NODE 注釋
Node.DOCUMENT_NODE 最外層的 (根節(jié)點)
Node.DOCUMENT_TYPE_NODE 文檔類型定義
Node.DOCUMENT_FRAGMENT_NODE 更小型的Docment 的節(jié)點,定義整個數(shù)據(jù)類型主要是為了方便只希望提取文檔的某一部分時使用
Node.NOTATION_NODE DTD 的Nation定義

3.2.2 HTML DOM 文檔節(jié)點的屬性

文檔節(jié)點的屬性,我們今天主要認識的就只有三個:

  • nodeName

    節(jié)點名稱,只讀

  • nodeValue

    節(jié)點的值 ,可讀可寫

  • nodeType

    節(jié)點的類型,只讀

3.3 HTML DOM 核心對象 document 對象

在JavaScript中 是通過Document 來表示文檔的,Document 的屬性如下:

  • document的節(jié)點類型 (nodeType) 為 9
  • document 的節(jié)點名稱 (nodeName) 是 #document
  • document 的節(jié)點值(nodeValue) 為空(null)
  • document 是沒有父節(jié)點(parentNode) 的
  • document 也沒有根元素(ownerDocument)

3.3.1 通過document 來獲取 元素(節(jié)點)

在JavaScript 獲取元素的方式主要有以下中方法

  1. document.getElementById() 通過ID的方式來獲取元素.
  2. document.getElementsByTagName() 根據(jù)標(biāo)簽名來獲取元素
  3. document.getElementsByName() 通過標(biāo)簽的name屬性的值來獲取元素
  4. document.getElementsByClassName() 通過class 的屬性值來獲取元素
  5. querySelector() 通過選擇器名稱來獲取元素(獲取匹配到的第一個)
  6. querySelectorAll() 通過選擇器名稱來獲取元素(獲取全部)
3.3.1.1 document.getElementById()

通過元素中ID屬性的屬性值來查找元素

語法: node.getElementById("id");

注意:

  1. 使用該方法不能同時查找多個ID
  2. 如果有HTML中有相同ID,則只會返回一個元素
  3. 在 低于 IE 8 版本的IE瀏覽器中,對匹配元素的ID,該方法不區(qū)分大小寫

代碼示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title></title>
    </head>
    <body>
        <h1 id="h1">我是標(biāo)題</h1>
    </body>
    <script type="text/javascript">
        var eH1 = document.getElementById("h1");
        alert(eH1.innerHTML);
    </script>
</html>

3.3.1.2 document.getElementsByTagName()

根據(jù)標(biāo)簽名來獲取元素

語法: node.getElementsByTagName(標(biāo)簽名稱)

返回值: 返回多個同標(biāo)簽名的Element組成的集合

代碼示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <h1 id="myH1" class="myH1class">我是H1標(biāo)簽</h1>
        <h1 id="myH2" class="myH1class">我是H1標(biāo)簽</h1>
        <h1 id="myH3" class="myH1class">我是H1標(biāo)簽</h1>
        <h1 id="myH4" class="myH1class">我是H1標(biāo)簽</h1>
    </body>
    <script>
        var h1_ls  = document.getElementsByTagName("h1");
        console.log(h1_ls);
        for (var i = 0; i < h1_ls.length; i++) {
            console.log(h1_ls[i].id); //元素的ID
            console.log(h1_ls.item(i).id); //通過元素的Item 來獲取Item內(nèi)容
        }
    </script>
</html>

3.3.1.3 document.getElementsByName()

通過標(biāo)簽的name屬性的值來獲取元素,可能出現(xiàn)

語法: docuemnt.getElementsByName("name屬性值");

返回值: 返回多個相同的name值的Element組成的集合

注意: 該方法存在嚴(yán)重的兼容性問題,在IE中,此方法還能獲取ID屬性匹配的值

代碼示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <form action="" method="get">
            <input type="checkbox" name="input_name" value="洗澡" />洗澡
            <input type="checkbox" name="input_name"  value="喝水" />喝水
        </form>
    </body>
    <script type="text/javascript">
        var names = document.getElementsByName('input_name');
        for (var i = 0; i<names.length; i++) {
            console.log(names[i].value);
        }
    </script>
</html>

3.3.1.4 document.getElementsByClassName()

通過相同的class屬性的值來獲取元素

語法: document.getElementsByClassName(class屬性值);

返回值: 返回多個相同的class屬性值的Element組成的集合

代碼示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <h1 id="myH1" class="myH1class">我是H1標(biāo)簽</h1>
        <h2 id="myH2" class="myH1class">我是H2標(biāo)簽</h1>
        <h3 id="myH3" class="myH1class">我是H3標(biāo)簽</h1>
        <h4 id="myH4" class="myH1class">我是H4標(biāo)簽</h1>
    </body>
    <script type="text/javascript">
        var myClassLi = document.getElementsByClassName('myH1class');
        for (var i = 0; i<myClassLi.length; i++) {
            console.log(myClassLi[i].value);
        }
    </script>
</html>
3.3.1.4 querySelector()

通過CSS 選擇器的放來來獲取元素,

指定一個或者多個匹配的CSS選擇器,id,class, 類型,屬性

如果針對多個選擇器,中間使用d"逗號分隔",

語法: document.querySelector("#demo")

返回值: 直接返回匹配到的第一個元素,如果沒有找到則返回null

代碼示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        
    </head>
    <body>
        <p id="demo"></p>
    </body>
    <script type="text/javascript">
        var p_1 = document.querySelector("#demo");
        console.log(p_1);
    </script>
</html>

3.3.1.4 querySelectorAll()

HTML5引入的一種新的查找元素的方法

語法: document.querySelectorAll(".p_1")

返回值: 返回查找到的所有相同選擇器的Element 集合

注意: 該方法不是實時返回的,只有調(diào)用的時候才會返回,因為這樣開發(fā)人員通??梢岳脗晤愡x擇器( :hover , :visited ) 去訪問用戶的瀏覽習(xí)慣等,所以現(xiàn)在很多瀏覽器不支持該方法

代碼示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div class="p_1"></div>
        <div class="p_1"></div>
        <div class="p_1"></div>
    </body>
    <script type="text/javascript">
        var all = document.querySelectorAll(".p_1");
        console.log(all)
    </script>
</html>

好了,說了上面一大推,篇幅有點長了,但是我覺得我還是要繼續(xù)把下面幾點說完

上面說了元素的獲取的幾種方法,那么現(xiàn)在我們可以獲取到元素了,那么元素和元素之間的關(guān)系又是怎么樣的? 那么下面我們來說 元素節(jié)點之間的關(guān)系

3.3.2 HTML DOM 中節(jié)點的關(guān)系

我們學(xué)過HTML 的都知道 HTML元素之間的關(guān)系 有父子關(guān)系,和兄弟關(guān)系(同級元素)

那么在DOM中節(jié)點關(guān)系有以下幾種

  1. parent 父節(jié)點
  2. child子節(jié)點
  3. sibling 兄弟節(jié)點(同級節(jié)點)
  4. root 根節(jié)點

如圖所示:

  • 父節(jié)點屬性(parentNode)

    獲取一個元素的父節(jié)點

    語法: node.parentNode

  • 兄弟節(jié)點屬性(sibling)

    同級節(jié)點屬性又分為兩個小的屬性:

    ? 上一個同級節(jié)點(previousSibling)

    ? 獲取某個元素的上一個同級節(jié)點

    ? 語法:node.previousSibling

    ? 下一個同級節(jié)點(nextSibling)

    ? 獲取某個元素的下一個同級節(jié)點

    ? 語法 node.nextSibling

    因為在使用者兩種方法獲取到,可能含有<div> </div> 中間的空格,又因為JavaScript 是一種弱類型語言,就衍生了下面的兩種方法:

    ? 上一個同級元素(previousElementSibling)

    ? 獲取某個元素的上一個同級元素

    ? 語法:node.previousElementSibling

    ? 下一個同級元素(nextElementSibling)

    ? 獲取某個元素的下一個同級元素

    ? 語法 node.nextElementSibling

  • 根節(jié)點 ( ownerDocument)

    獲取某個元素的根元素

    語法:node.ownerDocument

    獲取一個元素的根節(jié)點

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="demo">
            <a href="###">搜狐</a><div id="div">DIV</div><div>
                <a href="#"></a>
            </div>
            <input type="text" />
        </div>
    </body>
    <script type="text/javascript">

        //parentNode 獲取父節(jié)點
        var div = document.getElementById("demo");
        div.previousSibling;
        console.log(div.parentNode.nodeName); //BODY
        
        //previousSibling 獲取元素的上一個同級節(jié)點
        var div1 = document.getElementById("div");
        var preSib= div1.previousSibling;
        console.log(preSib);
        
        //previousElementSibling  獲取元素的上一個同級節(jié)點
        var preSib2= div1.previousElementSibling;
        console.log(preSib2);
        
        //nextSibling 獲取元素的下一個同級節(jié)點
        var nextElement = div1.nextSibling;
        console.log(nextElement)
        
        //nextElementSibling 獲取元素的下一個同級節(jié)點
        var nextElement2 = div1.nextElementSibling;
        console.log(nextElement2)
        
        //ownerDocument  獲取元素的根節(jié)點
        var rootElement = div1.ownerDocument;
        console.log(rootElement)
    </script>
</html>

  • 子節(jié)點屬性(ChildNodes)

    在這里要寫的是三個小屬性

    ? 所有子節(jié)點(ChildNodes)

    ? 用來獲取一個元素的所有子節(jié)點

    ? 返回值: 一個數(shù)組,只獲取子節(jié)點,不能獲取子節(jié)點的子節(jié)點

    ? 語法:node.chilNodes

    ? 第一個子節(jié)點(firstChild)

    ? 獲取元素的第一個子節(jié)點 ,如果匹配不到則返回null

    ? 語法:node.firstChild

    ? 最后一個子節(jié)點(lastChild)

    ? 獲取元素的最后一個子節(jié)點 ,如果匹配不到則返回null

    ? 語法 node.lastChild

    因為在使用者兩種方法獲取到,可能含有<div> </div> 中間的空格,又因為JavaScript 是一種弱類型語言,就衍生了下面的兩種方法:

    ? 第一個子元素(firstElementChild)

    ? 獲取某個元素的第一個子元素

    ? 語法:node.firstElementChild

    ? 最后一個子元素(lastElementChild)

    ? 獲取某個元素的最后一個子元素

    ? 語法 node.lastElementChild

    代碼:

    <!DOCTYPE html>
    <html>
      <head>
          <meta charset="UTF-8">
          <title></title>
      </head>
      <body>
          <div id="demo">
              <a href="###">簡書</a>
              <a href="###">百度</a>
              <div>
                  <a href="###">博客</a>
              </div>
              <input type="text" name="input_name" id="input" value="" />
          </div>
      </body>
      <script type="text/javascript">
          //獲取元素的所有子節(jié)點
          var nodes = document.getElementById("demo").childNodes;
          console.log(nodes);
          for (var i = 0;i<nodes.length; i++) {
              console.log(nodes[i].nodeName);
          }
          
          //獲取所有子元素的個數(shù)
          var nodes = document.getElementById("demo").childElementCount;
          console.log(nodes);
          
          //firstChild 獲取元素的第一個子節(jié)點
          var div = document.getElementById("demo");
          var firstChlid = div.firstChild;
          console.log(firstChild);
          console.log(firstChild.nodeName);
          //firstElementChild  獲取元素的第一個子節(jié)點
          var firstChild2 = div.firstElementChild;
          console.log(firstChild2);
          console.log(firstChild2.nodeName);
          
          
          //firstChild 獲取元素的第一個子節(jié)點
          var div = document.getElementById("demo");
          var lastCh = div.lastChild;
          console.log(lastCh);
          console.log(lastCh.nodeName);
          
          //firstElementChild  獲取元素的第一個子節(jié)點
          var lastChild = div.lastElementChild;
          console.log(lastChild);
          console.log(lastChild.nodeName);
      </script>
    </html>
    
    

    ?

有比比了好久,說了那么多的元素之間的關(guān)系,那么我們平時獲取元素,不僅僅只是想獲取到他的一下屬性,了解他的關(guān)系吧,同樣我們有事需要對元素進行操作,那么下面我們來說說對Node節(jié)點的操作

3.3.2 HTML DOM 中節(jié)點增加 刪除 修改 創(chuàng)建

由于文章篇幅比較長了,大家也是不想看到我說一大推的廢話了 那么我下面直接貼出代碼 給大家看 在代碼中我也是注釋的比較清楚,以后再來修改

代碼如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="demo">
            
        </div>
        
        <ul id="language">
            <li>Java</li>
            <li>C#</li>
        </ul>
        <button onclick="addNode()">點擊添加一個新的首節(jié)點</button>
        <button onclick="removeNode()">刪除一個子節(jié)點</button>
        <button onclick="replaceNode()">替換首節(jié)點</button>
        <button onclick="cloneNodes()">克隆整個列表</button>
    </body>
    <script type="text/javascript">
        /*
        修改
         *  1.創(chuàng)建文本節(jié)點
         *      createTextNode(text)
         *          參數(shù): text 文本
         *          返回值: 創(chuàng)建的文本標(biāo)簽
         *      該方法屬于 document 的
         *  2.添加一個子節(jié)點
         *      addpendChild(node)
         *          參數(shù):
         *              node: 必選參數(shù),需要添加的節(jié)點
         *          返回值: 參數(shù)對象本身
         *      翻譯過來時追加,如果本身已經(jīng)有child ,則追加到child之后
         *      添加進去就是 lastChild
         *  3.創(chuàng)建新的元素節(jié)點  
         *      createElement(nodeName)
         *          參數(shù):
         *              nodeName: 需要創(chuàng)建的元素名稱
         *          返回值: 創(chuàng)建的元素節(jié)點
         *  4.在節(jié)點之前加入新的節(jié)點
         *      insertBefor(newNode,existingNode)
         *          參數(shù):
         *              newNode:需要插入的新節(jié)點
         *              existingNode:  當(dāng)前插入的目標(biāo)節(jié)點
         *          會將新節(jié)點插入到目標(biāo)節(jié)點之前
         *  5.移除一個子節(jié)點
         *      removeChild(node)
         *          參數(shù):
         *              node:必選參數(shù),表示需要移除的子節(jié)點
         *  6.替換一個子節(jié)點
         *      replaceChild(newNode,oldNode)
         *          參數(shù):
         *              newNode: 新節(jié)點
         *              oldNode: 舊的節(jié)點
         *  7.克隆節(jié)點
         *      該方法用于創(chuàng)建指定的節(jié)點的精準(zhǔn)拷貝所有的屬性和屬性值
         *      cloneNode(deep)
         *          參數(shù):
         *              deep: true/ false
         *                  true: 將遞歸復(fù)制當(dāng)前節(jié)點的所有節(jié)點
         *                  false: 只復(fù)制當(dāng)前節(jié)點
         */
        
        var divDemo = document.getElementById("demo");
        //======創(chuàng)建一個文本節(jié)點====
        var textNode = document.createTextNode("hello world");
        console.log(textNode.nodeName);  // #text 
        console.log(textNode.nodeValue);  // hello world 
        
        //=====添加一個文本節(jié)點===
        var appendNode = divDemo.appendChild(textNode);
        console.log(appendNode.nodeValue);  //hello world
        
        //===== 創(chuàng)建元素節(jié)點====
        var newElement  = document.createElement("a");
        
        var newElementText = document.createTextNode("新建的元素內(nèi)容");
        newElement.appendChild(newElementText);
        var divDemo = divDemo.appendChild(newElement);
        
        //====在節(jié)點之前加入新的節(jié)點===
        function addNode(){
            var newItem = document.createElement("li"); //創(chuàng)建一個新的li元素
            var newItemTextNode = document.createTextNode("Javascript");
            newItem.appendChild(newItemTextNode);
            
            var languageList = document.getElementById("language");
            //將新創(chuàng)建的Item添加到目標(biāo)節(jié)點之前
            languageList.insertBefore(newItem,languageList.firstChild);
        }
        
        //=======移除子節(jié)點====
        function removeNode(){
            var languageList = document.getElementById("language");
            var li_lsit = languageList.getElementsByTagName("li");
            //移除li中的第一個
            languageList.removeChild(li_lsit[0]);
        }
        
        
        //============替換子節(jié)點=====
        function replaceNode(){
            
            var languageList = document.getElementById("language");
            
            var newLi = document.createElement("li");
            newLi.innerHTML="node.js"
            console.log(newLi.value);
            
            languageList.replaceChild(newLi,languageList.firstElementChild);
            
        }
        
        //==========克隆節(jié)點===========
    
        function cloneNodes(){
            var languageList = document.getElementById("language");
            
            var newList = languageList.cloneNode(false);
            document.getElementsByTagName("body")[0].appendChild(newList);
        }
    </script>
</html>

好了 看到這里 我的文章也就結(jié)束了,感謝您的瀏覽!

你們的支持,就是我前進的動力

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容