JavaScriptDOM物件控制HTML元素

乘風而歸發表於2017-09-27

1.認識DOM

文件物件模型DOM(Document Object Model)定義訪問和處理HTML文件的標準方法。DOM 將HTML文件呈現為帶有元素、屬性和文字的樹結構(節點樹)。

先來看看下面程式碼:

這裡寫圖片描述

將HTML程式碼分解為DOM節點層次圖:

這裡寫圖片描述

HTML文件可以說由節點構成的集合,DOM節點有:

  1. 元素節點:上圖中<html>、<body>、<p>等都是元素節點,即標籤。

  2. 文字節點:向使用者展示的內容,如<li>...</li>中的JavaScript、DOM、CSS等文字。

  3. 屬性節點:元素屬性,如<a>標籤的連結屬性href=”http://www.imooc.com”。

節點屬性:

這裡寫圖片描述

遍歷節點樹:

這裡寫圖片描述

以上圖ul為例,它的父級節點body,它的子節點3個li,它的兄弟結點h2、P。

DOM操作:

這裡寫圖片描述

注意:前兩個是document方法。

2.getElementsByName()方法

返回帶有指定名稱的節點物件的集合。

語法:

document.getElementsByName(name)
與getElementById() 方法不同的是,通過元素的 name 屬性查詢元素,而不是通過 id 屬性。

注意:

  1. 因為文件中的 name 屬性可能不唯一,所有 getElementsByName() 方法返回的是元素的陣列,而不是一個元素。

  2. 和陣列類似也有length屬性,可以和訪問陣列一樣的方法來訪問,從0開始。

看看下面的程式碼:

這裡寫圖片描述

執行結果:

這裡寫圖片描述

3.getElementsByTagName()方法

返回帶有指定標籤名的節點物件的集合。返回元素的順序是它們在文件中的順序。

語法:

document.getElementsByTagName(Tagname)
說明:

  1. Tagname是標籤的名稱,如p、a、img等標籤名。

  2. 和陣列類似也有length屬性,可以和訪問陣列一樣的方法來訪問,所以從0開始。

看看下面程式碼,通過getElementsByTagName()獲取節點。

這裡寫圖片描述

innerHTML節點物件的內容。

4.區別

getElementByID,getElementsByName,getElementsByTagName
以人來舉例說明,人有能標識身份的身份證,有姓名,有類別(大人、小孩、老人)等。

  1. ID 是一個人的身份證號碼,是唯一的。所以通過getElementById獲取的是指定的一個人。

  2. Name 是他的名字,可以重複。所以通過getElementsByName獲取名字相同的人集合。

  3. TagName可看似某類,getElementsByTagName獲取相同類的人集合。如獲取小孩這類人,getElementsByTagName(“小孩”)。

把上面的例子轉換到HTML中,如下:

<input type="checkbox" name="hobby" id="hobby1">  音樂

input標籤就像人的類別。

name屬性就像人的姓名。

id屬性就像人的身份證。

方法總結如下:

這裡寫圖片描述

注意:方法區分大小寫

通過下面的例子(6個name=”hobby”的複選項,兩個按鈕)來區分三種方法的不同:

  <input type="checkbox" name="hobby" id="hobby1">  音樂
  <input type="checkbox" name="hobby" id="hobby2">  登山
  <input type="checkbox" name="hobby" id="hobby3">  游泳
  <input type="checkbox" name="hobby" id="hobby4">  閱讀
  <input type="checkbox" name="hobby" id="hobby5">  打球
  <input type="checkbox" name="hobby" id="hobby6">  跑步 
  <input type="button" value = "全選" id="button1">
  <input type="button" value = "全不選" id="button1">
  1. document.getElementsByTagName(“input”),結果為獲取所有標籤為input的元素,共8個。

  2. document.getElementsByName(“hobby”),結果為獲取屬性name=”hobby”的元素,共6個。

  3. document.getElementById(“hobby6”),結果為獲取屬性id=”hobby6”的元素,只有一個,”跑步”這個複選項。

5.getAttribute()方法

通過元素節點的屬性名稱獲取屬性的值。

語法:

elementNode.getAttribute(name)
說明:

  1. elementNode:使用getElementById()、getElementsByTagName()等方法,獲取到的元素節點。

  2. name:要想查詢的元素節點的屬性名字

看看下面的程式碼,獲取h1標籤的屬性值:

這裡寫圖片描述

執行結果:

h1標籤的ID :alink
h1標籤的title :getAttribute()獲取標籤的屬值

6.setAttribute()方法

setAttribute() 方法增加一個指定名稱和值的新屬性,或者把一個現有的屬性設定為指定的值。

語法:

elementNode.setAttribute(name,value)
說明:

1.name: 要設定的屬性名。

2.value: 要設定的屬性值。

注意:

1.把指定的屬性設定為指定的值。如果不存在具有指定名稱的屬性,該方法將建立一個新屬性。

2.類似於getAttribute()方法,setAttribute()方法只能通過元素節點物件呼叫的函式。

7.節點屬性

在文件物件模型 (DOM) 中,每個節點都是一個物件。DOM 節點有三個重要的屬性 :

  1. nodeName : 節點的名稱

  2. nodeValue :節點的值

  3. nodeType :節點的型別

一、nodeName 屬性: 節點的名稱,是隻讀的。

  1. 元素節點的 nodeName 與標籤名相同
  2. 屬性節點的 nodeName 是屬性的名稱
  3. 文字節點的 nodeName 永遠是 #text
  4. 文件節點的 nodeName 永遠是 #document

二、nodeValue 屬性:節點的值

  1. 元素節點的 nodeValue 是 undefined 或 null
  2. 文字節點的 nodeValue 是文字自身
  3. 屬性節點的 nodeValue 是屬性的值

三、nodeType 屬性: 節點的型別,是隻讀的。以下常用的幾種結點型別:

元素型別 節點型別
元素 1
屬性 2
文字 3
註釋 8
文件 9

8.訪問子節點childNodes

訪問選定元素節點下的所有子節點的列表,返回的值可以看作是一個陣列,他具有length屬性。
語法:

elementNode.childNodes
注意:

如果選定的節點沒有子節點,則該屬性返回不包含節點的 NodeList。

我們來看看下面的程式碼:

這裡寫圖片描述

執行結果:

IE:

UL子節點個數:3
節點型別:1
其它瀏覽器:

UL子節點個數:7
節點型別:3
注意:

  1. IE全系列、firefox、chrome、opera、safari相容問題

  2. 節點之間的空白符,在firefox、chrome、opera、safari瀏覽器是文字節點,所以IE是3,其它瀏覽器是7,如下圖所示:

這裡寫圖片描述

如果把程式碼改成這樣:

<ul><li>javascript</li><li>jQuery</li><li>PHP</li></ul>

執行結果:(IE和其它瀏覽器結果是一樣的)

UL子節點個數:3
節點型別:1

9.訪問子節點的第一和最後項

一、firstChild 屬性返回‘childNodes’陣列的第一個子節點。如果選定的節點沒有子節點,則該屬性返回 NULL。

語法:

node.firstChild
說明:與elementNode.childNodes[0]是同樣的效果。

二、 lastChild 屬性返回‘childNodes’陣列的最後一個子節點。如果選定的節點沒有子節點,則該屬性返回 NULL。

語法:

node.lastChild
說明:與elementNode.childNodes[elementNode.childNodes.length-1]是同樣的效果。

注意: 上一節中,我們知道Internet Explorer 會忽略節點之間生成的空白文字節點,而其它瀏覽器不會。我們可以通過檢測節點型別,過濾子節點。 (以後章節講解)

10.訪問父節點parentNode

獲取指定節點的父節點

語法:

elementNode.parentNode
注意:父節點只能有一個。

看看下面的例子,獲取 P 節點的父節點,程式碼如下:

<div id="text">
  <p id="con"> parentNode 獲取指點節點的父節點</p>
</div> 
<script type="text/javascript">
  var mynode= document.getElementById("con");
  document.write(mynode.parentNode.nodeName);
</script>

執行結果:

parentNode 獲取指點節點的父節點
DIV

訪問祖節點:

elementNode.parentNode.parentNode

看看下面的程式碼:

<div id="text">  
  <p>
    parentNode      
    <span id="con"> 獲取指點節點的父節點</span>
  </p>
</div> 
<script type="text/javascript">
  var mynode= document.getElementById("con");
  document.write(mynode.parentNode.parentNode.nodeName);
</script>

執行結果:

parentNode獲取指點節點的父節點
DIV
注意: 瀏覽器相容問題,chrome、firefox等瀏覽器標籤之間的空白也算是一個文字節點。

11.訪問兄弟節點

  1. nextSibling 屬性可返回某個節點之後緊跟的節點(處於同一樹層級中)。

語法:

nodeObject.nextSibling
說明:如果無此節點,則該屬性返回 null。

  1. previousSibling 屬性可返回某個節點之前緊跟的節點(處於同一樹層級中)。

語法:

nodeObject.previousSibling
說明:如果無此節點,則該屬性返回 null。

注意: 兩個屬性獲取的是節點。Internet Explorer 會忽略節點間生成的空白文字節點(例如,換行符號),而其它瀏覽器不會忽略。

解決問題方法:

判斷節點nodeType是否為1, 如是為元素節點,跳過。

這裡寫圖片描述

執行結果:

LI = javascript
nextsibling: LI = jquery

12.插入節點appendChild()

在指定節點的最後一個子節點列表之後新增一個新的子節點。

語法:

appendChild(newnode)
引數:

newnode:指定追加的節點。

我們來看看,div標籤內建立一個新的 P 標籤,程式碼如下:

這裡寫圖片描述

執行結果:

HTML
JavaScript
This is a new p

13. 插入節點insertBefore()

insertBefore() 方法可在已有的子節點前插入一個新的子節點。

語法:

insertBefore(newnode,node);

引數:

newnode: 要插入的新節點。

node: 指定此節點前插入節點。

我們在來看看下面程式碼,在指定節點前插入節點。

這裡寫圖片描述

執行結果:

This is a new p
JavaScript
HTML
注意: otest.insertBefore(newnode,node); 也可以改為: otest.insertBefore(newnode,otest.childNodes[0]);

14.刪除節點removeChild()

removeChild() 方法從子節點列表中刪除某個節點。如刪除成功,此方法可返回被刪除的節點,如失敗,則返回 NULL。

語法:

nodeObject.removeChild(node)
引數:

node :必需,指定需要刪除的節點。

我們來看看下面程式碼,刪除子點。

這裡寫圖片描述

執行結果:

HTML
刪除節點的內容: javascript

注意: 把刪除的子節點賦值給 x,這個子節點不在DOM樹中,但是還存在記憶體中,可通過 x 操作。

如果要完全刪除物件,給 x 賦 null 值,程式碼如下:

這裡寫圖片描述

15.替換元素節點replaceChild()

replaceChild 實現子節點(物件)的替換。返回被替換物件的引用。

語法:

node.replaceChild (newnode,oldnew )
引數:

newnode : 必需,用於替換 oldnew 的物件。
oldnew : 必需,被 newnode 替換的物件。

我們來看看下面的程式碼:

這裡寫圖片描述

效果: 將文件中的 Java 改為 JavaScript。

注意:

  1. 當 oldnode 被替換時,所有與之相關的屬性內容都將被移除。

  2. newnode 必須先被建立。

        <div><b id="oldnode">JavaScript</b>是一個很常用的技術,為網頁新增動態效果。</div>
        <a href="javascript:replaceMessage()"> 將加粗改為斜體</a>

        <script type="text/javascript">
        function replaceMessage(){
        var a1=document.createElement("i");  
        var a2=document.createTextNode("文字內容哦!"); 
        a1.appendChild(a2);//將a2文字資訊插入到a1標籤中
        var a3=document.getElementById("oldnode");
        a3.parentNode.replaceChild(a1,a3);
        }

<b>b標籤內容是為粗體bold</b>
<i>i標籤內容為斜體italic</i>,
以上程式碼的結果就是b標籤的值付給i然後就呈現斜體效果了

16.建立元素節點createElement

createElement()方法可建立元素節點。此方法可返回一個 Element 物件。

語法:

document.createElement(tagName)
引數:

tagName:字串值,這個字串用來指明建立元素的型別。

注意:要與appendChild() 或 insertBefore()方法聯合使用,將元素顯示在頁面中。

我們來建立一個按鈕,程式碼如下:

<script type="text/javascript">
   var body = document.body; 
   var input = document.createElement("input");  
   input.type = "button";  
   input.value = "建立一個按鈕";  
   body.appendChild(input);  
 </script>  

效果:在HTML文件中,建立一個按鈕。

我們也可以使用setAttribute來設定屬性,程式碼如下:

<script type="text/javascript">  
   var body= document.body;             
   var btn = document.createElement("input");  
   btn.setAttribute("type", "text");  
   btn.setAttribute("name", "q");  
   btn.setAttribute("value", "使用setAttribute");  
   btn.setAttribute("onclick", "javascript:alert('This is a text!');");       
   body.appendChild(btn);  
</script>  

效果:在HTML文件中,建立一個文字框,使用setAttribute設定屬性值。 當點選這個文字框時,會彈出對話方塊“This is a text!”。

17.建立文字節點createTextNode

createTextNode() 方法建立新的文字節點,返回新建立的 Text 節點。

語法:

document.createTextNode(data)
引數:

data : 字串值,可規定此節點的文字。

我們來建立一個<div>元素並向其中新增一條訊息,程式碼如下:

這裡寫圖片描述

執行結果:

這裡寫圖片描述

18.瀏覽器視窗可視區域大小

獲得瀏覽器視窗的尺寸(瀏覽器的視口,不包括工具欄和滾動條)的方法:

一、對於IE9+、Chrome、Firefox、Opera 以及 Safari:

• window.innerHeight - 瀏覽器視窗的內部高度

• window.innerWidth - 瀏覽器視窗的內部寬度

二、對於 Internet Explorer 8、7、6、5:

• document.documentElement.clientHeight表示HTML文件所在視窗的當前高度。

• document.documentElement.clientWidth表示HTML文件所在視窗的當前寬度。

或者

Document物件的body屬性對應HTML文件的<body>標籤

• document.body.clientHeight

• document.body.clientWidth

在不同瀏覽器都實用的 JavaScript 方案:

var w= document.documentElement.clientWidth
      || document.body.clientWidth;
var h= document.documentElement.clientHeight
      || document.body.clientHeight;

19.網頁尺寸scrollHeight

scrollHeight和scrollWidth,獲取網頁內容高度和寬度。

一、針對IE、Opera:

scrollHeight 是網頁內容實際高度,可以小於 clientHeight。

二、針對NS、FF:

scrollHeight 是網頁內容高度,不過最小值是 clientHeight。也就是說網頁內容實際高度小於 clientHeight 時,scrollHeight 返回 clientHeight 。

三、瀏覽器相容性

var w=document.documentElement.scrollWidth
|| document.body.scrollWidth;
var h=document.documentElement.scrollHeight
|| document.body.scrollHeight;
注意:區分大小寫

scrollHeight和scrollWidth還可獲取Dom元素中內容實際佔用的高度和寬度。

20.網頁尺寸offsetHeight

offsetHeight和offsetWidth,獲取網頁內容高度和寬度(包括滾動條等邊線,會隨視窗的顯示大小改變)。

一、值

offsetHeight = clientHeight + 滾動條 + 邊框。

二、瀏覽器相容性

var w= document.documentElement.offsetWidth
    || document.body.offsetWidth;
var h= document.documentElement.offsetHeight
    || document.body.offsetHeight;

21.網頁捲去的距離與偏移量

我們先來看看下面的圖:

這裡寫圖片描述

scrollLeft:設定或獲取位於給定物件左邊界與視窗中目前可見內容的最左端之間的距離 ,即左邊灰色的內容。

scrollTop:設定或獲取位於物件最頂端與視窗中可見內容的最頂端之間的距離 ,即上邊灰色的內容。

offsetLeft:獲取指定物件相對於版面或由 offsetParent 屬性指定的父座標的計算左側位置 。

offsetTop:獲取指定物件相對於版面或由 offsetParent 屬性指定的父座標的計算頂端位置 。

注意:

  1. 區分大小寫

  2. offsetParent:佈局中設定postion屬性(Relative、Absolute、fixed)的父容器,從最近的父節點開始,一層層向上找,直到HTML的body。

22.程式設計練習

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>實踐題 - 選項卡</title>
    <style type="text/css">
     /* CSS樣式製作 */  
     *{margin:0;padding:0;font:normal 12px "微軟雅黑";color:#000000;}
     ul{list-style-type: none;}
     a{text-decoration: none;}

     #tab-list{width: 275px;height:190px;margin: 20px auto;}

     #ul1{border-bottom: 2px solid #8B4513;height: 32px;}
     #ul1 li{display: inline-block;width: 60px;line-height: 30px;text-align: center;border: 1px solid #999;border-bottom: none;margin-left: 5px;}
     #ul1 li:hover{cursor: pointer;}
     #ul1 li.active{border-top:2px solid #8B4513;border-bottom:2px solid #FFFFFF;}

     #tab-list div{border: 1px solid #7396B8;border-top: none;}
     #tab-list div li{height: 30px;line-height: 30px;text-indent: 8px;}

     .show{display: block;}.hide{display: none;}
    </style>
    <script type="text/javascript">

    window.onload = function() {
        var oUl1 = document.getElementById("ul1");
        var aLi = oUl1.getElementsByTagName("li");
        var oDiv = document.getElementById("tab-list");
        var aDiv = oDiv.getElementsByTagName("div");
        for(var i = 0; i < aLi.length; i++) {
            aLi[i].index = i;
            aLi[i].onmouseover = function() {
                for(var i = 0; i < aLi.length; i++) {
                    aLi[i].className = "";
                }
                this.className = "active";
                for(var j = 0; j < aDiv.length; j++) {
                    aDiv[j].className = "hide";
                }
                aDiv[this.index].className = "show";
            }        
        }
    }


    </script>

</head>
<body>
<!-- HTML頁面佈局 -->
<div id="tab-list">
    <ul id="ul1">
        <li class="active">房產</li><li>家居</li><li>二手房</li>
    </ul>
    <div>
        <ul>
            <li><a href="javascript:;">275萬購昌平鄰鐵三居 總價20萬買一居</a></li>
            <li><a href="javascript:;">200萬內購五環三居 140萬安家東三環</a></li>
            <li><a href="javascript:;">北京首現零首付樓盤 53萬購東5環50平</a></li>
            <li><a href="javascript:;">京樓盤直降5000 中信府 公園樓王現房</a></li>
        </ul>
    </div>    
    <div class="hide">
        <ul>
            <li><a href="javascript:;">40平出租屋大改造 美少女的混搭小窩</a></li>
            <li><a href="javascript:;">經典清新簡歐愛家 90平老房煥發新生</a></li>
            <li><a href="javascript:;">新中式的酷色溫情 66平撞色活潑家居</a></li>
            <li><a href="javascript:;">瓷磚就像選好老婆 衛生間煙道的設計</a></li>
        </ul>
    </div>    
    <div class="hide">
        <ul>
            <li><a href="javascript:;">通州豪華3居260萬 二環稀缺2居250w甩</a></li>
            <li><a href="javascript:;">西3環通透2居290萬 130萬2居限量搶購</a></li>
            <li><a href="javascript:;">黃城根小學學區僅260萬 121平70萬拋!</a></li>
            <li><a href="javascript:;">獨家別墅280萬 蘇州橋2居優惠價248萬</a></li>
        </ul>
    </div>
</div>


</body>
</html>

這裡我們分析一下最後的程式碼,div標籤是將邏輯相同的部分劃分出來,ul是新聞標籤,如果此時單單有內容部分,而沒有CSS和js部分,將會是內容的每一條左邊都有一個點,而設定了超連結的a標籤,則會顯示藍色,還有下劃線我們都要去掉。兩者分別是ul標籤和a標籤的,所以

ul{list-style-type: none;}
     a{text-decoration: none;}

此時下劃線和預設的小圓點格式就都沒有了,設定一下顏色這樣藍色也就去掉了,我們開始完善css和js程式碼。

*{margin:0;padding:0;font:normal 12px "微軟雅黑";color:#000000;}

通用選擇器,所有標籤設定一個格式,邊界0,填充0,字型微軟雅黑12大小,顏色黑色。
這裡因為我們整個是要在網頁中居中的,定寬元素居中

#tab-list{width: 275px;height:190px;margin: 20px auto;}

tab-list這個id的div代表的就是最大的這個整體,寬度設定為275,高190,邊界上下20px,左右自適應居中。
然後設定頭部,也就是頂部這三個分組。

#ul1{border-bottom: 2px solid #8B4513;height: 32px;}

#ul1 li{display: inline-block;width: 60px;line-height: 30px;text-align: center;border: 1px solid #999;border-bottom: none;margin-left: 5px;}

#ul1 li:hover{cursor: pointer;}

#ul1 li.active{border-top:2px solid #8B4513;border-bottom:2px solid #FFFFFF;}

top、right、bottom、left上 右 下 左,這裡第一條程式碼先給ul1標籤設定了高度32px,然後給它的下邊框設定為2px實線, 顏色#8B4513。
這裡的第二條程式碼,因為後續的分組都是在一行中顯示的,所以將它設定為行內塊元素,直到該行排滿為止,inline-block,寬度為60,對邊框進行了設定。
第三條是偽選擇器,游標指標,應該是當滑鼠在這個元素時指標變成手那個樣子
第四條是對active這個類選擇器進行了上下邊框的設定,後面下邊框顏色設定成了白色,所以我們看到的就是沒有下邊框了。

#tab-list div{border: 1px solid #7396B8;border-top: none;}

#tab-list div li{height: 30px;line-height: 30px;text-indent: 8px;}

     .show{display: block;}.hide{display: none;} 

對後面的三個子標籤div邏輯塊進行了設定,表框1px實現以及顏色,上邊框定義為無
對li標籤,高度30,行高30(關於行高還得多瞭解),首行文字縮排8px
後面兩個.show要在js中體現,.hide就是後兩個元素,直接隱藏。此時css程式碼中就完成了。

window.onload = function() {
        var oUl1 = document.getElementById("ul1");
        var aLi = oUl1.getElementsByTagName("li");
        var oDiv = document.getElementById("tab-list");
        var aDiv = oDiv.getElementsByTagName("div");
        for(var i = 0; i < aLi.length; i++) {
            aLi[i].index = i;
            aLi[i].onmouseover = function() {
                for(var i = 0; i < aLi.length; i++) {
                    aLi[i].className = "";
                }
                this.className = "active";
                for(var j = 0; j < aDiv.length; j++) {
                    aDiv[j].className = "hide";
                }
                aDiv[this.index].className = "show";
            }        
        }
    }

關於這個方法,設定了各種迴圈,具體應該是先得到頂部三個分組的這個元素物件,然後通過它得到一個li標籤的結果集,也就是那三個分組aLi。用程式碼得出後面三個div元素,因為不同條件下要顯示不同的div元素,預設情況下應該是第一個。
設定一個迴圈,滑鼠滑過時觸發一個事項,將該元素的類名設定成active,再迴圈,將對應的div類名設定成hide。全部隱藏又單獨顯示一個。

相關文章