JavaScript(十八):DOM對象

1、 認識DOM

DOM(Document Object Model,文檔對象模型):定義訪問和處理HTML文檔的標準方法。DOMHTML 文檔呈現爲帶有 元素、屬性和文本的樹結構(節點樹)。javascript

先來看看下面代碼:css

<!DOCTYPE HTML>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html;charset=gb2312"/>
		<title>DOM</title>
	</head>
	<body>
		<h2>
			<a href="http://www.imooc.com">javascript DOM</a>
		</h2>
		<p>
			對HTML元素進行操做,可添加、改變或移除CSS樣式等
		</p>
		<ul>
			<li>JavaScript</li>
			<li>DOM</li>
			<li>CSS</li>
		</ul>
	</body>
</html>

HTML 代碼分解爲 DOM 節點層次圖: 輸入圖片說明html

文檔構成:

HTML 文檔能夠說由 節點 構成的集合,DOM 節點有:java

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

  2. 文本節點 :向用戶展現的內容,如<li>...</li>中的JavaScript、DOM、CSS等文本。jquery

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

看下面代碼:數組

<a href="http://www.imooc.com">JavaScript DOM</a>

輸入圖片說明

2、元素節點獲取方式

2.一、經過 ID 獲取元素

學過HTML/CSS樣式,都知道,網頁由標籤將信息組織起來,而標籤的 id 屬性值是惟一的,就像是每人有一個身份證號同樣,只要經過身份證號就能夠找到相對應的人。那麼在網頁中,咱們經過id先找到標籤,而後進行操做。瀏覽器

語法:app

document.getElementById("id")

看看下面代碼:

<!DOCTYPE HTML>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html;charset=gb2312"/>
		<title>獲取元素</title>
		<script type="text/javascript">
		  var mye = document.getElementById("con");//獲取元素存儲在變量mye中
		  document.write(mye);// 輸出變量mye
		</script>
	</head>
	<body>
		<h3>Hello</h3>
		<p id="con">I love JavaScript</p>
	</body>
</html>

結果:null或[object HTMLParagraphElement] 輸入圖片說明

注:獲取的元素是一個對象,如想對元素進行操做,咱們要經過它的屬性或方法。

2.二、 getElementsByName() 方法

返回帶有指定名稱的節點對象的集合。

語法

document.getElementsByName(name)

getElementById() 方法不一樣的是,經過元素的 name 屬性查詢元素,而不是經過id屬性。

注意:

  • 由於文檔中的 name 屬性可能不惟一,全部 getElementsByName() 方法返回的是元素的數組,而不是一個元素。
  • 和數組相似也有 length 屬性,能夠和訪問數組同樣的方法來訪問,從0開始。

看看下面的代碼:

<!DOCTYPE HTML>
<html>
	<head>
		<script type="text/javascript">
		  function getElements(){
		     var x = document.getElementsByName("alink");
			 alert(x.length);
		  }
		</script>
	</head>
	<body>
		<a name="alink" href="#">我是連接一</a>
	    <a name="alink" href="#">我是連接二</a>
	    <a name="alink" href="#">我是連接三</a>
		<br />
		<input type="button" onclick="getElements()" value = "看看幾個連接?" />
	</body>
</html>

運行結果:
輸入圖片說明

2.三、 getElementsByTagName() 方法

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


語法:

document.getElementsByTagName(Tagname)

說明:

  • Tagname 是標籤的名稱,如paimg等標籤名。
  • 和數組相似也有length屬性,能夠和訪問數組同樣的方法來訪問,因此從0開始。

看看下面代碼,經過getElementsByTagName()獲取節點。

<!DOCTYPE HTML>
<html>
	<head>
	    <title>JavaScript</title>
	</head>
	<body>
	    <p id="intro">個人課程</p>
		<ul>
		  <li>JavaScript</li>
		  <li>JQuery</li>
		  <li>HTML</li>
		  <li>JAVA</li>
		  <li>PHP</li>
		</ul>
		<script>
		  // 獲取全部 li 集合
		  var list = document.getElementByTagName('li');
		  // 訪問無序列表:[0]索引
		  li =  list[0];
		  // 獲取 list 的長度
		  document.write(list.length);
		  // 彈出 li 節點對象的內容
		  document.write(li.innerHTML);
		</script>
	</body>
</html>

2.四、上述三種方式的區別

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

  • ID 是一我的的身份證號碼,是惟一的。因此經過getElementById獲取的是指定的一我的。

  • Name 是他的名字,能夠重複。因此經過getElementsByName獲取名字相同的人集合。

  • TagName可看似某類,getElementsByTagName獲取相同類的人集合。如獲取小孩這類人,getElementsByTagName("小孩")。

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

<input type="checkbox" name="hobby" id="hobby1">  音樂
  • input標籤就像人的類別。

  • name屬性就像人的姓名。

  • id屬性就像人的身份證。


方法總結以下:

方法 說明 結果集
getElementById 經過指定 id 得到元素 1個
getElementsByName 經過元素名稱 name 屬性得到元素 1組
getElementsByTagName 經過標籤名稱得到元素 1組

**注意:**方法區分大小寫


經過下面的例子(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">
  • document.getElementsByTagName("input"),結果爲獲取全部標籤爲input的元素,共8個。

  • document.getElementsByName("hobby"),結果爲獲取屬性name="hobby"的元素,共6個。

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

3、節點屬性

3.一、屬性詳解

在文檔對象模型 (DOM) 中,每一個節點都是一個對象。

屬性 描述
nodeName 節點的名稱:返回一個字符串,其內容是給定節點的名字
nodeType 節點的類型: 返回一個整數,這個數值表明給定節點的類型
nodeValue 節點的值: 返回給定節點的當前值

3.1.一、 nodeName 屬性

節點的名稱,是隻讀的。

說明

  • 元素節點的 nodeName 與標籤名相同
  • 屬性節點的 nodeName 是屬性的名稱
  • 文本節點的 nodeName 永遠是 #text
  • 文檔節點的 nodeName 永遠是 #document

3.1.二、 nodeValue 屬性

節點的值

說明

  • 元素節點的 nodeValueundefinednull
  • 文本節點的 nodeValue 是文本自身
  • 屬性節點的 nodeValue 是屬性的值

3.1.三、nodeType 屬性

節點的類型,是隻讀的。

如下經常使用的幾種結點類型:

元素類型 節點類型
元素 1
屬性 2
文本 3
註釋 8
文檔 9

3.二、屬性值獲取:getAttribute() 方法

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


語法

elementNode.getAttribute(name)

說明:

  • elementNode:使用 getElementById()getElementsByTagName()等方法,獲取到的元素節點。
  • name:要想查詢的元素節點的屬性名字

舉例: 獲取 h1 標籤的屬性值:

<!DOCTYPE HTML>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html;charset=gb2312"/>
		<title>getAttribute()</title>
	</head>
	<body>
		<h1 id="alink" title="getAttribute()獲取標籤的屬性值" onclick="hattr()">點擊我,獲取標籤的屬性值</h1>
	
		<script type="text/javascript">
		  function hattr(){
		     var anode = document.getElementById("alink");
			 var attr1 = anode.getAttribute("id");
			 var attr2 = anode.getAttribute("title");
			 document.write("h1標籤的ID:" + attr1 + "<br>");
			 document.write("h1標籤的title:" + attr2 );
		  }
		</script>
	</body>
</html>

運行結果:

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

3.三、 屬性值設置: setAttribute() 方法

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


語法

elementNode.setAttribute(name,value)

說明

  • name: 要設置的屬性名。
  • value: 要設置的屬性值。

注意

  • 把指定的屬性設置爲指定的值。若是不存在具備指定名稱的屬性,該方法將建立一個新屬性。

  • 相似於getAttribute()方法,setAttribute()方法只能經過元素節點對象調用的函數。

4、 遍歷節點樹

屬性 描述
childNodes 返回一個數組,這個數組由給定元素節點的子節點構成
firstChild 返回第一個子節點
lastChild 返回最後一個子節點
parentNode 返回一個給定節點的父節點
nextSibling 返回給定節點的下一個兄弟節點
previousSibling 返回給定節點的上一個兄弟節點

以層次圖中 ul 爲例,它的父級節點 body,它的子節點3li,它的兄弟結點h2P

4.一、childNodes

訪問給定 元素節點 下 的全部子節點的列表。
返回的 值能夠看做是一個數組,具備 length 屬性。


語法

elementNode.childNodes

注意:若是選定的節點沒有子節點,則該屬性返回不包含節點的 NodeList


舉例

<!DOCTYPE HTML>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
		<title>無標題文檔</title>
	</head>
	<body>
		<ul>
			<li>JavaScript</li>
			<li>jQuery</li>
			<li>PHP</li>
		</ul>
		<script type="text/javascript">
		  var x = document.getElementByTagName("ul")[0].childNodes;
		  document.write("UL子節點個數:" + x.length + "<br />");
		  document.write("節點類型:" + x[0].nodeType);
		</script>
	</body>
</html>

運行結果: IE:

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

其它瀏覽器:

UL子節點個數:7
   節點類型:3

出現上述結果的緣由以下:

  • IE全系列、firefox、chrome、opera、safari兼容問題
  • 節點之間的空白符,在firefox、chrome、opera、safari瀏覽器是文本節點,在 IE中會忽略掉。以下:
<ul> 空白節點
     <li>javascript</li> 空白節點
	 <li>jQuery</li>  空白節點
	 <li>PHP</li>  空白節點
  </ul>

若是把代碼改爲這樣:

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

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

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

4.二、 firstChild and lastChild:訪問子節點的第一和最後項

(1) firstChild 屬性

返回 childNodes 數組的第一個子節點。
若是選定的節點沒有子節點,則該屬性返回 NULL。


語法:

node.firstChild

說明
      與 elementNode.childNodes[0] 是一樣的效果。

(2)、 lastChild 屬性

返回 childNodes 數組的最後一個子節點。
若是選定的節點沒有子節點,則該屬性返回 NULL。

語法:

node.lastChild

說明
      與 elementNode.childNodes[elementNode.childNodes.length-1] 是一樣的效果。

注意: 上一節中,咱們知道 Internet Explorer 會忽略節點之間生成的空白文本節點,而其它瀏覽器不會。咱們能夠經過檢測節點類型,過濾子節點。 (之後章節講解)

4.三、 訪問父節點:parentNode

獲取指定節點的父節點。

注意:
      瀏覽器兼容問題,chrome、firefox等瀏覽器標籤之間的空白也算是一個文本節點。


語法:

elementNode.parentNode

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


舉例:
(1)、獲取 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

(2)、 訪問祖節點:

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

4.四、 訪問兄弟節點:nextSibling、previousSibling

(1)、nextSibling 屬性

可返回某個節點以後緊跟的節點(處於同一樹層級中)。


語法:

nodeObject.nextSibling

說明: 若是無此節點,則該屬性返回 null。

(2)、 previousSibling 屬性

可返回某個節點以前緊跟的節點(處於同一樹層級中)。


語法:

nodeObject.previousSibling

說明:若是無此節點,則該屬性返回 null。


(3)、舉例

注意:

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

如何獲取正確的兄弟節點,解決方法:
      遍歷兄弟節點時判斷節點nodeType是否爲1(元素節點),不是繼續遍歷直到得到的是 元素節點 爲止。 以下代碼:

<!DOCTYPE HTML>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
		<title>nextsibling</title>
	</head>
	<body>
		<ul id="u1">
			<li id="a">javascript</li>
			<li id="b">jquery</li>
			<li id="c">html</li>
		</ul>
		<ul id="u2">
			<li id="d">javascript</li>
			<li id="e">jquery</li>
			<li id="f">html</li>
		</ul>
		<script type="text/javascript">
		  function get_nextSibling(n){
		    var x=n.nextSibling;
			while(x.nextSibling != 1){
			  x = x.nextSibling;
			}
			
			retrun x;
		  }
		  var x = document.getElementByTagName("li")[0];
		  document.write(x.nodeName);
		  document.write("=");
		  document.write(x.innerHTML);
		  
		  var y = get_nextSibling(x);
		  document.write("nextSibling:" + y.nodeName);
		  document.write("=");
		  document.write(y.innerHTML); 
		</script>
	</body>
</html>

運行結果:

LI = javascript
nextsibling: LI = jquery

5、修改節點樹

方法 描述
createElement(element) 建立一個新的元素節點
createTextNode() 建立一個包含給定文本的新文本節點
appendChild() 指定節點的最後一個子節點列表以後添加一個新的子節點
insertBefore() 將一個給定節點插入到一個給定元素節點的給定子節點前面
removeChild() 從一個給定元素中刪除一個子節點
replaceChild() 把一個給定父元素裏的一個子節點替換爲另一個節點

注意: 前兩個是 document 方法。

5.一、 建立節點

(1)建立 元素 節點: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!」。

(2)建立文本節點:createTextNode

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


語法:

document.createTextNode(data)

參數: data : 字符串值,可規定此節點的文本。


實例: 咱們來建立一個 <div> 元素並向其中添加一條消息,代碼以下:

<!DOCTYPE HTML>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
		<title>無標題</title>
		<style type="text/css">
		  .message{
		     width:200px;
			 height:100px;
			 background-color:#CCC;
		  }
		</style>
	</head>
	<body>
		<script type="text/javascript">
		  var element = document.createElement("div");
		  element.className = "message";
		  
		  var textNode = document.createTextNode("Hello world!");
		  element.appendChild(textNode);
		  document.body.appendChild(element);
		</script>
	</body>
</html>

運行結果:
輸入圖片說明

5.二、 插入節點

(1) appendChild()

在指定節點的最後一個子節點列表以後添加一個新的子節點。


語法

appendChild(newnode)

參數:

  • newnode:指定追加的節點。

實例

<div id="test"><p id="x1">HTML</p><p>JavaScript</p></div>
	    <script type="text/javascript">
		    var otest = document.getElementById("test");
			var newnode = document.createElement("p");
			newnode.innerHEML = "This is a new p";
			// appendChild方法添加節點
			otest.appendChild(newnode);
		</script>

運行結果:

HTML
JavaScript
This is a new p

(2) insertBefore()

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


語法

insertBefore(newnode,node);

參數:

  • newnode: 要插入的新節點。
  • node: 指定此節點前插入節點。

實例

<!DOCTYPE HTML>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
		<title>無標題</title>
	</head>
	<body>
	    <div id="div1"><p id="x1">JavaScript</p><p>HTML</p></div>
	    <script type="text/javascript">
		    var otest = document.getElementById("div1");
			var node = document.getElementById("x1");
			var newnode = document.createElement("p");
			newnode.innerHEML = "This is a new p";
			otest.insertBefore(newnode,node);
		</script>
	</body>
</html>

運行結果:

This is a new p
JavaScript
HTML

注意
otest.insertBefore(newnode,node);
也能夠改成:
otest.insertBefore(newnode,otest.childNodes[0]);

5.三、 刪除節點:removeChild()

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


語法:

nodeObject.removeChild(node)

參數:

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

實例

<!DOCTYPE HTML>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
		<title>無標題</title>
	</head>
	<body>
	    <div id="div1"><h1>HTML</h1><h2>javascript</h2></div>
	    <script type="text/javascript">
		    var otest = document.getElementById("div1");
			var x = otest.removeChild(otest.childNodes[1]);
			document.write("刪除節點的內容:" + x.innerHTML);
		</script>
	</body>
</html>

運行結果:

HTML
刪除節點的內容: javascript

注意:

  • 把刪除的子節點賦值給 x,這個子節點不在 DOM 樹中,可是還存在內存中,可經過 x 操做。

  • 若是要徹底刪除對象,給 x 賦 null 值,代碼以下:

var otest = document.getElementById("div1");
   var x = otest.removeChild(otest.childNodes[1]);
   x=null;

5.四、 替換元素節點:replaceChild()

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


語法:

node.replaceChild (newnode,oldnew )

參數:

  • newnode : 必需,用於替換 oldnew 的對象。
  • oldnew : 必需,被 newnode 替換的對象。

舉例:

<!DOCTYPE HTML>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
		<title>無標題</title>
	</head>
	<body>
	<script type="text/javascript">
		  function replaceMessage(){
		    var newnode=document.createElement("p");
			var newnodeText = document.createTextNode("JavaScript");
			
			newnode.appendChild(newnodeText);
			
			var oldNode = document.getElementById("oldnode");
			oldnode.parentNode.replaceChild(newnode,oldnode);
		  }
		</script>
		<h1 id="oldnode">Java<h1>
		<a href="javascript:replaceMessage()">"Java" 替換 "JavaScript"</a>
		
	</body>
</html>

**效果 **: 將 文檔中的 Java 改成 JavaScript

注意:

  • 當 oldnode 被替換時,全部與之相關的屬性內容都將被移除。
  • newnode 必須先被創建。
相關文章
相關標籤/搜索