W3C建议符合标准的浏览器采用节点操纵(node manipulation)的方式支持网页,使页面表现得更像应用程序,而不是一般的静态页面。
今天学习了一些关于节点和DOM的知识;添加、删除和操作特定的节点;以及在页面上插入和替换节点。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Manipulating Nodes</title>
<script type="text/javascript" src="script01.js"></script>
</head>
<body>
<form action="#">
<p><textarea id="textArea" rows="5" cols="30"></textarea></p>
<p><label><input type="radio" name="nodeAction" />Add node</label>
<label><input type="radio" name="nodeAction" />Delete node</label>
<label><input type="radio" name="nodeAction" />Insert before node</label>
<label><input type="radio" name="nodeAction" />Replace node</label></p>
Paragraph #: <select id="grafCount"></select>
<input type="submit" value="Submit" />
</form>
<div id="modifiable"> </div>
</body>
</html>
用户可以在页面上添加、删除和替换任何文本
window.onload = initAll;
var nodeChgArea;
function initAll() {
document.getElementsByTagName("form")[0].onsubmit = nodeChanger;
nodeChgArea = document.getElementById("modifiable");
}
function addNode() {
var inText = document.getElementById("textArea").value;
var newText = document.createTextNode(inText);
//首先使用createTextNode方法创建一个新的文本节点
var newGraf = document.createElement("p");
newGraf.appendChild(newText);//将文本添加到新段落中
nodeChgArea.appendChild(newGraf);
}
function delNode() {
var grafChoice = document.getElementById("grafCount").selectedIndex;
var allGrafs = nodeChgArea.getElementsByTagName("p");//收集页面上所有段落标签
var oldGraf = allGrafs.item(grafChoice);
nodeChgArea.removeChild(oldGraf);
}
function insertNode() {
var grafChoice = document.getElementById("grafCount").selectedIndex;
var inText = document.getElementById("textArea").value;
var newText = document.createTextNode(inText);
var newGraf = document.createElement("p");
newGraf.appendChild(newText);
var allGrafs = nodeChgArea.getElementsByTagName("p");
var oldGraf = allGrafs.item(grafChoice);
nodeChgArea.insertBefore(newGraf,oldGraf);//新节点插入到这个节点前面
}
function replaceNode() {
var grafChoice = document.getElementById("grafCount").selectedIndex;
var inText = document.getElementById("textArea").value;
var newText = document.createTextNode(inText);
var newGraf = document.createElement("p");
newGraf.appendChild(newText);
var allGrafs = nodeChgArea.getElementsByTagName("p");
var oldGraf = allGrafs.item(grafChoice);
nodeChgArea.replaceChild(newGraf,oldGraf);
}
function nodeChanger() {
var actionType = -1;
var pGrafCt = nodeChgArea.getElementsByTagName("p").length;
var radioButtonSet = document.getElementsByTagName("form")[0].nodeAction;
for (var i=0; i<radioButtonSet.length; i++) {
if (radioButtonSet[i].checked) {
actionType = i;
}
}
switch(actionType) {
case 0:
addNode();
break;
case 1:
if (pGrafCt > 0) {
delNode();
break;
}
case 2:
if (pGrafCt > 0) {
insertNode();
break;
}
case 3:
if (pGrafCt > 0) {
replaceNode();
break
}
default:
alert("No valid action was chosen");
}
document.getElementById("grafCount").options.length = 0;
for (i=0; i<nodeChgArea.getElementsByTagName("p").length; i++) {
document.getElementById("grafCount").options[i] = new Option(i+1);
}
return false;
}
以上代码用对象字面值来编写,则表现为:
window.onload = initAll;
function initAll() {
document.getElementsByTagName("form")[0].onsubmit = nodeChanger;//进行初始化
chgNodes.init();
}
function nodeChanger() {
return chgNodes.doAction();
}
var chgNodes = {//chgNodes对象的开头
actionType : function() {
var radioButtonSet = document.getElementsByTagName("form")[0].nodeAction;
for (var i=0; i<radioButtonSet.length; i++) {
if (radioButtonSet[i].checked) {
return i;
}
}
return -1;
},
//actionType()是chgNodes的一个方法
allGrafs : function() {
return this.nodeChgArea.getElementsByTagName("p");
},
pGrafCt : function() {
return this.allGrafs().length;
},
inText : function() {
return document.getElementById("textArea").value;
},
newText : function() {
return document.createTextNode(this.inText());
},
grafChoice : function() {
return document.getElementById("grafCount").selectedIndex;
},
newGraf : function() {
var myNewGraf = document.createElement("p");
myNewGraf.appendChild(this.newText());
return myNewGraf;
},
oldGraf : function () {
return this.allGrafs().item(this.grafChoice());
},
doAction : function() {
switch(this.actionType()) {
case 0:
this.nodeChgArea.appendChild(this.newGraf());
break;
case 1:
if (this.pGrafCt() > 0) {
this.nodeChgArea.removeChild(this.oldGraf());
break;
}
case 2:
if (this.pGrafCt() > 0) {
this.nodeChgArea.insertBefore(this.newGraf(),this.oldGraf());
break;
}
case 3:
if (this.pGrafCt() > 0) {
this.nodeChgArea.replaceChild(this.newGraf(),this.oldGraf());
break;
}
default:
alert("No valid action was chosen");
}
document.getElementById("grafCount").options.length = 0;
for (var i=0; i<this.pGrafCt(); i++) {
document.getElementById("grafCount").options[i] = new Option(i+1);
}
return false;
},
//除了最后一个语句之外,每个语句都应该以逗号结尾(函数本质上是一个扩展的语句)
init : function() {
this.nodeChgArea = document.getElementById("modifiable");
}//init()函数的作用只是初始化nodeChgArea供以后使用,且这个例程的末尾不加逗号
}
使用对象字面值时要注意几点差异:
使用 :设置属性而不是 = 。
行以 ,结尾而不是 ;。
在对象中的最后一个语句上不需要逗号。
程序员为什么要使用对象字面值而不是过程式方法来编写JavaScript的原因如下:
首先,因为每个对象(包括方法和属性)都包含在一个父对象中,所以不会遇到无意间覆盖别人的代码问题。如果你在你和你的同事各自负责的.js文件中都有一个名为myText的变量,一些页面会加载这两个文件,那么页面后加载的文件优先——它会直接覆盖另一个变量,就像根本没有加载过原来的代码一样。解决方案是确保不使用全局变量,而实现这一点最简单的方法就是把所有代码都放在一个对象字面值中。
其次,对象字面值的一个子集被称为JavaScript Object Notation,简称为JSON。JSON是Ajax中最常用的数据格式之一,因此在使用Ajax时经常会遇到这种格式。
最后,与所有东西一样,编程语言的风格也在随着潮流变化。JavaScript本身正在经历第二次飞跃,业界重新唤起了对脚本编程的兴趣。当前的潮流倾向于使用对象字面值,所以用对象字面值编写的代码会越来越多。
(源《JavaScript基础教程》)