Javascript高级程序设计(一)DOM和BOM之DOM篇

一个完整的JavaScript实现应该由下列三个不同的部分组成:

(1)核心(ECMAScript)
(2)文档对象模型(DOM)
(3)浏览器对象模型(BOM)

(一)DOM(Document Object Model)

1.DOM概念

(1)文本对象模型,是针对XML,HTML的应用程序编程接口。
(2)DOM把整个页面映射成一个多层节点结构。也就是树状结构。
(3)借助DOM提供的接口,可以轻松的删除,添加,替换和修改任何节点。
(4)在 DOM中 , 每一个元素都是节点。

整个文档是一个文档节点。
每个 HTML 标签是一个元素节点
包含在 HTML 元素中的文本是文本节点
每一个 HTML 属性是一个属性节点
注释属于注释节点

JavaScript中的所有节点类型都继承自Node类型,因此所有节点类型都共享着相同的基本属性和方法。
每个节点都有一个nodeType属性,用于表明节点的类型。

常见节点类型:
常见节点类型
nodeName和nodeValue属性

要了解节点的具体信息,可以使用这两个属性,不过这两个属性的值取决于节点的类型


nodeName和nodeValue属性
关系节点
  • childNodes

每个节点都有一个childNodes属性,保存着一个NodeList对象,是一种类数组对象,保存着一组子节点,并且length属性,特点是可以基于DOM结构动态执行查询的结果,因此DOM结构的变化能够自动反映在NodeList对象中

注意:节点的childNodes包含了节点内的所有节点类型(不包括属性节点),而且标签内的换行和空格都会被当成一个文本包含在childNodes属性中
  • parentNode

每个节点都有一个parentNode属性,该属性指向文档树种的父节点,因此,包含在childNodes列表中的所有节点都有相同的父节点,他们的parentNode属性都指向同一个节点

  • previousSibling 和nextSibling属性

childNodes列表中的每个元素节点相互之间都是同胞节点,可以通过每个节点的previousSibling和nextSibling属性访问同一列表的其他节点

  • firstChild 和lastChild属性

在父节点下使用这两个属性可以分别获取childNodes列表下的第一个和最后一个节点.为部分需求操作提供的极大的便利

  • hasChildNodes()

这个方法非常简单实用,在节点包含一或多个子节点的情况下返回true,而无需查询childNodes的length大小来判断

  • ownerDocument

所有节点都有的最后一个属性是ownerDocument,该属性指向整个文档的文档节点,不用层层回溯到顶端
举例:

<!DOCTYPE html>
<html>
<body>

<p id="demo">请点击按钮来获得 <p> 元素的 ownerDocument 的节点类型。</p>

<button onclick="myFunction()">试一下</button>

<script>
function myFunction()
{
var x=document.getElementById("demo");  
x.innerHTML=x.ownerDocument.nodeType;//9
}
</script>

</body>
</html>
注意:firstChild,lastChild,nextSibling,previousSibling都会将空格或者换行当做节点处理,(除IE)

所以为了准确地找到相应的元素(其他浏览器)
firstElementChild,
lastElementChild,
nextElementSibling,
previousElementSibling

浏览器兼容:var test = div1.nextElementSibling || div1.nextSibling;
操作节点
  • appendChild(新增的节点)
    接收一个新增节点作为参数 ,用于向childNodes列表的末尾添加一个节点,并返回新增的节点

  • insertBefore(要插入的节点,作为参照的节点)
    插入节点后,被插入的节点会变成参照节点的前一个同胞节点,同时被方法返回,如果参照节点是null,那么insertBefore()和appendChild()是等同的

  • replaceChild(要插入的节点,要替换的节点)
    要替换的节点将由这个方法返回并从文档树种移除,同时由要插入的节点占据其位置

  • removeChild(要删除的子节点)
    这个方法接收一个参数,即要移除的节点,并且被方法返回

    前面介绍的四个操作方法操作的都是某个节点的子节点,要使用必须先取得父节点

其他方法(所有类型节点都有)
  • cloneNode(布尔值)
    用于创建调用这个方法的节点的一个完全相同的副本,插入布尔值为true则表示深度复制,复制节点和其整个节点树,否则为浅复制 ,只复制节点本身,复制后返回的节点文本属于文档所有,但成为一个"孤儿",需要添加到文档树中
    注意:cloneNode()方法不会复制添加到DOM节点中的Javascript属性或者事件处理程序等

  • normalize()
    处理文档树中的文本节点,如果在节点的后代节点中找到空文本节点,则删除它,如果找到相邻的文本节点,则将它们合并为一个文本节点

<!DOCTYPE html>
<html>
<body>

<p id="demo">点击按钮添加文本,点击另一个按钮来正规化元素。</p>

<button onclick="addTextNode()">添加文本节点</button>

<button onclick="normPara()">对段落进行正规化</button>

<script>
function addTextNode()
{
var y=document.createTextNode("请再次点击。");
var x=document.getElementById("demo");
x.appendChild(y);
var z=document.getElementById("cc");
z.innerHTML=x.childNodes.length;
}

function normPara()
{
var x=document.getElementById("demo");  
x.normalize();
var z=document.getElementById("cc");
z.innerHTML=x.childNodes.length;
}
</script>

<p>上面的段落有 <span id="cc">1</span> 个子节点。</p>

</body>
</html>
举例

HTML的DOM树节点包括:

  1. 元素节点:上图中<html>、<body>、<p>都是元素节点即标签

  2. 文本节点:向用户展示的内容,如<li>...</li>中的javascript、Dom、CSS等文本。

  3. 属性节点:元素属性,如<a>标签的链接属性

Document对象:

当浏览器载入 HTML 文档, 它就会成为 document 对象。

Document 对象是HTML文档的根节点与所有其他节点(元素节点,文本节点,属性节点, 注释节点)。

Document 对象使我们可以从脚本中对 HTML 页面中的所有元素进行访问。

总结:
(1)Document 对象是 Window 对象的属性,可通过 window.document 属性对其进行访问。
(2)Javascript是通过Document类型表示文档,在浏览器中document对象是HTMLDocument的一个实例,表示整个页面,而且document对象也是window对象的一个属性,因此可以作为全局对象来访问

从document节点中取得页面标签
  • document.documentElement指向HTML页面中的<html>元素
  • document.body指向<body>元素
  • document.doctype可以取得对<!DOCTYPE>的引用
  • document.title 包含<title>元素中的文本
从document节点中取得页面的请求信息
  • document.URL为地址栏中显示的URL
  • document.domain为页面的域名
    -document.referrer为连接到当前页面的那个页面的URL
从document节点中查找元素
  • document.getElementById("mydiv")
  • document.getElementsByTagName("img"),返回一个HTMLCollection对象,和NodeList对象类似,并且拥有一个方法namedItem()可以传入元素的name特征来取得集合中的项,可以通过document.getElementsByTagName("*")获取全部元素
  • document.getElementsByClassName("class"):获取类名相同的元素,Internet Explorer 8 及更早 IE 版本不支持 getElementsByClassName() 方法
  • document.getElementsByName():这个方法会返回有给定name特征的所有元素,通常用来获取单选按钮.
  • document.anchors:包含文档中所有带name特性的a元素
  • document.forms:包含文档中所有的form元素
  • document.images:包含文档中所有的img元素
  • document.links:包含文档中所有带有href特性的a元素
文档写入
  • document.write(写入字符串):将输出流写入到网页
  • document.writeln(写入字符串):将输出流写入到网页并换行
    注意:必要时候要加转义字符\
  • document.open()和document.close()分别用于打开和关闭网页的输出流,如果是在页面加载期间使用write()或writeln()方法,则不需要用到这两个方法,调用write或writeln方法时和结束时,浏览器会隐式调用这两个方法

Element类型

判断元素标签的最佳实践:
if(element.tagName.toLowerCase() == "div"){ //在此执行某些操作 }

HTML元素

每个HTML元素都有下列标准特性:

获取和修改特性
  • getAttribute(特性名称attributename)
    参数:需要获得的属性值的属性名称;
    不仅可以取得节点的默认特性也可以取得自定义特性(根据HTML5规范,自定义属性应该加上data-前缀以便验证),返回对应特性值
    注意:传入style特性后返回的是包含的CSS文本,而通过属性来访问style则返回一个对象,因为一系列的问题原因,平时开发只使用对象的属性来获取特性,而只有在取得自定义特性值的情况下,才会使用getAttribute()方法

  • setAttribute(特性名称,特性值)
    如果特性存在,则用特性值进行修改,若不存在,则新建特性并赋予特性值,该方法不仅可以操作HTML特性也可以操作自定义特性,而使用对象属性设置的自定义特性则不会自动成为元素的特性

  • removeAttribute(要删除的特性名称)
    这个方法用于彻底删除元素的特性,不仅清除特性的值也会从元素中完全删除特性

attributes属性

Element类型是使用attributes属性的唯一一个DOM节点类型,elment.attributes实质是该元素节点的所有属性节点的结合,称为NamedNodeMap,并且拥有它自己的特殊方法:

  • getNamedItem(name) 返回nodeName属性等于name的节点,即返回属性名对应的属性节点
  • removeNamedItem(name):删除该属性节点
  • setNamedItem(node) :向列表中添加属性节点,以nodeName为索引
    item(po): 返回位于数字Pos位置处的节点
创建元素
  • document.createElement(元素标签名)
    该方法可以传入完整的元素标签如
    var div = document.createElement("div id="myNewDiv" class = "box"></div>");
    注意:这种形式创建的动态元素有很多已知的问题,若要创建一些跟别的元素或者存在相关事件处理的元素,不推荐用这种方法,如iframe标签 input标签 有name相同的单选按钮等
元素的子节点

从上面就可以发现,用元素节点的childNodes遍历其子元素节点会出现一些换行和空格等形成了文本节点的问题,这意味着在执行某项操作之前,都要检查一下nodeType属性,如:

for(var i = 0,len=element.childNodes.length;i<len;i++){
 if(element.childNodes[i].nodeType == 1){ 
//执行某些操作 
} }

Text类型

  • nodeValue和data属性:均可以用来访问Text节点包含的文本
  • appendData(text)
  • deleteData(offset,count)
  • insertData(offset,text)
  • replaceData(offset,count,text)使用指定文本来替换此节点以及所有相邻的文本节点,W3C标准,浏览器不支持
  • splitText(offset)
  • (offset,count)从节点提取数据
    length属性返回文本字符的数目
创建文本节点

document.createTextNode(要插入节点中的文本)
作为参数的文本将按照HTML或XML的格式进行编码

规范化文本节点

normalize()方法

分割文本节点

与normalize()方法相反的splitText(pos)方法,将一个文本节点分成两个文本节点

DocumentFragment类型

在所有的节点类型中,只有DocumentFragment在文档中没有对应的标记,DOM规范规定文档片段是一种"轻量级"的文档,可以包含和控制节点.虽然不能把文档片段直接添加到文档中,但可以将它作为一个"仓库"来使用,即可以在里面保存将来可能添加到文档中的节点

创建文档片段

使用document.createDocumentFragment(),返回一个文档片段对象,继承了Node的所有方法,可以往里面堆积节点,然后一次性添加到文档树中,减低浏览器的渲染次数

Attr类型
不常单独使用,不过多描述

Comment类型 ,CDATASection类型 ,DocumentType类型
不常单独使用,不过多描述

2.DOM级别

2.1 DOM1级

DOM1级由两个模块组成,DOM核心(DOM Core)和DOM HTML。
DOM核心规定的是如何映射基于XML的文档结构,以便简化堆文档中任意部分的访问和操作。
DOM HTML模块则在DOM核心的基础上加以扩展,添加了针对HTML的对象和方法。

2.2 DOM2级

DOM2级在原来的DOM基础上又扩充了鼠标和用户界面事件,范围,遍历(迭代DOM文档的方法)等模块,而且通过对象接口增加了对CSS的支持

DOM视图(DOM Views):定义了跟踪不同文档视图的接口。
DOM事件:描述事件接口;
DOM样式:描述处理基于CSS样式的接口;
DOM遍历与范围:描述遍历和操作文档树的接口;
2.3DOM3级
进一步扩展了DOM,引入了以统一方式加载和保存文档的方法-在DOM加载和保存(DOMLoad and Save)模板中定义
新增了验证文档的方法-在DOM验证(DOM Validation)模板中定义。
DOM3级也对DOM核心进行了扩展,开始支持XML1.0规范,涉及XML Infoset,XPath和XML Base。
注意:DOM0级标准是不存在的,所谓的DOM0级只是DOM历史坐标中的一个参照点。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容