永利酒店赌场:Document 对象的常用方法

微软的开发周期中很重要的一块是调整产品的性能。性能调整也是开发者应当留心的关键部分之一。
经过多年发展,业界对于如何优化Win32程序性能已经有非常多的了解。

客户端动态输出table数据并展示表格,是web应用中较为常见的工作。对于循环打印输出tr,td本身是一件非常僵硬和暴力的编程办法,再加上最后绑定元素innerHTML字符流输出,
系统所消耗的性能代价是非常高昂的,如果我们需要展现的数据非常庞大时,那么代价也是成倍的。然而这种动态输出表格的方法是大多数客户端程序员最常用的方法。那么基于最常用的方法,
如何才能降低性能成本,改善用户体验,快速安全的显示我们所需要的数据呢?
我认为从根本上调优需要从两个方面去考虑。
1:server的数据吐出和client的数据解析。这里涉及的知识点较多,今后再做详细的说明。但是对于较为复杂的xml的数据格式来说,client的解析应该用xpath寻址和dom内置对象相结合的方法,高速定位。
2:DHTML的优化。包括dom,css,js的优化,也就是MVC(model, view,
control)的优化。
这里我们用js动态生成一个table,
构建一个3000行,8列的表格,代码分多个版本,便于清晰的比较每个版本不同的性能消耗。
vision 0.1 【耗时14694ms】
貌似以下的写法是没有任何错误,但是确是最暴力,效率最低,性能消耗最大的写法。对于大量的数据行和列,用for循环拼接元素字符串,最后innerHTML输出是不可取的。
3000记录页面加载耗时14694毫秒,近15秒。这样的页面数据加载是近乎灾难的,应该竭力避免。
<html>
 <body>
  <div id=”tableDiv”></div>
  <script>
   var maxRow =3000;
   var maxCol = 8;
   var strTbl = “<table border=’1′><tbody>”;
   var strTbody = ”;
  
   for(var i = 0; i < maxRow; i++){
    strTbody +=”<tr>”;
     for(var j = 0; j < maxCol; j++){
      strTbody += “<td>test</td>”;
     }
    strTbody += “</tr>”;
   }
   strTbl = strTbody + “</tbody></table>”;
  
   var obj = document.getElementById(“tableDiv”);
   obj.innerHTML = strTbl;
  
  </script>
 </body>
</html>

1、getElementById(id)
通过元素的ID访问元素,这是DOM一个基础的访问页面元素的方法,我们要经常用到它.
例如下面的例子,我们可以同DIV的ID迅速的访问到它,而不必通过DOM层层遍历,

 

现在开发者遇到的问题之一是不太清楚是什么导致DTHML和HTML页面运行快或者慢。当然,有一些很简单的方法——比如不要使用2MB大的图片。我们曾经使用过另外一些有趣的技巧提高了DHTML页面的性能,希望它们能帮助你改善自己的页面性能。

vision 0.2 【耗时3623ms】
这个版本的代码有非常大的改进,采用DOM技术动态添加元素,说明在需要处理展现大量数据的情况下,运用DOM快速定位并添加绑定元素的方法,效率远比拼接html元素字符串的方法要高许多。
整个页面加载完成所耗的时间为3623毫秒。3000行的记录耗时不到4秒,这个版本的代码结构和编程思路也无可挑剔,
那么这样的加载速度是否可以再快些呢?
<html>
<body>
<script>
  var _table, _tbody, tr, td, text, maxRow, maxCol;
  maxRow = 3000;
  maxCol = 8;
 
  _table = document.createElement(“table”);
  _table.border = “1”;
  _tbody = document.createElement(“tbody”);
  _table.insertBefore(_tbody, null);
 
  document.body.insertBefore(_table, null);
  for (var i=0; i<maxRow; i++) {
  tr = document.createElement(“tr”);
  for(var j = 0; j<maxCol; j++){
   td = document.createElement(“td”);
   text = document.createTextNode(“Text”);
   td.insertBefore(text, null);
   tr.insertBefore(td, null);
  }
     _tbody.insertBefore(tr, null);
  }
</script>
</body>
</html>

复制代码 代码如下:

什么是DOM?

通过JavaScript,您可以重构整个HTML文档。您可以添加、移除、改变或重排页面上的项目。

要改变页面的某个东西,JavaScript就需要对HTML文档中所有元素进行访问的入口。这个入口,连同对HTML元素进行添加、移动、改变或移除的方法和属性,都是通过文档对象模型来获得的(DOM)。

在1998年,W3C发布了第一级的DOM规范。这个规范允许访问和操作HTML页面中的每一个单独的元素。

所有的浏览器都执行了这个标准,因此,DOM的兼容性问题也几乎难觅踪影了。

DOM可被JavaScript用来读取、改变HTML、XHTML以及XML文档。

这里我使用了一个建立Table的程序例子。其中用document.createElement()和element.insertBefore的表。Cell中包含的内容称为”Text”。这段代码能有多糟呢?这么小的程序又能有多大调整余地呢?请看介绍。

vision 0.3 【耗时3320ms】
基于vision
0.2中的代码,我们可以看到,整个代码段有多处用到了”body”,”window”,”document”这样的对象,在js中类似这样的对象都为全局对象,对他们的引用操作势必会消耗性能,
对这些全局变量引用要比简单通过局部变量引用的代价要昂贵的多。
这里我们可以将”document.body”的引用缓存到局部变量中,这样就完成了一个将全局对象转换成局部变量的过程。
在代码中添加:var docBody =
document.body;并且将行:document.body.insertBefore(_table,
null);替换为:docBody.insertBefore(_table, null);
在代码中对”document”单个全局对象的引用就达到8×3000=24000次之多,获取一个document变量比局部变量大约多花费4ms时间,
所以我们下一步把document对象也缓存起来。
在代码中添加:var _doc = document;
这样,我们重新加载页面,所耗时间为3320毫秒。只比上个版本所耗的时间减少了10%,似乎性能相差不大,但是在我们日常的开发习惯中,将全局的对象缓存到局部变量中是一个好的开始。
<html>
<body>
<script>
  var _table, _tbody, tr, td, text, maxRow, maxCol;
  var docBody = document.body;
  var _doc = document;
  maxRow = 3000;
  maxCol = 8;
 
  _table = _doc.createElement(“table”);
  _table.border = “1”;
  _tbody = _doc.createElement(“tbody”);
  _table.insertBefore(_tbody, null);
 
  docBody.insertBefore(_table, null);
  for (var i=0; i<maxRow; i++) {
  tr = _doc.createElement(“tr”);
  for(var j = 0; j<maxCol; j++){
   td = _doc.createElement(“td”);
   text = _doc.createTextNode(“Text”);
   td.insertBefore(text, null);
   tr.insertBefore(td, null);
  }
     _tbody.insertBefore(tr, null);
  }
</script>
</body>
</html>
vision 0.4 【耗时2779ms】
一个document对象加载速度的优化就是在<script>标签指定defer属性。首先在这里简单介绍一下defer属性。defer作用是文档加载完毕了再执行脚本,这样回避免找不到对象的问题,
加上defer等于在页面完全在入后再执行,相当于window.onload,但应用上比window.onload
更灵活。设置这个属性仅适合不需要立即运行<SCRIPT>中代码的情况。
(立即运行的代码指不在函数体内的--这些代码将会在脚本块加载后立即执行)当defer属性设置后,IE不会等待加载和转换这段脚本。这就也为着页面加载会快很多。
通常这意味着立即运行的脚本应该封装放在一个函数内,并通过document或者body的onload的事件处理。如果你的脚本是依赖于页面加载后的用户动作,如点击按钮,或者移动鼠标到某个区域,会更加有用!
最后请注意两点:
1、不要在defer型的脚本程序段中调用document.write命令,因为document.write将产生直接输出效果。
2、不要在defer型脚本程序段中包括任何立即执行脚本要使用的全局变量或者函数。
<html>
<body onload=”init()”>
<script defer>
function init() {
  var _table, _tbody, tr, td, text, maxRow, maxCol;
  var docBody = document.body;
  var _doc = document;
  maxRow = 3000;
  maxCol = 8;
 
  _table = _doc.createElement(“table”);
  _table.border = “1”;
  _tbody = _doc.createElement(“tbody”);
  _table.insertBefore(_tbody, null);
 
  docBody.insertBefore(_table, null);
  for (var i=0; i<maxRow; i++) {
  tr = _doc.createElement(“tr”);
  for(var j = 0; j<maxCol; j++){
   td = _doc.createElement(“td”);
   text = _doc.createTextNode(“Text”);
   td.insertBefore(text, null);
   tr.insertBefore(td, null);
  }
     _tbody.insertBefore(tr, null);
  }
}
</script>
</body>
</html>
 
 vision 0.5 【耗时2650ms】
 上一个版本中的页面加载速度已经缩短到了2779ms。下面我们对代码进行进一步的优化。
 我们看到代码中dom操作,绑定子元素的方法是由下至上包裹,这样的元素绑定方式会相对较慢。
  create <TR>
  create <TD>
  create TextNode
第一步 insert TextNode into <TD>
第二步 insert <TD> into <TR>
第三步 insert <TR> into TBODY
 
 现在我们将元素的绑定顺序颠倒过来,由上至下的包裹绑定元素
  create <TR>
  create <TD>
  create TextNode
第一步 insert <TR> into TBODY
第二步 insert <TD> into <TR>
第三步 insert TextNode into <TD>
<html>
<body onload=”init()”>
<script defer>
function init() {
  var _table, _tbody, tr, td, text, maxRow, maxCol;
  var docBody = document.body;
  var _doc = document;
  maxRow = 3000;
  maxCol = 8;
 
  _table = _doc.createElement(“table”);
  _table.border = “1”;
  _tbody = _doc.createElement(“tbody”);
  _table.insertBefore(_tbody, null);
  docBody.insertBefore(_table, null);
 
  for (var i=0; i<maxRow; i++) {
  tr = _doc.createElement(“tr”);
   _tbody.insertBefore(tr, null);
  for(var j = 0; j<maxCol; j++){
   td = _doc.createElement(“td”);
   text = _doc.createTextNode(“Text”);
   td.insertBefore(text, null);
   tr.insertBefore(td, null);
  }
  }
}
</script>
</body>
</html>

<body>
<div id=’divid’><p>h</p>
Just for testing;
</div>
<div id=’divid’>
Just for testing;
</div>
<script>
var div=document.getElementById(‘divid’);
alert(div.nodeName);
</script>
</body>

DOM被分为不同的部分(核心、XML及HTML)和级别(DOM Level 1/2/3):

Core DOM

定义了一套标准的针对任何结构化文档的对象

XML DOM

定义了一套标准的针对XML文档的对象

HTML DOM

定义了一套标准的针对HTML文档的对象。


HTML DOM 节点


HTML文档中的每个成分都是一个节点。


一开始我写了一段自认为会很快的程序,我尽量避免一些低级问题—-像没有显式定义变量、或者在一个页面中同时使用VBScript和Javascript。程序如下:

vision 0.6 【耗时2580ms】
这个版本中我们要调优的是修改table的css属性,使用fixed-table布局(layout)。指定了fixed-table布局后的表格的列宽使用<col>标签设置。
fixed-table布局样式将改善table的性能,因为每个单元格的内容的尺寸不需要进行计算了。这是一个非常实用的性能改善方法,特别是那些有很多列的大型表格。
这个操作也可以通过简单增加css样式实现:
<html>
<body onload=”init()”>
<script defer>
function init() {
  var _table, _tbody, tr, td, text, maxRow, maxCol;
  var docBody = document.body;
  var _doc = document;
  maxRow = 3000;
  maxCol = 8;
 
  _table = _doc.createElement(“table”);
  _table.border = “1”;
  _table.style.tableLayout = “fixed”;
  _tbody = _doc.createElement(“tbody”);
  _table.insertBefore(_tbody, null);
  docBody.insertBefore(_table, null);
 
  for (var i=0; i<maxRow; i++) {
  tr = _doc.createElement(“tr”);
   _tbody.insertBefore(tr, null);
  for(var j = 0; j<maxCol; j++){
   td = _doc.createElement(“td”);
   text = _doc.createTextNode(“Text”);
   td.insertBefore(text, null);
   tr.insertBefore(td, null);
  }
  }
}
</script>
</body>
</html>

注意使用这个函数时如果元素的ID不是唯一的,那么会获得第一个符合条件的元素。
在IE6中如果input、checkbox,radio. 等元素name匹配指定的ID,也会被访问到
例如下面的例子中,获得的元素是input:

节点

根据DOM,HTML文档中的每个成分都是一个节点。

DOM是这样规定的:

·         整个文档是一个文档节点

·         每个HTML标签是一个元素节点

·         包含在HTML元素中的文本是文本节点

·         每一个HTML属性是一个属性节点

·         注释属于注释节点


在PII233/64MB内存/NT4.0/IE5.0的机器上运行这段程序。页面从本机上装载。从开始装载页面到页面完全安静下来的时间为2328毫秒,这也是本次测试的基线。

vision 0.7 【耗时2210ms】
最后的一个版本的调优就是给单元格赋值的方式。在所有的示例中,创建了一个TextNode,并添加给TD。而在这个版本中我们将使用innerText代替插入一个text节点,代码调整为:
td.innerText = “Text”;
(注意:innerText只在IE中受支持,属于IE扩展,兼容FireFox可使用innerHTML,但是innerHTML正如文章开头所说的,效率非常低下,不建议使用)
<html>
<body onload=”init()”>
<script defer>
  function init() {
  var _table, _tbody, tr, td, text, maxRow, maxCol;
  var docBody = document.body;
  var _doc = document;
  maxRow = 3000;
  maxCol = 8;
 
  _table = _doc.createElement(“table”);
  _table.border = “1”;
  _table.style.tableLayout = “fixed”;
  _tbody = _doc.createElement(“tbody”);
 
  docBody.insertBefore(_table, null);
  _table.insertBefore(_tbody, null);
 
  for (var i=0; i<maxRow; i++) {
  tr = _doc.createElement(“tr”);
   _tbody.insertBefore(tr, null);
  for(var j = 0; j<maxCol; j++){
   td = _doc.createElement(“td”);
   td.innerText = “Text”;
   tr.insertBefore(td, null);
  }
  }
}
</script>
</body>
</html>

复制代码 代码如下:

Node 层次

节点彼此都有等级关系。

HTML文档中的所有节点组成了一个文档树(或节点树)。HTML文档中的每个元素、属性、文本等都代表着树中的一个节点。树起始于文档节点,并由此继续伸出枝条,直到处于这棵树最低级别的所有文本节点为止。

这个页面中,一个很耗时的操作是频繁引用全局对象,如“document”、“body”、“window”等。引用所有这些类似的全局变量远比引用一个本地变量代价高昂。

vision 0.8 【耗时672ms】终极优化
将字符串作为数组对象的方式是目前效率最高,性能最优的方式。
<script>
 var t1 = new Date();
</script>
<html>
 <head>
  <title></title>
  <script>
   function testTime(){
    var t2 = new Date();
    alert(t2-t1+”ms”);
   }
  
  </script>
 
 </head>
 <body onload=”init();testTime();”>
  <div id=”tableDiv”></div>
  <script>
   var maxRow =3000;
   var maxCol = 8;
   var strTbody = [“<table border=’1′><tbody>”];
  
   for(var i = 0; i < maxRow; i++){
    strTbody.push(“<tr>”);
     for(var j = 0; j < maxCol; j++){
      strTbody.push(“<td>test</td>”);
     }
    strTbody.push(“</tr>”);
   }
  
   strTbody.push(“</tbody></table>”);
  
   var obj = document.getElementById(“tableDiv”);
   obj.innerHTML = strTbody.join(“”);
  </script>
 </body>
</html>

<body>
<input name=’divid’ type=”text”/>
<div id=’divid’>
Just for testing;
</div>
<script>
var div=document.getElementById(‘divid’);
alert(div.nodeName);
</script>
</body>

文档树(节点数)

请看下面这个HTML文档:

<html>

  <head>

    <title>DOM Tutorial</title> 

  </head> 

  <body> 

    <h1>DOM Lesson one</h1> 

    <p>Hello world!</p> 

  </body> 

</html>

上面所有的节点彼此间都存在关系

除文档节点之外的每个节点都有父节点。举例,<head> 和
<body>的父节点是<html>节点,文本节点”Hello
world!”的父节点是<p>节点。

大部分元素节点都有子节点。比方说,<head>节点有一个子节点:<title>节点。<title>节点也有一个子节点:文本节点”DOM
Tutorial”。

当节点分享同一个父节点时,它们就是同辈(同级节点)。比方说,<h1>和
<p>是同辈,因为它们的父节点均是<body>节点。

节点也可以拥有后代,后代指某个节点的所有子节点,或者这些子节点的子节点,以此类推。比方说,所有的文本节点都是<html>节点的后代,而第一个文本节点是<head>节点的后代。

节点也可以拥有先辈。先辈是某个节点的父节点,或者父节点的父节点,以此类推。比方说,所有的文本节点都可把<html>节点作为先辈节点。


HTML DOM访问节点


通过DOM,您可访问HTML文档中的每个节点。


因此我作了第一次改进尝试:缓存document.body 到本地变量“theBody”中:

来源:

2、getElementsByName(name)
返回名字是name的元素数组,在IE6中元素ID匹配这个名字的话,这个元素也将包括在内,而且getElementsByName()仅用于象input,radio,checkbox等元素对象。
象下面例子中georges数组的长度应该是0。

查找并访问节点

你可通过若干种方法来查找您希望操作的元素:

·         通过使用 getElementById() 和 getElementsByTagName() 方法

·         通过使用一个元素节点的parentNode、firstChild以及lastChild属性


增加了如下代码:

复制代码 代码如下:

getElementById() 和 getElementsByTagName()

getElementById() 和
getElementsByTagName()这两种方法,可查找整个HTML文档中的任何HTML元素。

这两种方法会忽略文档的结构。假如您希望查找文档中所有的<p>元素,getElementsByTagName()会把它们全部找到,不管<p>元素处于文档中的哪个层次。同时,getElementById()方法也会返回正确的元素,不论它被隐藏在文档结构中的什么位置。

这两种方法会像您提供任何你所需要的HTML元素,不论它们在文档中所处的位置!

getElementById()可通过指定的ID来返回元素:

var theBody = document.body;然后修改这一行:

<body>
<div name=”george”>f</div>
<div name=”george”>f</div>
<script type=”text/javascript”>
var georges=document.getElementsByName(“george”);
alert(georges.length);
</script>
</body>

getElementById() 语法

document.getElementById("ID"); 

注释:getElementById()
无法工作在XML中。在XML文档中,您必须通过拥有类型id的属性来进行搜索,而此类型必须在XML
DTD中进行声明。

getElementsByTagName()
方法会使用指定的标签名返回所有的元素(作为一个节点列表),这些元素是您在使用此方法时所处的元素的后代。

getElementsByTagName() 可被用于任何的HTML元素:

document.body.insertBefore;将之改为:

3、getElementsByTagName(tagname)
getElementByTagName可以用于DOCUMENT也可以用元素。getElementsByTagName返回具有指定tagname的子元素列表(数组)。你可以遍历这个数组获得每一个单独的子元素。当处理很大的DOM结构,使用这种方法可以很容易的所有缩小范围。

getElementsByTagName() 语法

document.getElementsByTagName("标签名称"); 

或者:

document.getElementById('ID').getElementsByTagName("标签名称"); 

theBody.insertBefore;View the second sample.

复制代码 代码如下:

实例 1

下面这个例子会返回文档中所有<p>元素的一个节点列表:

document.getElementsByTagName("p"); 

这次修改并没有太大影响到整体时间,它只缩短了3
ms。但它已经表明,如果在循环中也有document.body对象而对其引用做出修改,带来的好处将是可观的。

<html>
<head>
<title></title>
<script>
function start() {
// 获得所有tagName是body的元素(当然每个页面只有一个)
myDocumentElements=document.getElementsByTagName(“body”);
myBody=myDocumentElements.item(0);
// 获得body子元素种的所有P元素
myBodyElements=myBody.getElementsByTagName(“p”);
// 获得第二个P元素
myP=myBodyElements.item(1);
//显示这个元素的文本
alert(myP.firstChild.nodeValue);
}
</script>
</head>
<body onload=”start()”>
<p>hi</p>
<p>hello</p>
</body>
</html>

实例 2

下面这个例子会返回所有<p>元素的一个节点列表,且这些<p>元素必须是id为”maindiv”的元素的后代:

document.getElementById('maindiv').getElementsByTagName("p"); 

随后,我缓存了document对象—-在我们这个测试中,document对象共被引用了3002次。修改后代码如下:

DOM Element 常用方法
1、appendChild(node)
向当前节点对象的追加节点。经常用于给页面动态的添加内容。
例如下面给div添加一个文本节点:

节点列表(nodeList)

当我们使用节点列表时,通常要把此列表保存在一个变量中,就像这样:

var x=document.getElementsByTagName("p");

现在,变量x包含着页面中所有<p>元素的一个列表,并且我们可以通过它们的索引号来访问这些<p>元素。

注释:索引号从0开始。

您可以通过使用length属性来循环遍历节点列表:

var x=document.getElementsByTagName("p");

for (var i=0;i<x.length;i++)

  { 

  // do something with each paragraph

  }

您也可以通过索引号来访问某个具体的元素。

要访问第三个<p>元素,您可以这么写:

var y=x[2];

View the third sample.

复制代码 代码如下:

parentNode、firstChild以及lastChild

这三个属性 parentNode、firstChild 以及 lastChild
可遵循文档的结构,在文档中进行“短距离的旅行”。

请看下面这个HTML片段:

<table>

  <tr>

    <td>John</td>

    <td>Doe</td>

    <td>Alaska</td>

  </tr>

</table>

在上面的HTML代码中,第一个<td>是<tr>元素的首个子元素(firstChild),而最后一个<td>是<tr>元素的最后一个子元素(lastChild)。

此外,<tr>是每个<td>元素的父节点(parentNode)。

对firstChild最普遍的用法是访问某个元素的文本:

var x=[a paragraph];

var text=x.firstChild.nodeValue; 

parentNode属性常被用来改变文档的结构。假设您希望从文档中删除带有id为”maindiv”的节点:

var x=document.getElementById("maindiv");

x.parentNode.removeChild(x); 

首先,您需要找到带有指定id的节点,然后移至其父节点并执行removeChild()方法。


此次运行时间只有2100ms,节约了大约10%的时间。使用本地变量而不是直接引用document对象平均每次节约了0.4毫秒。

<div id=”test”></div>
<script type=”text/javascript”>
var newdiv=document.createElement(“div”)
var newtext=document.createTextNode(“A new div”)
newdiv.appendChild(newtext)
document.getElementById(“test”).appendChild(newdiv)
</script>

根节点

有两种特殊的文档属性可用来访问根节点:

·         document.documentElement

·         document.body

第一个属性可返回存在于XML以及HTML文档中的文档根节点。

第二个属性是对HTML页面的特殊扩展,提供了对<body>标签的直接访问。


HTML DOM 节点信息


nodeName、nodeValue以及nodeType包含有关于节点的信息。


一个常用的优化性能的方法是:当脚本不需要立即运行时,在

上面的例子中给DIV添加文本,也可以用newdiv.innerHTML=”A new div”实现,
不过innerHTML不属于DOM
2、removeChild(childreference)
移除当前节点的子节点,返回被移除的节点。这个被移除的节点可以被插入document树中别的地方

节点信息

每个节点都拥有包含着关于节点某些信息的属性。这些属性是:

·         nodeName(节点名称)

·         nodeValue(节点值)

·         nodeType(节点类型)


View the fourth sample.

复制代码 代码如下:

nodeName

nodeName属性含有某个节点的名称。

·         元素节点的nodeName是标签名称

·         属性节点的nodeName是属性名称

·         文本节点的nodeName永远是#text

·         文档节点的nodeName永远是#document

注释:nodeName所包含的XML元素的标签名称永远是大写的


这次测试的时间为2043 ms。相对基线测试提高了12%,比上次测试提高了2.5%。

<div id=”father”><div id=”child”>A
child</div></div>
<script type=”text/javascript”>
var childnode=document.getElementById(“child”)
var
removednode=document.getElementById(“father”).removeChild(childnode)
</script>

nodeValue

对于文本节点,nodeValue属性包含文本。

对于属性节点,nodeValue属性包含属性值。

nodeValue属性对于文档节点和元素节点是不可用的。

下面我们谈到的一个改进方法非常有用,当然也稍微麻烦一点。当需要创建元素然后将其插入树状的结构中时,将其直接插入到主干中效率更高—-而不是首先将其插入大的子树,然后再将大的子树插入主干。例如,如果你创建一个每行有一列、列中有一些文字的表,你可以这样做:

3、cloneNode(deepBoolean)
复制并返回当前节点的复制节点,这个复制得到的节点是一个孤立的节点,不在document树中。复制原来节点的属性值,包括ID属性,所以在把这个新节点加到document之前,一定要修改ID属性,以便使它保持唯一。当然如果ID的唯一性不重要可以不做处理。
这个方法支持一个布尔参数,当deepBoolean设置true时,复制
当前节点的所有子节点,包括该节点内的文本。

nodeType

nodeType属性可返回节点的类型。

最重要的节点类型是:

元素类型

节点类型

元素

1

属性

2

文本

3

注释

8

文档

9


一个 HTML DOM 实例

  1. 创建

  2. 创建

  3. 创建TextNode节点

  4. 将TextNode 插入

复制代码 代码如下:

一个HTML DOM的实例

下面这个例子向我们展示了当一个用户在文档中点击时,HTML文档的背景颜色如何被改变。

<html>

<head>

<script type="text/javascript">

function ChangeColor()

{

document.body.bgColor="yellow"

}

</script>

</head>

<body onclick="ChangeColor()">

Click on this document!

</body>

</html>

DOM的核心: Node
由于DOM是树形结构,所以一个节点被抽象为对象Node,这是DOM的核心对象:
Node的种类一共有12种,通过Node.nodeType的取值来确定(为1-12),分为:

Js代码

  1. Node.ELEMENT_NODE (1)   
  2. Node.ATTRIBUTE_NODE (2)   
  3. Node.TEXT_NODE (3) //<![CDATA[ ]]>中括着的纯文本,它没有子节点
      
  4. Node.CDATA_SECTION_NODE (4) //子节点一定为TextNode   
  5. Node.ENTITY_REFERENCE_NODE (5)    
  6. Node.ENTITY_NODE (6) //DTD中的实体定义<!ENTITY foo “foo”>,无子节点
      
  7. Node.PROCESSING_INSTRUCTION_NODE (7) //PI,无子节点   
  8. Node.COMMENT_NODE (8)   
  9. Node.DOCUMENT_NODE (9) //最外层的Root element,包括所有其它节点   
  10. Node.DOCUMENT_TYPE_NODE (10) //DTD,<!DOCTYPE………..>   
  11. Node.DOCUMENT_FRAGMENT_NODE (11)   
  12. Node.NOTATION_NODE (12) //DTD中的Nation定义   

Node.ELEMENT_NODE (1)

Node.ATTRIBUTE_NODE (2)

Node.TEXT_NODE (3) //<![CDATA[ ]]>中括着的纯文本,它没有子节点

Node.CDATA_SECTION_NODE (4) //子节点一定为TextNode

Node.ENTITY_REFERENCE_NODE (5) 

Node.ENTITY_NODE (6) //DTD中的实体定义<!ENTITY foo “foo”>,无子节点

Node.PROCESSING_INSTRUCTION_NODE (7) //PI,无子节点

Node.COMMENT_NODE (8)

Node.DOCUMENT_NODE (9) //最外层的Root element,包括所有其它节点

Node.DOCUMENT_TYPE_NODE (10) //DTD,<!DOCTYPE………..>

Node.DOCUMENT_FRAGMENT_NODE (11)

Node.NOTATION_NODE (12) //DTD中的Nation定义 

❑ Node接口包含的特性/方法
节点的属性
nodeName
属性将返回一个字符串,其内容是给定节点的名字。如果节点是元素节点,返回这个元素的名称;如果是属性节点,返回这个属性的名称;如果是文本节点,返回一个内容为#text
的字符串;

nodeType 属性将返回一个整数,这个数值代表给定节点的类型
nodeValue
属性将返回给定节点的当前值.如果节点是元素节点,返回null;如果是属性节点,返回这个属性的名称;如果是文本节点,返回文本节点的内容;

ownerDocument 指向这个节点所属的文档
attributes 包哈勒代表一个元素的特性的Attr对象;仅用于Element节点

childNodes 所有子节点的列表
firstChild 指向在childNodes列表中的第一个节点
lastChild 指向在childNodes列表中的最后一个节点
nextSibling
指向后一个兄弟节点;如果这个节点就是最后一个兄弟节点,那么该值为null
previousSibling
指向前一个兄弟节点;如果这个节点就是第一个兄弟节点,那么该值为null
parentNode 返回一个给定节点的父节点

❑ hasChildNodes() 当childNodes包含一个或多个节点时,返回真
❑ appendChild(node) 将node添加到childNodes的末尾
❑ removeChild(node) 将node从childNodes中删除

❑ insertBefore(newnode refnode) 在childNodes中的refnode之前插入newnode

Js代码

  1. var container = document.getElementById(“content”);   
  2. var message = document.getElementById(“fineprint”);   
  3. var para = document.createElement(“p”);   
  4. container.insertBefore(para,message);  

var container = document.getElementById("content");

var message = document.getElementById("fineprint");

var para = document.createElement("p");

container.insertBefore(para,message);

  ❑ replaceChild(newnode,oldnode)将childNodes中的oldnode替换成newnode

Js代码

  1. var container = document.getElementById(“content”);   
  2. var message = document.getElementById(“fineprint”);   
  3. var para = document.createElement(“p”);   
  4. container.replaceChild(para,message);  

var container = document.getElementById("content");

var message = document.getElementById("fineprint");

var para = document.createElement("p");

container.replaceChild(para,message);

 ❑ 获得Node:

Js代码

  1. /* 通过document对象 */  
  2. var oHtml = document.documentElement;   
  3.   
  4.   
  5. /* 得到<head />和<body /> */  
  6. var oHead = oHtml.firstChild;   
  7. var oBody = oHtml.lastChild;   
  8. /* 可以用这种方式 */  
  9. var oHead = oHtml.childNodes[0];   
  10. var oBody = oHtml.childNodes[1];   
  11. /* 也可以使用方法获取数组的索引值 */  
  12. var oHead = oHtml.childNodes.item(0);   
  13. var oBody = oHtml.childNodes.item(1);   
  14. /* 使用document.body来得到<body /> */  
  15. var oBody = document.body;  

/* 通过document对象 */

var oHtml = document.documentElement;

 

 

/* 得到<head />和<body /> */

var oHead = oHtml.firstChild;

var oBody = oHtml.lastChild;

/* 可以用这种方式 */

var oHead = oHtml.childNodes[0];

var oBody = oHtml.childNodes[1];

/* 也可以使用方法获取数组的索引值 */

var oHead = oHtml.childNodes.item(0);

var oBody = oHtml.childNodes.item(1);

/* 使用document.body来得到<body /> */

var oBody = document.body;

❑ createElement(element)
创建一个指定标签名创建一个新的元素节点,返回值为指向新建元素节点的引用指针。
eg) var para = document.createElement(“p”);
document.body.appendChild(para);

❑ createTextNode()
创建一个包含着给定文本的新文本节点,返回一个指向新建文本节点的引用指针:
reference = document.createTextNode()
参数为新建文本节点所包含的文本字符串

Js代码

  1. var message = document.createTextNode(“hello world”);   
  2. var container = document.createElement(“p”);   
  3. container.appendChild(message);   
  4. document.body.appendChild(container);  

var message = document.createTextNode("hello world");

var container = document.createElement("p");

container.appendChild(message);

document.body.appendChild(container);

 ❑ cloneNode()
reference = node.cloneNode(deep)
为给定节点创建一个副本,参数为 true 或者 false,true
表示同时复制该节点的子节点,false 则不复制任何子节点。

Js代码

  1. var para = document.createElement(“p”);   
  2. var message = document.createTextNode(“hello world”);   
  3. para.appendChild(message);   
  4. document.body.appendChild(para);   
  5. var newpara = para.cloneNode(true);   
  6. document.body.appendChild(newpara);  

var para = document.createElement("p");

var message = document.createTextNode("hello world");

para.appendChild(message);

document.body.appendChild(para);

var newpara = para.cloneNode(true);

document.body.appendChild(newpara);

❑ 检测节点类型
通过使用nodeType特性检验节点类型:
alert(document.nodeType); //outputs “9”
alert(document.documentElement.nodeType); //outputs “1”
这个例子中,document.nodeType返回9,等于Node.DOCUMENT_NODE;同时document.
documentElement.nodeType返回1,等于Node.ELEMENT_NODE。

也可以用Node常量来匹配这些值:
alert(document.nodeType == Node.DOCUMENT_NODE); //true
alert(document.documentElement.nodeType == Node.ELEMENT_NODE); //true

这段代码可以在Mozilla 1.0+、Opera 7.0+和Safari
1.0+上正常运行。但是IE不支持这些常量,所以这些代码在IE上会产生错误。

❑ 处理特性
即便Node接口已具有attributes方法,且已被所有类型的节点继承,然而,只有Element节点才能有特性。
Element节点的attributes属性其实是NamedNodeMap,它提供一些用于访问和处理其内容的方法:
getNamedItem(name) 返回nodeName属性值等于name的节点;
removeNamedItem(name) 删除nodeName属性值等于name的节点;
setNamedItem(node) 将node添加到列表中,按其nodeName属性进行索引;
item(pos)  像NodeList一样,返回在位置pos的节点;

请记住这些方法都是返回一个Attr节点,而非特性值。
NamedNodeMap对象也有一个length属性来指示它所包含的节点的数量。

当NamedNodeMap用于表示特性时,其中每个节点都是Attr节点,它的nodeName属性被设置为特性名称,而nodeValue属性被设置为特性的值。
例如,假设有这样一个元素:
<p id=”p1″ style=”color:red”>hello world!</p>

假设变量oP包含指向这个元素的一个引用。于是可以这样访问id特性的值:
var sId = oP.attributes.getNamedItem(“id”).nodeValue; //p1
或者
var sId = oP.attributes.item(0).nodeValue;

还可以通过给nodeValue属性赋新值来改变id特性:
oP.attributes.getNamedItem(“id”).nodeValue = “newId”;

Attr节点也有一个完全等同于(同时也完全同步于)nodeValue属性的value属性,并且有name属性和nodeName属性保持同步。我们可以随意使用这些属性来修改或变更特性。

因为这个方法有些累赘,DOM又定义了三个元素方法来帮助访问特性:
getAttribute(name) 等于attributes.getNamedItem(name).value;
setAttribute(name, newvalue) 等于attribute.getNamedItem(name).value =
newvalue;
removeAttribute(name) 等于attributes.removeNamedItem(name)

要获取前面用的<p/>的id特性,只需这样做:
var sId = oP.getAttribute(“id”);
更改ID:
oP.setAttribute(“id”, “newId”);

❑ setAttribute()
element.setAttribute(attributeName,attributeValue);
为给定元素节点添加一个新的属性值或是改变它的现有属性

❑ getAttribute
attributeValue = element.getAttribute(attributeName)
返回一个给定元素的一个给定属性节点的值。

❑ getElementById()
element = document.getElementById(ID)
寻找一个有着给定 id 属性值的元素,返回一个元素节点

❑ getElementsByName()
用来获取所有name特性等于指定值的元素:
elements = document.getElementsByName(tagName)
返回一个节点集合。

❑ getElementsByTagName()
用于寻找有着给定标签名的所有元素:
elements = document.getElementsByTagName(tagName)
返回一个节点集合。

❑ 生成与操作Node
永利酒店赌场,createAttribute(name) :创建一个名为name的属性节点。
createCDATASection(text) :创建一个子节点为text的CDATA区。
createComment(text) :创建一个注释内容为text的注释节点。
createDocumentFragment() :创建一个文档片断(fragment)节点。
createElement(tagName) :创建一个名为tagName的元素节点。
createEntityReference(name) :Creates an entity reference node with the
given name。
createProcessingInstruction(target, data) :Creates a PI node with the
given target and data。
createTextNode(text) :创建一个包含text的文本节点。
其中最重要的方法是createElement(),createDocumentFragment(), create
TextNode()。

Js代码

  1. /*使用createElement(),createTextNode(),appendChild()动态添加节点*/  
  2. function createMessage(){   
  3.  var op = document.createElement(“p”);   
  4.  var oText = document.createTextNode(“hello world!”);   
  5.  op.appendChild(oText);   
  6.  document.body.appendChild(op);   
  7. }  

/*使用createElement(),createTextNode(),appendChild()动态添加节点*/

function createMessage(){

 var op = document.createElement("p");

 var oText = document.createTextNode("hello world!");

 op.appendChild(oText);

 document.body.appendChild(op);

}

❑ 使用createDocumentFragment()

Js代码

  1. //通常做法   
  2. var arrText = [‘first’, ‘second’, ‘third’];   
  3. for(var i=0; i<arrText.length; i++){   
  4.     var op = document.createElement(‘p’);   
  5.     var oText = document.createTextNode(arrText[i]);   
  6.     op.appendChild(oText);   
  7.     document.body.appendChild(op);   
  8. }   
  9.   
  10. //使用documentFragment   
  11. var arrText = [‘first’, ‘second’, ‘third’];   
  12. var oFragment = document.createDocumentFragment();   
  13. for(var i=0; i<arrText.length; i++){   
  14.     var op = document.createElement(‘p’);   
  15.     var oText = document.createTextNode(arrText[i]);   
  16.     op.appendChild(oText);   
  17.     oFragment.appendChild(op);   
  18. }   
  19. document.body.appendChild(oFragment);  

//通常做法

var arrText = ['first', 'second', 'third'];

for(var i=0; i<arrText.length; i++){

 var op = document.createElement('p');

 var oText = document.createTextNode(arrText[i]);

 op.appendChild(oText);

 document.body.appendChild(op);

}

 

//使用documentFragment

var arrText = ['first', 'second', 'third'];

var oFragment = document.createDocumentFragment();

for(var i=0; i<arrText.length; i++){

 var op = document.createElement('p');

 var oText = document.createTextNode(arrText[i]);

 op.appendChild(oText);

 oFragment.appendChild(op);

}

document.body.appendChild(oFragment);

  通过DocumentFragment的方式效率更高。

❑ HTML DOM:
使用DOM的核心方法是针对所有XML的,针对HTML DOM有特殊的方法,如
使用DOM core:oImg.setAttribute(“src”, “picture.gif”);
使用HTML DOM:oImg.src = “picture.jpg”;

插入到

<p id=”mypara”>11111</p>
p=document.getElementById(“mypara”)
pclone = p.cloneNode(true);
p.parentNode.appendChild(pclone);

简介

本文概述了一些强大的,基本的DOM
级别一中的法以及如何在JavaScript中使用它们。你将会学习到如何动态地创建,访问,控制以及移除HTML元素。这里提到的DOM方法,并非是
HTML专有的;它们在XML中同样适用。这里所有的示例,在任何全面支持DOM
level1
的浏览器里都能正常工作;例如Mozilla浏览器或者其他基于Mozilla的浏览器。这里的示例代码在IE5中也能正常工作。

这里所提到的DOM方法是第一级文档对象模型定义的核心的一部分。DOM
级别一包括对文档进行访问和处理的方法(DOM 1
核心)和专门为HTML文档定义的方法。

4、replaceChild(newChild, oldChild)
把当前节点的一个子节点换成另一个节点
例如:

Sample1.html概览

这段文字是通过一个实例代码来介绍了DOM的。那么我们从下面的HTML示例来开始吧。这段示例使用了DOM
级别一的方法,从JavaScript动态创建了一个HTML表格。它创建了一个包含了四个单元的小表格,并且在每个单元中含有文本。单元中文字内容是
“这个单元式y行x列”,来展示单元格在表格中所处的位置。

<head>

<title>样例代码 - 使用 JavaScript 和 DOM 接口创建一个 HTML 表格</title>

<script>

    function start() {

        // 获得从body的引用

        var mybody=document.getElementsByTagName("body").item(0);

        // 创建一个TABLE的元素

        mytable = document.createElement("TABLE");

        // 创建一个TBODY的元素

        mytablebody = document.createElement("TBODY");

        // 创建所有的单元格

        for(j=0;j<2;j++) {

            // 创建一个TR元素

            mycurrent_row=document.createElement("TR");

            for(i=0;i<2;i++) {

                // 创建一个TD元素

                mycurrent_cell=document.createElement("TD");

                // 创建一个文本(text)节点

                currenttext=document.createTextNode("cell is row "+j+", column "+i);

                // 将我们创建的这个文本节点添加在TD元素里

                mycurrent_cell.appendChild(currenttext);

                // 将TD元素添加在TR里

                mycurrent_row.appendChild(mycurrent_cell);

            }

            // 将TR元素添加在TBODY里

            mytablebody.appendChild(mycurrent_row);

        }

        // 将TBODY元素添加在TABLE里

        mytable.appendChild(mytablebody);

        // 将TABLE元素添加在BODY里

        mybody.appendChild(mytable);

        // 设置mytable的边界属性border为2

        mytable.setAttribute("border","2");

    }

</script>

</head>

<body onload="start()">

</body>

</html>

注意我们创建元素和文本节点的顺序:

  1. 首先我们创建了TABLE元素。
  2. 然后,我们创建了TABLE的子元素–TBODY。
  3. 然后,我们使用循环语句创建了TBODY的子元素–TR。
  4. 对于每一个TR元素,我们使用一个循环语句创建它的子元素–TD。
  5. 对于每一个TD元素,我们创建单元格内的文本节点。

现在,我们创建了TABLE,TBODY,TR,TD等元素,然后创建了文本节点;接下来,我们将每一个对象接在各自的父节点上,使用逆序:

  1. 首先,我们将每一个文本节点接在TD元素上

2.  mycurrent_cell.appendChild(currenttext);
  1. 然后,我们将每一个TD元素接在他的父TR元素上。

4.  mycurrent_row.appendChild(mycurrent_cell);
  1. 然后,我们将每一个TR元素接在他们的父TBODY元素上。

6.  mytablebody.appendChild(mycurrent_row);
  1. 下一步,我们将TBODY元素接在他的父TABLE元素上

8.  mytable.appendChild(mytablebody);
  1. 最后,我们将TABLE元素接在他的父元素BODY上。

10.mybody.appendChild(mytable);

请记住这个机制。你将会在W3C
DOM编程中经常使用它。首先,你从上到下的创建元素;然后你从下向上的将子元素接在他们的父元素上。

下面是由javascript代码生成的HTML代码:

<TABLE border=5>

<tr><td>cell is row 0 column 0</td><td>cell is row 0 column 1</td></tr>

<tr><td>cell is row 1 column 0</td><td>cell is row 1 column 1</td></tr>

</TABLE>

下面是由代码生成的TABLE及其子元素的DOM对象树:

你可以只用一些DOM方法来创建这个表格和它内部的子元素。请在脑海中时刻保留你想要创建的数据结构的树之模型,这样有利于更简便的写出必须的代码。在图1的TABLE树中,TABLE有一个子元素TBODY。TBODY有两个子元素。每一个TR又含有一个子元素(TD)。最后,每一个TD
有一个子元素–文本节点。

插入到TBODY

复制代码 代码如下:

基本DOM方法 – Sample2.html

getElementByTagName是文档接口(Document interface)和元素接口(Element
interface)的中的方法,所以不管是根文档对象还是所有的元素对象都含有方法getElementByTagName。用来通过它们的标签名称(tag
name)来获得某些元素的一系列子元素。你可以使用的方法是:element.getElementsByTagName(tagname)

getElementsByTagName返回一个有特定标签名称(tagname)的子元素列表。从这个子元素列表中,你可以通过调用item和你想得到的元素的下标,来获得单个元素。列表中第一个元素的下标是0。上面的方法很简单,但是当你操作一个巨大的数据结构时还是应该小心一些。
OK,我们下一个话题中要继续对我们的表格例子进行修改。下面的示例更加简单,它意图展示一些基础的方法:

<html>

<head>

<title>样例代码 - 使用 JavaScript 和 DOM 接口操作 HTML 表格</title>

<script>

    function start() {

        // 获得所有的body元素列表(在这里将只有一个)

        myDocumentElements=document.getElementsByTagName("body");

        // 我们所需要body元素是这个列表的第一个元素

        myBody=myDocumentElements.item(0);

        // 现在,让我们获得body的子元素中所有的p元素

        myBodyElements=myBody.getElementsByTagName("p");

        // 我们所需要的是这个列表中的第二个单元元素

        myP=myBodyElements.item(1);

    }

</script>

</head>

<body onload="start()">

<p>hi</p>

<p>hello</p>

</body>

</html>

在这个例子中,我们设置变量myP指向DOM对象body中的第二个p元素:

  1. 首先,我们使用下面的代码获得所有的body元素的列表,因为在任何合法的HTML文档中都只有一个body元素,所以这个列表是只包含一个单元的。

2.  document.getElementsByTagName("body")
  1. 下一步,我们取得列表的第一个元素,它本身就会body元素对象。

4.  myBody=myDocumentElements.item(0);
  1. 然后,我们通过下面代码获得body的子元素中所有的p元素

6.  myBodyElements=myBody.getElementsByTagName("p");
  1. 最后,我们从列表中取第二个单元元素。

8.  myP=myBodyElements.item(1);

一旦你取得了HTML元素的DOM对象,你就可以设置它的属性了。比如,如果你希望设置背景色属性,你只需要添加:

myP.style.background="rgb(255,0,0)";

// 设置inline的背景色风格

当它要比下面的方法慢一些:

<div id=”adiv”><span
id=”innerspan”>span</span></div>
<script type=”text/javascript”>
var oldel=document.getElementById(“innerspan”);
var newel=document.createElement(“p”);
var text=document.createTextNode(“ppppp”);
newel.appendChild(text);
document.getElementById(“adiv”).replaceChild(newel, oldel);
</script>

使用document.createTextNode(..)创建文本节点

使用文档对象来调用一个createTextNode方法并创建你自己的文本节点。你只需要传递文字内容给这个函数。返回的值就是一个展示那个文本节点信息的对象。

myTextNode=document.createTextNode("world");

这表示你已经创建了一个TEXT——NODE(一个文字片断)类型的节点,并且它的内容是“world”,任何你对myTextNode的引用都指向这个节点对象。如果想将这个文本插入到HTML页面中,你还需要将它作为其他节点元素的子元素。

  1. 创建

  2. 创建

  3. 创建TextNode

5、insertBefore(newElement, targetElement)
给当前节点插入一个新节点,如果targetElement被设置为null,那新节点被当作最后一个子节点插入,否则那新节点应该被插入targetElement之前的最近位置。

使用appendChild(..)插入元素

那么,通过调用myP.appendChild([node_element])你可以将这个元素设置成为第二个P的一个新的子元素。

myP.appendChild(myTextNode);

在测试了这个例子之后,我们注意到,hello和world单词被组合在了一个:helloworld。事实上,当你看到HTML页面时,
hello和world两个文字节点看起来更像是一个节点。但是请记住它们在文档模型中的形式–是两个节点。第二个节点是一个TEXT_NODE类型的新节点,也是第二个P标签的第二个子元素。下面的图标将在文档树种展示最近创建的文本节点对象。

createTextNode 和 appendChild
是在单词hello和world之间设置空格的一个简单方法。另外一个重要的注意事项是:appendChild方法将把新的子节点接在最后一个子节点之后,正如world被加在了hello之后。所以如果你想在hello和world中间添加一个文本节点的话,你应该使用insertBefore来提到
appendChild.

插入到TBODY

复制代码 代码如下:

使用文档对象和createElement(..)方法创建新的元素

你可以使用createElement来创建新的HTML元素或者任何其它你想要的元素。比如,如果你想要创建一个新的P作为BODY的子元素,你可以使用前面例子的myBody并给它接上一个新的元素节点。使用
document.createElement(“tagname”)可以方便的创建一个节点。如下:

myNewPTAGnode=document.createElement("p");

myBody.appendChild(myNewPTAGnode);

<body>
<span id=”lovespan”>熊掌我所欲也!</span>
</body>
<script type=”text/javascript”>
var lovespan=document.getElementById(“lovespan”)
var newspan=document.createElement(“span”)
var newspanref=document.body.insertBefore(newspan, lovespan)
newspanref.innerHTML=”鱼与”;
</script>

使用removeChild(..)方法移除节点

每一个节点都可以被移除.下面的一行代码移除了包含在myP(第二个p元素)下面的文本节点world。

myP.removeChild(myTextNode);

最后你可以将myTextNode(那个包含了world单词的节点)添加给我们最后创建的P元素:

myNewPTAGnode.appendChild(myTextNode);

被修改的对象树的最后的状态如下:

插入到

6、click()
执行元素的一次点击,可以用于通过脚本来触发onClick函数

动态创建一个表格(回到Sample1.html)

这一段落的剩余部分我们将继续修改我们sample1.html。下面的图展示了我们在示例中创建的表格的对象树的结构。

  1. 将TextNode插入到

复制代码 代码如下:

创建元素节点并将他们插入到文档树中

sample1.html中创建表格的基本步骤是:

  • 获得body对象(文档对象的第一个元素)
  • 创建所有元素。
  • 最后,根据表格结构(上面图中所示)将每一个孩子节点拼接起来。下面的一段源码是经过修改的sample1.html

在start函数的最后,有一行新代码。使用另一个DOM方法(setAttribute)来设置表格的边界属性。setAttribute有两个参数:属性的名称和属性的值。你可以使用这个方法来设置任意元素的任意属性。

<head>

<title>示例代码 - 使用Javascript和DOM Interfaces来处理HTML</title>

<script>

    function start() {

        // 获得body的引用

        var mybody=document.getElementsByTagName("body").item(0);

        // 创建一个标签名称为TABLE的元素

        mytable = document.createElement("TABLE");

        // 创建一个标签名称为在TBODY的元素

        mytablebody = document.createElement("TBODY");

        // 创建所有的单元格

        for(j=0;j<2;j++) {

            // 创建一个标签名称为在TR的元素

            mycurrent_row=document.createElement("TR");

            for(i=0;i<2;i++) {

                // 创建一个标签名称为在TD的元素

                mycurrent_cell=document.createElement("TD");

                // 创建一个文字节点

                currenttext=document.createTextNode("cell is row "+j+", column "+i);

                // 将文字节点添加到TD单元格内

                mycurrent_cell.appendChild(currenttext);

                // 将TD单元格添加到TR行中

                mycurrent_row.appendChild(mycurrent_cell);

            }

            // 将TR行添加到TBODY中

            mytablebody.appendChild(mycurrent_row);

        }

        // 将TBODY添加到TABLE中

        mytable.appendChild(mytablebody);

        // 将TABLE添加到BODY中

        mybody.appendChild(mytable);

        // 设置边界属性为2

        mytable.setAttribute("border","2");

    }

</script>

</head>

<body onload="start()">

</body>

</html>

上面的四次测试使用的都是前一种方法。我们用后一种方法进行第5次测试。代码如下:

<script>
function wow() {
alert(“我好象没有点鼠标啊”);
}
</script>
<div id=”test” onclick=’wow()’>hhh</div>
<script type=”text/javascript”>
var div = document.getElementById(“test”);
div.click();
</script>

使用CSS和DOM来操作表格

View the fifth sample.

DOM Element的属性:(下面是常用的。IE5.0以上,mozllia都支持的)
1、childeNodes 返回所有子节点对象,
例如

从表格中获得一个文字节点

示例介绍了两个新的DOM属性。首先,使用childNodes属性来获得mycel的孩子节点列表。childNodes列表包括所有的孩子节点,无论它们的名称或类型是什么。像getElemengByTagName一样,它返回了一个节点列表。不同的是,
getElementByTagName只返回指定标签名称的元素。一旦你获得了返回的列表,你可以使用item(x)方法来使用指定的元素。这个例子在表格的第二行第二个单元格中的myceltext中保存了一个文字节点。然后,运行这个例子并观察结果,他创建了一个新的文字节点,这个文字节点的内容是
myceltext的值,并且将这个文字节点作为了BODY元素的一个孩子。

如果你的对象是一个文字节点,你可以使用data属性来回收(retrieve)节点的文字内容

mybody=document.getElementsByTagName("body").item(0);

mytable=mybody.getElementsByTagName("table").item(0);

mytablebody=mytable.getElementsByTagName("tbody").item(0);

myrow=mytablebody.getElementsByTagName("tr").item(1);

mycel=myrow.getElementsByTagName("td").item(1);

// mycel的孩子节点列表的第一个元素

myceltext=mycel.childNodes.item(0);

// currenttext的内容是myceltext的内容

currenttext=document.createTextNode(myceltext.data);

mybody.appendChild(currenttext);

Test5只需1649ms。这比上次测试提高了25%,比基线快了几乎30%。

复制代码 代码如下:

获得一个属性的值

在sample1的最后我们在mytable对象上调用了setAttribute。这个调用是用来设置表格的边界属性的。然后是用了getAttribute方法来获得一个属性的值:

mytable.getAttribute("border");

随后的修改是使用了预制的样式表。使用了预制样式表的表格列宽或者是通过

<table id=”mylist”>
<tr><td>一个和尚有水喝。</td></tr>
<tr><td>两个和尚挑水喝。</td></tr>
<tr><td>三个和尚没水喝。</td></tr>
</table>
<script>
var msg=””
var mylist=document.getElementById(“mylist”)
for (i=0; i<mylist.childNodes.length; i++){
var tr=mylist.childNodes[i];
for(j=0;j<tr.childNodes[j].length; j++) {
var td=tr.childNodes[j];
msg+=td.innerText;
}
}
alert(msg);
</script>

通过改变样式属性来隐藏一列

一旦你在你的javascript变量中保存了一个对象,你就可以直接为它设置样式属性了。下面的代码是修改后的sample1.html,在这里,第二列的每一个单元格都被隐藏了。而且第一列中的每一个单元格改为使用红色背景。注意,样式属性是被直接设置的。

<html>

<body onload="start()">

</body>

<script>

    function start() {

       var mybody=document.getElementsByTagName("body").item(0);

       mytable = document.createElement("TABLE");

       mytablebody = document.createElement("TBODY");

       for(j=0;j<2;j++) {

           mycurrent_row=document.createElement("TR");

           for(i=0;i<2;i++) {

               mycurrent_cell=document.createElement("TD");

               currenttext=document.createTextNode("cell is:"+i+j);

               mycurrent_cell.appendChild(currenttext);

               mycurrent_row.appendChild(mycurrent_cell);

               // 当column为0时,设置单元格背景色;column为1时隐藏单元格

               if(i==0) {

                   mycurrent_cell.style.background="rgb(255,0,0)";

               } else {

                   mycurrent_cell.style.display="none";

               }

           }

           mytablebody.appendChild(mycurrent_row);

       }

       mytable.appendChild(mytablebody);

       mybody.appendChild(mytable);

    }

</script>

</html>

版权声明:本文为博主原创文章,未经博主允许不得转载。


标签设置,没有

2、innerHTML
这是一个事实上的标准,不属于w3c
DOM,但是几乎所有支持DOM的浏览器,都支持这个属性。通过这个属性我们很容易修改一个元素的HTML。

标签时,每列的宽度均匀分布。因为不需要对每一列重新计算大小等,使用样式表实际上提高了性能,尤其当表格中的列数很多时。

复制代码 代码如下:

增加样式表的代码非常简单,如下:

<p><b>新人类,什么?!</b></p>
<script type=”text/javascript”>
window.onload=function(){
document.getElementsByTagName(“p”)[0].innerHTML=”<b>新新人类,什么?!</b>”
}
</script>

tbl.style.tableLayout = “fixed”;View the sixth sample.

3、style
返回一个元素的style对象的引用,通过它我们可以获得并修改每个单独的样式。
例如下面的脚本可以修改一个元素的背景色
document.getElementById(“test”).style.backgroundColor=”yellow”
4、firstChild 返回第一个子节点
5、lastChild 返回最后一个子节点
6、parentNode 返回父节点的对象。
7、nextSibling 返回下一个兄弟节点的对象
8、previousSibling 返回前一个兄弟节点的对象
9、nodeName 返回节点的HTML标记名称,使用英文的大写字母,如P, FONT
例如

因为我们测试中的表格只有一列,这种改变只提高了页面1.6%的性能。如果有更多的列,性能增加会更多。

复制代码 代码如下:

最后两次测试改变了将文字插入到表格中的方法。前面的测试中,我们都先创建一个TextNode
,然后将其插入到TD中。在Test7中, 取而代之,我们通过innerText
指定包含的文字。修改的代码是:

<div id=’test’>ddd</div>
<script>
if (document.getElementById(“test”).nodeName==”DIV”)
alert(“This is a DIV”);
</script>

td.innerText = “Text”;View the seventh sample.

第一个例子:
使用DOM1.0 的javascript动态地创建一个HTML table。

令人惊奇的是,这次修改产生的差异很大—-比上次提高了9%的性能,比最初总共提高了36%的性能。时间从最初的2323ms到最后的1473ms。

复制代码 代码如下:

现在,几乎人人都知道使用element.innerHTML 非常慢.
为了看看究竟它如何慢,我做了最后一次测试:使用
innerHTML替代innerText插入文字。这大大降低了性能。时间达到3375ms,比上次测试慢了80%,比基线测试慢了45%。显然,innerHTML是非常耗时的。

<head>
<title>Sample code </title>
<script>
function start() {
//获得body的引用
var mybody=document.getElementsByTagName(“body”).item(0);
//创建一个<table></table>元素
mytable = document.createElement(“TABLE”);
//创建一个<TBODY></TBODY>元素
mytablebody = document.createElement(“TBODY”);
// 创建行列
for(j=0;j<3;j++) {
//创建一个<TR></TR>元素
mycurrent_row=document.createElement(“TR”);
for(i=0;i<3;i++) {
//创建一个<TD></TD>元素
mycurrent_cell=document.createElement(“TD”);
//创建一个文本元素
currenttext=document.createTextNode(“cell is row “+j+”, column “+i);
//把新的文本元素添加到单元TD上
mycurrent_cell.appendChild(currenttext);
// appends the cell TD into the row TR
//把单元TD添加到行TR上
mycurrent_row.appendChild(mycurrent_cell);
}
//把行TR添加到TBODY上
mytablebody.appendChild(mycurrent_row);
}
// 把 TBODY 添加到 TABLE
mytable.appendChild(mytablebody);
// 把 TABLE 添加到 BODY
mybody.appendChild(mytable);
// 把mytable的border 属性设置为2
mytable.setAttribute(“border”,”2″);
}
</script>
</head>
<body onload=”start()”>
</body>
</html>

调整HTML页面性能类似于调整Win32应用程序性能;需要知道什么慢,什么快。希望这些方法能帮你提高页面性能。

首先,我们创建一个table元素
接着,创建一个TBODY元素,它应该是TABLE元素的子元素,
但是现在现在它们之间没有联系。
接着,使用一个循环创建TR元素,它们应该是TBODY元素的子元素。
对于每一个TR,我们使用一个循环创建TD元素,它们是TR的子元素。
对于每一个TD,我们创建一个文本节点元素
现在,我们创建好了这些TABLE, TBODY, TR,
TD还有文本元素,但是它们之间的层级
关系并没有建立起来。然后我们以上相反的顺序把每一个对象添加到它的父节点上。
mycurrent_cell.appendChild(currenttext);
mycurrent_row.appendChild(mycurrent_cell);
mytablebody.appendChild(mycurrent_row);
mytable.appendChild(mytablebody);
现在DOM层次如下:
BODY

TABLE

TBODY

TR——————-TR——————TR

TD—–TD—–TD TD—–TD—–TD TD—–TD—–TD

)
通过元素的ID访问元素,这是DOM一个基础的访问页面元素的方法,我们要经常用到它.
例如下面的例子,我们可以同DIV的…

网站地图xml地图