JavaScript之DOM对象

DOM(文档对象模型)


DOM可以将任何HTML或XML文档映射成一个多层节点的树形结构。节点有不同的类型,每种类型分别表示不同的信息或标记。每个节点都有各自的特点、数据和方法,也与其它的节点存在某种关系。节点之间构成了层次,页面中的所有节点构成了以某个特定节点为根节点的树形结构。

简单点说,就是DOM将HTML文档映射为带有属性、元素和文本的树形结构。

以下面的HTML为例:

<!doctype html>
<html lang="zh">
  <head>
    <meta charset="utf-8">
    <title>节点类型</tilte>
  </head>
  <body>
    <h2>JavaScript DOM</h2>
    <p class="p1">hello JavaScript!!</p>
    
    <ul>
        <li>JavaScript</li>
        <li>BOM</li>
        <li>DOM</li>
    </ul>

  <script>

  </script>
  </body>
</html>



DOM将其映射为树形结构的形式为:



图中,DOM将每个元素映射为一个节点,每个节点都有自己的属性、数据和方法,节点与节点之间有着层次关系,正是这些层次关系构成了树形结构。

以上的节点有:

1、元素节点,如:<html>、<p>、<body>等都属于元素节点。

2、属性节点,如:p元素的class属性。

3、文本节点,如:<li>元素中的JavaScript、BOM、DOM等文本均属于文本节点。


在页面中<html>元素被称为文档元素一个页面也只有一个文档元素即<html>元素文档元素包含了所有的文档节点每个标记通过节点来表示,HTML元素通过元素节点表示 ,特性通过特性节点表示,注释通过注释节点表示,文档类型通过文档类型节点表示。



Document类型

JavaScript通过Document类型表示文档。在浏览器中,document对象是HTMLDocument(继承了Document类型)的一个实例,表示整个页面,可以取得与页面有关的信息、操作页面以及底层结构。而且,document是window对象的一个属性,因为可以作为全局对象来表示。Document节点有以下特性:
  • nodeType的值为9
  • nodeName的值为#document
  • nodeValue的值为null
  • parentNode的值为null
  • 它的子节点有可能是:DocumentType(也就是!doctype html  最多一个)、Element(也就是<html>文档元素 最多一个)。

访问子节点的快捷方式

documentElement
该属性始终指向HTML页面中的<html>元素,取得对<html>的引用。也可以通过document.childNodes属性访问文档元素。

var html = document.documentElement; //取得对<html>的引用
console.log(html); //<htmll>...</html>
//Document节点的子节点(DocumentType  Element)
console.log(document.childNodes[0]); //<!DOCTYPE html>
console.log(document.childNodes[1]); //<htmll>...</html>
console.log(document.childNodes[2]); //undefined
在一个文档中,<!doctype html>和<html>是Document节点(documentElment 文档节点)的子节点。

document.body属性
该属性是对<body>元素的引用,通过这个属性可以访问<body>下的所有子节点。如:
var body = document.body; //取得对<html>的引用
console.log(body); //<htmll>...</html>
//body节点的子节点,是body下的所有元素节点
console.log(body.childNodes[0]); //#text 文本节点
console.log(body.childNodes[1]); // <p></p>
console.log(body.childNodes[2]); // #text
console.log(body.childNodes[3]); // <script>...</script>

DocumentType
var doctype = document.doctype;
console.log(doctype); //<!DOCTYPE html>

该属性是对<!DOCTYPE html>的引用,表示文档类型。


文档信息

对文档信息的访问。

  • document.title,表示对文档标题的访问
  • document.URL,表示对文档的URL的访问
  • document.charset,表示对文档字符编码形式的访问

特殊集合

  • document.anchors,返回包含所有带有name属性的<a>元素
  • document.links,返回包含所有带有href属性的<a>元素
  • document.images,返回文档中所有的<img>元素
  • document.forms,返回文档中所有的<form>元素

文档的写入方法

  • document.write(),表示写入要输出的文本,并输出到文档中。此方法会覆盖原内容。
  • document.writeln(),与以上方法相同,不过这个方法会在末尾添加一个"/n"换行符。
  • document.open(),打开网页的输出流。
  • document.close(),关闭网页的输出流。

查找元素

通过什么样的方式来查找页面中的元素,常见的是通过ID、元素标签名、元素的类名、元素的name属性查找。

getElementById()

该属性通过ID来获取元素。通过获取元素,可以对其进行赋值、添加样式、隐藏等操作。

注意:因为ID是唯一的,所以查找到的元素也是唯一的,返回的是一个元素。

<body>

  <h2 id="con">I love JavaScript!</h2>
  <p id="p2">hello JavaScript!!</p>

<script>
  
    var con = document.getElementById("con"); //通过ID获取元素
    con.style.color = "red"; //将文字颜色设置高红色
    con.style.backgroundColor = "#ccc"; //将文字背景色设置为灰色
  
</script>
</body>


getElementsByName()

通过name属性获取元素,返回带有指定名称的元素节点的集合

注:name属性不是唯一的,可能有多个元素有共同的name属性名,所以可能获取的元素有多个,可以看作是一个数组。有length属性可以进行访问。

<body>
  <input name="myt" type="text" value="1">
  <input name="myt" type="text" value="2">
  <input name="myt" type="text" value="3">
  <input name="myt" type="text" value="4">
  <input name="myt" type="text" value="5">
  <input name="myt" type="text" value="6">

<script>
  
    var con = document.getElementsByName("myt"); //通过name获取元素,元素可以有多

个。
    console.log(con.length); //6 表示有6个name为myt的元素
  
</script>

返回的顺序是它们在文档中的顺序。


getElementsByTagName()

通过标签名(元素名称)获取元素。返回带有指定标签名的节点对象的集合,返回的顺序是它们在文档中的顺序。可以通过length属性访问。

注:该方法返回的看作是一个数组。

<body>
  <input name="myt" type="text" value="1">
  <input name="myt" type="text" value="2">
  <input name="myt" type="text" value="3">
  <input name="myt" type="text" value="4">
  <input name="myt" type="text" value="5">
  <input name="myt" type="text" value="6">

<script>
  
    var con = document.getElementsByTagName("input"); //通过标签名input获取节点对象,对象可以有多个。
    console.log(con.length); //6 表示有6个标签名为input的节点对象。
  
</script>


getElementsByClaseName()

通过元素的类名来查找元素,返回的是一个nodeList类型,类似数组一样,可以通过argument、length属性访问。


Element类型

该类型表示HTML元素节点的访问,可以访问元素的标签名、子节点、属性。它的特点:

  • nodeType的值为1
  • nodeName的值为它的标签名及元素名
  • nodeValue的值为null
  • parentNode是Document或Element(其它元素节点)
  • 它的子节点可能是:Element、Text。

访问元素节点的方式

可以使用nodeName、tagName属性来访问元素节点。首先通过查找元素的方式获取元素节点,再用这两个属性得到其标签名。
var p1 = document.getElementById("p1");
console.log(p1); //<p>...</p>
console.log(p1.nodeName); //p
console.log(p1.tagName);  //p


取得属性(特性)

getAttribute()

通过 元素节点属性名 获取 属性的值

格式:elementNode.getAttribute("属性名");

<body>
  <ul>
    <li title="t1">第一个li</li>
    <li>第二个li</li>
    <li title="t3">第三个li</li>
    <li title="t4">第四个li</li>
</ul>

<script>
  
    var con = document.getElementsByTagName("li"); //通过标签名获取节点对象。
      
    for (var i = 0; i < con.length; i++) {
        var text = con[i].getAttribute("title"); //通过元素节点的属性名称获取属性的值。
		  
        if (text != null) {
            console.log(text); //t1 t3 t4
        }
    }	
</script>
</body>


设置属性(特性)

setAttribute()

该方法增加一个 指定名称和值新属性,或把现有的属性设定为 指定的值。

格式:elementNode.setAttribute("属性名", "属性值")

注:把指定的属性设定为指定的值,如果不存在具有指定的属性,则该方法创建一个。

<body>
    
  <li id="l" title="li1">1</li>
  <p id="2"></p>

 <script>
  
    var con = document.getElementById("l");
    var cos = document.getElementById("2");  
        
    con.setAttribute("title", "WEB前端技术"); //把现有的属性设定为指定的值
    cos.setAttribute("name", "pad"); //对于没有的属性,则新创建。
    
    console.log(con.getAttribute("title")); //WEB前端技术
    console.log(cos.getAttribute("name")); //pad
	
</script>
</body>

对于li节点对象,将其现有的属性title的值"li1"设定为指定的值"WEB前端技术"。而对于p节点对象,该节点原本没有属性name,通过setAttribute()方法,给其新创建了一个属性name并赋值"pad"。


removeAttribute()

该方法删除元素的属性。

<p id="p1" name="p"></p>

<script>
  var p1 = document.getElementById("p1");
  p1.removeAttribute("name"); //删除p元素的name属性
  var att = p1.getAttribute("name");
  console.log(att); // null
    
</script>


创建新元素节点(document.createElement)

格式:document.createElement("标签名");

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
	<title>javascript</title>
  </head>
  <body>
    
    <ul id="u1"><li id="a">JavaScript</li><li id="b">jquery</li><li id="c">html</li>
	</ul>
	
  
  <script>
      /* 在此处书写javascript代码 */
	  var con = document.getElementById("u1"); //找到指定节点。
	  
	  //找到JavaScript所在
	  var node = con.firstChild; //找到ul的第一个子节点
	  
	  //先创建一个新节点元素
	  var newNode = document.createElement("li");
	  newNode.innerHTML = "css";
	  
	  con.replaceChild(newNode, node); //用新创建的节点去替换JavaScript所在的节点。
	  
  </script>
  </body>
</html>

先创建一个节点元素,再用其将JavaScript所在节点替换掉。




Node类型

JavaScript中的所有节点类型都继承于Node类型,因为它们共享想再的基本属性和方法。Node类型有12种。

节点属性

在DOM中,每个节点都是一个对象,节点有三个重要的属性:

1、nodeName:节点名称

2、nodeValue:节点的值

3、nodeType:节点的类型


nodeName:节点名称,只是可读的。

1、元素节点的nodeName与标签名相同

2、属性节点的nodeName与属性名相同

3、文本节点的nodeName永远是#text

4、文档节点的nodeName永远是#document


nodeValu:节点的值

1、元素节点的nodeValue是undefined或null

2、文本节点的nodeValue是文本自身

3、属性节点的nodeValue是属性的值


nodeType:节点的类型

1、元素节点的nodeType是 1

2、属性节点的nodeType是 2

3、文本节点的nodeType是 3

4、注释节点的nodeType是 8

5、文档节点的nodeType是 9


<body>
  <ul>
    <li>javascript</li>
    <li>HTML/CSS</li>
    <li>jQuery</li>     
  </ul>
  
<script type="text/javascript">
    var con = document.getElementsByTagName("li");
	
    for(var i=0; i<con.length; i++){
        var nodeName = con[i].nodeName;
        var nodeValue = con[i].nodeValue;
        var nodeType = con[i].nodeType;
        
        document.write(nodeName + "<br>");
        document.write(nodeValue + "<br>");
        document.write(nodeType + "<br>");
    } 
</script>
</body>

li元素是元素节点,所有元素节点的nodeName是标签名li,元素节点的nodeValue是undefined或null,元素节点的nodeType是 1。



节点关系

childNodes

访问选定元素节点下的所有子节点的 列表,返回的值可以看作是一个数组,具有length属性。

格式:elementNode.childNodes

注意:元素节点之间的空白符 被默认为 文本节点

<body>
  <div>

    javascript  
    <p>javascript</p>
    <div>jQuery</div>
    <h5>PHP</h5>

  </div>

<script>
    
    var arr = document.getElementsByTagName("div")[0].childNodes; //获取第一个div下的所有子节点。
     
    //遍历所有子节点
    for (var i = 0; i < arr.length; i++) {
        document.write("节点的名称:" + arr[i].nodeName + "<br>");
        document.write("节点的值:" + arr[i].nodeValue + "<br>");
        document.write("节点的类型:" + arr[i].nodeType + "<br>");
    }

    console.log(arr.length); //对于除IE外,其它主浏览器显示的子节点为7个
 
</script>
</body>


IE下显示的子节点只有3个,而其它主浏览器显示的子节点有7个,因为其它主浏览器把元素节点之间的空白默认为文本节点。

也就是说:

<div>
  javascript 文本节点 
  <p>javascript</p> 文本节点
  <div>jQuery</div> 文本节点
  <h5>PHP</h5> 文本节点
</div>

这样就有4个文本节点,再加上3个元素节点,就是7个子节点。


firstChild 和lastChild

分别为返回 某节点下的第一个子节点 和返回 某节点下的最后一个子节点。如果某节点没有子节点则返回null。

格式:node.firstChild   和 node.lastChild

<body>

  <div id="con"><p>javascript</p><div>jQuery</div><h5>PHP</h5></div>

<script>
    var x=document.getElementById("con"); //首先获取第一个div
 
    document.write(x.firstChild.nodeName); //获取第一个div下的第一个子节点的节点名称
    document.write(x.lastChild.nodeName); //获取第一个div下的最后一个子节点的节点名称
  
</script>
</body>

firstChild与elementNode.childNodes[0]效果一样,lastChild与elementNode.childNodes[elementNode.childNodes.length -1]效果一样。


parentNode

获取指定节点的父节点

格式:elementNode.parentNode

注意:父节点只能有一个。

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>无标题文档</title>
</head>
<body>
<div>
  javascript
  <p id="p1">javascript</p> 
  <div>jQuery</div> 
  <h5>PHP</h5> <!-- 这里的文本节点 -->
</div>
<script>
    
    var con = document.getElementById("p1"); //根据获取p元素节点
	
    var f = con.parentNode; //接着获取其父节点
	
    var n = f.lastChild; //最后获取父节点的最后一个子节点,即文本节点
	
    console.log(n.nodeName); //#text
	
 
</script>
</body>
</html>

根据获取p元素节点来运用父节点知识,最后获取h5与</div>之间的文本节点。



操作节点

访问兄弟节点

兄弟节点:两个紧跟着的节点。

nextSibling:访问节点的下一个紧跟着的节点。

格式:nodeObject.nextSibling


perviousSibling:访问节点的上一个紧跟着的节点。

格式:nodeObject.perviousSibling

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
	<title>javascript</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">css3</li>
	  <li id="e">php</li>
	  <li id="f">java</li>
	</ul>
  
  
  <script>
      /* 在此处书写javascript代码 */
	  
	  var con = document.getElementsByTagName("li")[0]; //通过标签名找到JavaScript所在的元素节点。
	  document.write(con.nodeName);
	  document.write("=");
	  document.write(con.innerHTML);
	  
	  //使用nextSibling找到节点的下一个兄弟节点,并判断其是否是元素节点。
	  function get_nextSibling (n) {
	    var x = n.nextSibling;
		
		//如果不是元素节点,继续向下查找。利用while语句继续访问下一个兄弟节点。
		while (x && x.nodeType != 1) {
		    x = x.nextSibling;
		}
		
		return x; //返回此兄弟节点。
	  }
      
	  var y = get_nextSibling(con);
	  
	  //判断是否是空节点,如果是空节点,表示已经是最后一个节点了,最后一个节点没有nextSibling。
	  if (y != null) {
	      document.write("<br>nextSibling:");
	      document.write(y.nodeName);
		  document.write("=");
		  document.write(y.innerHTML);
	  } else {
	      document.write("已经最后一个节点了。");
	  }
      
		
  </script>
  </body>
</html>

上述例子是通过nextSibling访问JavaScript后面紧跟着的jquery。

效果如下:



插入节点appendChild()

指定节点最后一个子节点列表后面添加一个节点。

格式:nodeObject.appendChild(newNode)

注:是将已经创建成的节点插入到指定节点的最后一个子节点列表后面。

其中,nodeObject表示newNode的父节点。


<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
	<title>javascript</title>
  </head>
  <body>
    
    <ul id="u1">
	  <li id="a">JavaScript</li>
	  <li id="b">jquery</li>
	  <li id="c">html</li>
	</ul>
	
  
  <script>
      /* 在此处书写javascript代码 */
	  var con = document.getElementById("u1"); //找到指定节点。
	  
	  //先创建这个新节点
	  var newNode = document.createElement("li"); //添加一个名的li的元素。
	  
	  /*var newText = document.createTextNode("css"); //添加一个文本节点。
	  newNode.appendChild(newText); */
	  
	  newNode.innerHTML = "css"; 
	  con.appendChild(newNode); //将创建好的新节点插入ul的最后一个子节点列表之后。
	  
  </script>
  </body>
</html>


上述例子是为ul添加一个新项css,第一步就是找到指定的节点ul,第二步就是创建这个新的节点,创建的方法有两种,一是添加一个新的元素li,为其添加文本节点。二是直接用innerTHML添加文本内容。最后一步用appendChild将新创建的节点插入到子节点列表之后。


insertBefore()

在已有的子节点前面添加一个新节点。

格式:nodeObject.insetBefore(newNode,node)

其中,newNode为要插入的新节点。node为已有的子节点,在此节点之前添加新节点。nodeObject表示node的父节点。

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
	<title>javascript</title>
  </head>
  <body>
    
    <ul id="u1"><li id="a">JavaScript</li><li id="b">jquery</li><li id="c">html</li>
	</ul>
	
  
  <script>
      /* 在此处书写javascript代码 */
	  var con = document.getElementById("u1"); //找到指定节点。
	  
	  //找到JavaScript所在
	  var node = con.firstChild; //找到ul的第一个子节点
	  
	  //先创建这个新节点
	  var newNode = document.createElement("li"); //添加一个名的li的元素。  
	  /*var newText = document.createTextNode("css"); //添加一个文本节点。
	  newNode.appendChild(newText); */  
	  newNode.innerHTML = "css"; 
	  
	  //插入节点
	  con.insertBefore(newNode, node); //将新节点插入到指定节点之前。
	  
  </script>
  </body>
</html>

在ul节点的第一个子节点前面添加一个新节点。


removeChild()

删除子节点列表中的某个节点,如果删除成功,则返回被删除的节点,如果失败,则返回null。

格式:nodeObject.removeChild(node)

其中,nodeObject表示node的父节点,node表示要删除的节点


<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
	<title>javascript</title>
  </head>
  <body>
    
    <ul id="u1"><li id="a">JavaScript</li><li id="b">jquery</li><li id="c">html</li>
	</ul>
	
  
  <script>
      /* 在此处书写javascript代码 */
	  var con = document.getElementById("u1"); //找到指定节点。
	  
	  //找到JavaScript所在
	  var node = con.firstChild; //找到ul的第一个子节点
	  
	  con.removeChild(node);
	  
  </script>
  </body>
</html>

删除JavaScript所在的节点。

效果:





替换节点replaceChild()

实现子节点的替换。

格式:node.replaceChild(newNode, oldNode)

其中,newNode为要替换(新创建的节点)的节点,oldNode为被替换的节点,node为它们的父节点。如果没父节点,node就表示要被替换的节点。


<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
	<title>javascript</title>
  </head>
  <body>
    
    <ul id="u1"><li id="a">JavaScript</li><li id="b">jquery</li><li id="c">html</li>
	</ul>
	
  
  <script>
      /* 在此处书写javascript代码 */
	  var con = document.getElementById("u1"); //找到指定节点。
	  
	  //找到JavaScript所在
	  var node = con.firstChild; //找到ul的第一个子节点
	  
	  //先创建一个新节点
	  var newNode = document.createElement("li");
	  newNode.innerHTML = "css";
	  
	  con.replaceChild(newNode, node); //用新创建的节点去替换JavaScript所在的节点。
	  
  </script>
  </body>
</html>

效果:


复制节点(cloneNode)

该方法接收一个参数,这个参数是一个布尔值。接收"true"时表示深复制,即复制节点及其以下的整个子节点树,也就说把这个节点和它的所有子节点均复制了。接收"false"时表示浅复制,只复制这个节点。复制后返回的节点属于文档所有,它并没有父节点,可以为其指定父节点,如使用appendChild、inserBefore()、replaceChild()将它添加到文档中。


Text类型

文本节点,是DOM结构中常见的节点类型。它表示的是可以照字面意思解释的纯文本内容。它的特点有:

  • nodeType的值为3
  • nodeName的值为#text
  • nodeValue的值为它的文本内容
  • parentNode是一个Element。(就是包含文本的元素节点)

注:元素与元素之间的空格或换行符默认为一个文本节点。


创建文本节点

document.createTextNode()

创建文本节点。

格式:document.createTextNode("文本内容");

其中,创建一个文本节点,也需要同时创建一个元素节点来包含它,要将文本节点添加到指定地方,要用appendChild()或inserBefore()插入到节点的后面或前面。

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
	<title>javascript</title>
  </head>
  <body>
    
    <ul id="u1"><li id="a">JavaScript</li><li id="b">jquery</li><li id="c">html</li>
	</ul>
	
  
  <script>
      /* 在此处书写javascript代码 */
	  var con = document.getElementById("u1"); //找到指定节点。
	  
	  //找到JavaScript所在
	  var node = con.firstChild; //找到ul的第一个子节点
	  
	  //先创建这个新节点
	  var newNode = document.createElement("li"); //添加一个名的li的元素。  
	  var newText = document.createTextNode("css"); //添加一个文本节点。
	  newNode.appendChild(newText); //将文本节点插入到某节点之后
	  //newNode.innerHTML = "css"; 
	  
	  //插入节点
	  con.insertBefore(newNode, node); //将新节点插入到指定节点之前。
	  
  </script>
  </body>
</html>

效果:



规范文本节点

normalize()方法
该方法用于处理DOM结构中的文本节点

有时一个节点的子节点中可能有一个或多个不包含文本的空文本节点。如果是不连续的空文本节点,使用这个方法可以删除它;如果是连续的空文本节点,使用这个方法可以合成一个空文本节点。

该方法也可以将所有文本节点合成一个文本节点,结果nodeValue是所有文本节点内容的拼接。

分割文本节点

splitText()方法
该方法可以将一个文本节点分成两个文本节点。



DOM简单终结:

DOM可以对页面节点进行访问、增、删、替换、复制等操作。

访问节点的方式:nextSibling、previousSibling、lastChild、firstChild、parentChild、childNodes、getAttribute()、getElementById()、getElementsByTagName()、getElementsByClassName()、getElementByName()

增加节点的方式:createElement()、createTextNode()、setAttribute()、

替换节点方式:replaceChild()

删除节点方式:removeChild()、removeAttribute()

复制节点:cloneNode()

规范文本节点:normolize()、spliceText()


nodeList保存着DOM最新的、最准确的DOM结构信息。每次访问nodeList都会在DOM结构中查询。所以要尽量减少访问nodeList的次数。


DOM操作是消耗性能最大的原因所在,应尽量减少DOM操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值