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 相关文章推荐
jQuery结合Json提交数据到Webservice,并接收从Webservice返回的Json数据
Feb 18 Javascript
用于deeplink的js方法(判断手机是否安装app)
Apr 02 Javascript
js密码强度检测
Jan 07 Javascript
通过node-mysql搭建Windows+Node.js+MySQL环境的教程
Mar 01 Javascript
Bootstrap表单Form全面解析
Jun 13 Javascript
AngularJS中实现动画效果的方法
Jul 28 Javascript
详解Bootstrap的iCheck插件checkbox和radio
Aug 24 Javascript
理解 Node.js 事件驱动机制的原理
Aug 16 Javascript
10分钟上手vue-cli 3.0 入门介绍
Apr 04 Javascript
js简单的分页器插件代码实例
Sep 11 Javascript
基于VSCode调试网页JavaScript代码过程详解
Jul 20 Javascript
解决vue组件销毁之后计时器继续执行的问题
Jul 21 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 八种基本的数据类型小结
2011/06/01 PHP
解析PHP多种序列化与反序列化的方法
2013/06/06 PHP
php使用pack处理二进制文件的方法
2014/07/03 PHP
PHP实现适用于自定义的验证码类
2016/06/15 PHP
php事件驱动化设计详解
2016/11/10 PHP
php中输出json对象的值(实现方法)
2018/03/07 PHP
用Laravel轻松处理千万级数据的方法实现
2020/12/25 PHP
php慢查询日志和错误日志使用详解
2021/02/27 PHP
求数组最大最小值方法适用于任何数组
2013/08/16 Javascript
jquery配合css简单实现返回顶部效果
2013/09/30 Javascript
用jquery实现动画跳到顶部和底部(这个比较简单)
2014/09/01 Javascript
详谈javascript中DOM的基本属性
2015/02/26 Javascript
jQuery实现滚动鼠标放大缩小图片的方法(附demo源码下载)
2016/03/05 Javascript
javascript iframe跨域详解
2016/10/26 Javascript
react.js 翻页插件实例代码
2017/01/19 Javascript
ES6 Class中实现私有属性的一些方法总结
2019/07/08 Javascript
解决React在安装antd之后出现的Can't resolve './locale'问题(推荐)
2020/05/03 Javascript
[05:04]完美世界携手游戏风云打造 卡尔工作室地图界面篇
2013/04/23 DOTA
Python 字典与字符串的互转实例
2017/01/13 Python
python检测主机的连通性并记录到文件的实例
2018/06/21 Python
python输入多行字符串的方法总结
2019/07/02 Python
python根据多个文件名批量查找文件
2019/08/13 Python
使用Pandas将inf, nan转化成特定的值
2019/12/19 Python
浅谈spring boot 集成 log4j 解决与logback冲突的问题
2020/02/20 Python
Python 解决火狐浏览器不弹出下载框直接下载的问题
2020/03/09 Python
Python 如何实现访问者模式
2020/07/28 Python
Python3 ffmpeg视频转换工具使用方法解析
2020/08/10 Python
详解python爬取弹幕与数据分析
2020/11/14 Python
Python Pygame实现俄罗斯方块
2021/02/19 Python
输入N,打印N*N矩阵
2012/02/20 面试题
董事长秘书工作职责
2014/06/10 职场文书
化工生产实习心得体会
2016/01/22 职场文书
pycharm debug 断点调试心得分享
2021/04/16 Python
阿里云服务器搭建Php+Apache运行环境的详细过程
2021/05/15 PHP
CSS3实现列表无限滚动/轮播效果
2021/06/23 HTML / CSS
Node实现搜索框进行模糊查询
2021/06/28 Javascript