JavaScript DOM学习第一章 W3C DOM简介


Posted in Javascript onFebruary 19, 2010

在这一章我主要介绍已经被新一代的浏览器所支持的W3C 第一级的DOM。对他的运作做一个大概的了解并且让你知道你可以对他们做什么。
首先是对于DOM的一些建议和DOM设计的目的,然后我会告诉你什么是节点(nodes)并且怎样通过DOM树来遍历节点。接着是如何得到一个特定的节点,以及怎样改变他的值和属性。最后就是DOM的终极目标:怎么创建一个自己的新节点。
建议
Level 1DOM是W3C制定的用来提供给任何程序语言来访问XML文档的。不管你用什么语言程序来处理XML文档,只要是Level 1DOM里面的方法和属性就可以。不管是Perl、VBScript还是JavaScript你都可以读取任何你想读取的值并且修改他们。
你们可能会猜到,这段描述的是一种理想情况,差异还是存在的(比如浏览器)。然后这部分内容还是比较少,并且你在JavaScript里学习如何处理XML也对你在其它语言中的学习会有一定的帮助。
从某种程度上也可以讲HTML看做是一种XML文档。只要浏览器能够处理相应的脚本,那么Level 1 DOM也同样在HTML里面可以运行的很好。
你可以读取每一个HTML的标签的文本和属性,你可以删除每一个标签和他们的内容,你还可以实时的在现有的文档里面插入一个新的标签而不用在服务器上修改。
因为设计之初要考虑到修改XML的方方面面,所以对于一般的网页工程师来说有一些方法可能永远也用不上。比如,你可以用它来修改HTML的注释,但是我没有看出来问什么要这样做。同样的还有一些DOM处理DTD/Doctype的内容,你在你的网页设计中并不需要,所以忽略掉,集中注意力在你的日常所需上就好。
节点(Nodes)
文档对象模型是一种文档内的多个元素之间怎样相互联系的一种模型。在Level 1 DOM中,每一个对象都是一个节点。所以如果你写:

<p>This is a paragraph</p>

那么你就创建了两个节点:元素P和内容是"This is a paragraph”的文本节点。这个文本节点包含在P元素内,所以可以认为是p节点的子节点。反过来说,p元素就是文本节点的父节点。
如果你写成:
<p>This is a <B>Paragraph</B></p>

那么元素节点p就有两个子节点,其中一个还有他自己的子节点。
最后就是参数节点。(令人困惑的是,他们不算做元素节点的子节点。事实上,在我写这一章的过程中我做过一些测试,IE5根本就不把参数节点当做元素的子节点。)所以:
<P ALIGN="right">This is a <B>paragraph</B></P>

的结构可能是这样的:

<P> ----------------     --------------     ALIGN
  This is a     <B>     |
            |    right
          paragraph

这就是元素节点,文本节点和参数节点。99%的HTML页面都是由他们组成,你的主要任务也就是如何放置他们。当然还有很多的其他节点,暂且略过。

就像你所了解的,p元素也有他自己的父节点,通常就是document,有时候也可能是一个DIV。所以整个文档都可以看做是一颗由很多的节点组成的树,而且这些节点大多都有自己的子节点。

<BODY>        |-------------------------------------
       <P> ----------------      lots more nodes
     --------------     ALIGN
  This is a     <B>     |
            |    right
          paragraph

遍历DOM树
知道了DOM树的结构,你就可以遍历他来找到你想要的元素。举个例子,假设元素节点p已经存储在变量x中(等一会介绍这是怎么做到的)。这时候如果我们想访问BODY那么:
x.parentNode

我们就得到了x的父元素,然后就可以修改它了。这样可以到达B节点:
x.childNode[1]

childNode是一个包含所有x的子节点的数组。当然,数组是从0开始编号的,所以childNode[0]就是文本节点"This is a " childNode[1]就是B节点。
两个特别的:x.firstChild就表示x的第一个子节点;x.lastChild就表示x的最后一个子节点。
假设p是BODY的第一个子节点,BODY又是document的第一个子节点,所以为了到达B节点,你可以用下面的任意方法:
document.firstChild.firstChild.lastChild; 
document.firstChild.childNodes[0].lastChild; 
document.firstChild.childNodes[0].childNodes[1];

甚至是下面这个比较笨的:
document.firstChild.childNodes[0].parentNode.firstChild.childNodes[1];

得到一个元素
然而,这样遍历文档实在是太麻烦了。因为Level 1 DOM设计的目标就是允许你修改整个DOM树,所以你必须准确的知道DOM树的结构,这会很快导致一些问题。
所以还有一些方法能够很快的到达你想要的元素。只要你到达了这里,就可以遍历整个DOM树的每一个节点。
让我们继续前面的例子。你想要到达元素B。最简单的办法就是直接跳过去。通过document.getElementByTagName你就能很快的创建一个包含文档内的所有B标签的数组。假设我们的B是第一个,那么你就可以简单的写:
var x = document.getElementsByTagName('B')[0]

x就包含了元素节点B。首先你命令浏览器得到整个文档的所有元素B(document.getElementByTagName(‘B')) ,然后你选择了第一个文档的第一个元素B([0]),就得到了你想要的。
你也可以写:
var x = document.getElementsByTagName('P')[0].lastChild;

现在你先到了文档的第一个段落P(假设我们的P是第一个元素),然后到达p的最后一个子元素。
最好的能准确到达元素并且不需要DOM结构的办法就是给B一个ID:
<P ALIGN="right">This is a <B ID="hereweare">paragraph</B></P>现在你就可以简单的写:
var x = document.getElementById('hereweare');

元素B就存储在了x里。
修改一个节点
现在我们已经到达了节点,就可以做一些修改了。假设我们想把加粗的文字部分修改为'bold bit of text'。我们需要访问正确的元素然后修改它的nodeValue。现在正确的元素不是元素B而是他的子元素text node:我们想改变的是文字,不是元素。所以可以写:
document.getElementById('hereweare').firstChild.nodeValue='bold bit of text';

元素就改变了。
你可以通过nodeValue来修改任何文本节点或者参数。比如你可以修改段落的ALIGN参数。这也是非常的简单,先找到需要的元素(在这个例子中是B元素的父元素),然后使用setAttribute()方法来设置你想要的值:
function test2(val) { 
if (document.getElementById && document.createElement) 
{ 
node = document.getElementById('hereweare').parentNode; 
node.setAttribute('align',val); 
} 
else alert('Your browser doesn\'t support the Level 1 DOM'); 
}

创建和删除元素
修改元素固然有用,但是还是不如创建你需要的元素然后插入到现有的文档中。我可以很简单的在这个段落后面添加一个HR元素然后很简单的删除它。
创建元素使用下面的方法:
var x=document.createElemnt(‘HR')
这样HR就创建并且存储在x中。第二步就是把x插入到文档之中。我写了一个ID是inserthere的SPAN,我们就把它插入到这。所以我们使用appendChild()方法:
document.getElementById('inserthrhere').appendChild(x);

删除它稍稍有点麻烦。我先创建一个临时变量node来存储SPAN,然后我告诉他移除他的第一个子元素:
var node=document.getElementById(‘inserthere'); 
node.removeChild(node.childNode[0]);

同样的方法我们也可以创建一个新的元素然后添加在ID是hereweare的B元素上。

var x = document.createTextNode(' A new text node has been appended!'); 
document.getElementById('hereweare').appendChild(x);

你可以试一试,你会注意到用老的办法可能不会移除新加的文本,那是因为他们已经成为分离的两部分了:
<B> ------------
 paragraph A new text node
 has been appended!

(可以通过normalize()来把他们合并,但是IE5不支持)

我不打算告诉你怎么移除它,自己练习会比较有收获

翻译地址:http://www.quirksmode.org/dom/intro.html

转载请保留以下信息
作者:北玉(tw:@rehawk)

Javascript 相关文章推荐
js 获取和设置css3 属性值的实现方法
May 06 Javascript
JS+CSS设置img在DIV中只显示Img垂直居中的部分
Oct 24 Javascript
屏蔽script注入小例子
Nov 12 Javascript
jquery.post用法之type设置问题
Feb 24 Javascript
iframe窗口高度自适应的又一个巧妙实现思路
Apr 04 Javascript
JavaScript使用DeviceOne开发实战(四)仿优酷视频应用
Dec 02 Javascript
JavaScript学习笔记之ES6数组方法
Mar 25 Javascript
JavaScript中正则表达式使数字、中文或指定字符高亮显示
Oct 31 Javascript
vue+SSM实现验证码功能
Dec 07 Javascript
详解Webpack抽离第三方类库以及common解决方案
Mar 30 Javascript
js实现翻牌小游戏
Jul 31 Javascript
javascript代码实现简易计算器
Jan 25 Javascript
JavaScript 题型问答有答案参考
Feb 17 #Javascript
JavaScript 学习技巧
Feb 17 #Javascript
JavaScript Timer实现代码
Feb 17 #Javascript
两个比较有用的Javascript工具函数代码
Feb 17 #Javascript
类似GMAIL的Ajax信息反馈显示
Feb 16 #Javascript
JavaScript 10件让人费解的事情
Feb 15 #Javascript
JQuery 动画卷页 返回顶部 动画特效(兼容Chrome)
Feb 15 #Javascript
You might like
PHP ajax 异步执行不等待执行结果的处理方法
2015/05/27 PHP
thinkPHP框架乐观锁和悲观锁实例分析
2019/10/30 PHP
PhpStorm+xdebug+postman调试技巧分享
2020/09/15 PHP
使Ext的Template可以解析二层的json数据的方法
2007/12/22 Javascript
JavaScript 读取元素的CSS信息的代码
2010/02/07 Javascript
js nextSibling属性和previousSibling属性概述及使用注意
2013/02/16 Javascript
JavaScript使用键盘输入控制实现数字验证功能
2016/08/19 Javascript
JavaScript实现网页头部进度条刷新
2017/04/16 Javascript
vue实现一个移动端屏蔽滑动的遮罩层实例
2017/06/08 Javascript
js链表操作(实例讲解)
2017/08/29 Javascript
JS运动特效之同时运动实现方法分析
2018/01/24 Javascript
使用Vuex实现一个笔记应用的方法
2018/03/13 Javascript
详解Axios 如何取消已发送的请求
2018/10/20 Javascript
微信开发之微信jssdk录音功能开发示例
2018/10/22 Javascript
Vue+Element UI+vue-quill-editor富文本编辑器及插入图片自定义
2019/08/20 Javascript
Node.js中文件系统fs模块的使用及常用接口
2020/03/06 Javascript
关于vue属性使用和不使用冒号的区别说明
2020/10/22 Javascript
通过vue.extend实现消息提示弹框的方法记录
2021/01/07 Vue.js
[02:15]2014DOTA2国际邀请赛 赛后退役选手回顾
2014/08/01 DOTA
[00:48]DOTA2国际邀请赛公开赛报名开始 扫码开启逐梦之旅
2018/06/06 DOTA
Python网络爬虫出现乱码问题的解决方法
2017/01/05 Python
Python3实现计算两个数组的交集算法示例
2019/04/03 Python
Python3实现二叉树的最大深度
2019/09/30 Python
django filter过滤器实现显示某个类型指定字段不同值方式
2020/07/16 Python
Python爬虫之Selenium中frame/iframe表单嵌套页面
2020/12/04 Python
使用CSS3实现多列布局与多背景的技巧
2016/02/29 HTML / CSS
详解CSS3中字体平滑处理和抗锯齿渲染
2017/03/29 HTML / CSS
canvas像素画板的实现代码
2018/11/21 HTML / CSS
数控专业毕业生求职信范文
2013/09/21 职场文书
学校万圣节活动方案
2014/02/13 职场文书
仓库文员岗位职责
2014/04/06 职场文书
标准毕业生自荐信
2014/06/24 职场文书
护士工作失误检讨书
2014/09/14 职场文书
群众路线个人对照检查材料
2014/09/23 职场文书
2015年节能降耗工作总结
2015/05/22 职场文书
Mybatis-plus在项目中的简单应用
2021/07/01 Java/Android