DOM是针对HTML和XML文档的一个API(应用程序编程接口),DOM描绘了一个层次化的节点树,允许开发人员添加,移除,修改页面的某一部分。1998年10月DOM1级规范成为W3C的推荐标准,为基本的文档结构以及查询提供了接口。但是要注意,IE中的所有DOM对象都是以COM对象的形式实现的。这意味着IE中的DOM对象与原生JavaScript对象的行为或活动特点并不一致。
DOM可以将任何HTML或XML文档描绘成一个由多层节点构成的结构。节点分为几种不同的类型,每种类型分别表示文档中不同的信息或标记。每个节点拥有各自的特点,数据和方法,另外也有与其他节点存在某种关系。节点之间的关系构成了层次,所有页面标记则表现为一个以特定节点为根节点的树形结构。
1) Node类型
DOM1级定义为一个Node接口,该接口将由DOM中的所有节点类型实现。除了IE之外,在其他所有浏览器中都可以访问到这个类型。javascript中所有的节点类型都继承自Node类型,所有节点类型都共享着相同的基本属性和方法。
1. 节点关系
属性:
nodeType
表示节点类型
Element 1;TextNode 3;Comment[注释] 8;Document 9
document 是Document构造函数的实例 9
document.body是Element构造函数的实例 1
document.body.firstChild 是Comment构造函数的实例
nodeName[默认大写]
该属性取决于节点类型,如果是元素类型,值为元素的标签名
nodeValue
该属性取决于节点类型,如果是元素类型,值有null
childNodes
属性,保存一个NodeList对象,NodeList是一种类数组对象用来保存一组有序的节点,NodeList是基于DOM结构动态执行查询的结果,DOM结构变化可以自动反应到NodeList对象中。访问时可以通过 [ ] 中括号访问,也可以通过item()方法访问。可以使用slice方法将NodeList转换为数组
var arr = Array.prototype.slice.call(nodes,0);
parentNode 父亲
指向文档树中的父节点。包含在childNodes列表中所有的节点都具有相同的父节点,每个节点之间都是同胞/兄弟节点。
previousSibling 哥哥/姐姐
兄弟节点中的前一个节点
nextSibling 弟弟/妹妹
兄弟节点中的下一个节点
firstChild
childNodes列表中的第一个节点
lastChild
childNodes列表中的最后一个节点
ownerDocument
指向表示整个文档的文档节点。任何节点都属于它所在的文档,任何节点都不能同时存在于两个或更多个文档中。
方法:
hasChildNodes() 检测是否有孩子节点
在包含一个或多个子节点的情况下返回true
2. 操作节点
以下四个方法都需要父节点对象进行调用!
appendChild()
向childNodes列表末尾添加一个节点。返回新增的节点。关系更新如果参数节点已经为文档的一部分,位置更新而不插入,dom树可以看做是由一系列的指针连接起来的,任何DOM节点不能同时出现在文档中的多个位置。
insertBefore()
第一个参数:要插入的节点;
第二个参数:作为参照的节点;
被插入的节点会变成参照节点的前一个同胞节点,同时被方法返回。如果第二个参数为null将会将该节点追加在NodeList后面
replaceChild()
第一个参数:要插入的节点;
第二个参数:要替换的节点;
要替换的节点将由这个方法返回并从文档树中被移除,同时由要插入的节点占据其位置。
removeChild()
一个参数,即要移除的节点。
移除的节点将作为方法的返回值。
其他方法,任何节点对象都可以调用。
其他方法
cloneNode()
用于创建调用这个方法的节点的一个完全相同的副本。有一个参数为布尔类型参数为true时,表示深复制,即复制节点以及整个子节点数。参数为false的时候,表示浅复制,只复制节点本身。该方法不会复制添加到DOM节点中的JavaScript属性,例如事件处理程序等。该方法只复制特定,子节点,其他一切都不复制。但是IE中可以复制,建议标准相同,在复制之前,移除所有事件处理程序。
normalize()
处理文档树中的文本节点,由于解析器的实现或DOM操作等原因,可能会出现文本节点不包含文本,或者接连出现两个文本节点,当在某个节点上调用了该方法,会删除空白节点,会找到相邻的两个文本节点,并将他们合并为一个文本节点。
2) Document类型
javascript通过使用Document类型表示文档。在浏览器中,document对象是HTMLDocument的一个实例,表示整个HTML页面。document对象是window对象的一个属性,因此可以直接调用。HTMLDocument继承自Document
1. 文档子节点
可以继承Node中所有的属性和方法
属性:
documentElement 始终指向HTML页面中的<html>元素。
body 直接指向<body>元素
doctype 访问<!DOCTYPE>, 浏览器支持不一致,很少使用
title 获取文档的标题
URL 取得完整的URL
domain 取得域名,并且可以进行设置,在跨域访问中经常会用到。
referrer 取得链接到当前页面的那个页面的URL,即来源页面的URL
images 获取所有的img对象,返回HTMLCollection类数组对象
forms 获取所有的form对象,返回HTMLCollection类数组对象
links 获取文档中所有带href属性的<a>元素
2. 查找元素
getElementById()
参数为要取得元素的ID,如果找到返回该元素,否则返回null如果页面中多个元素的ID值相同,只返回文档中第一次出现的元素。如果某个表单元素的name值等于指定的ID,该元素也会被匹配。
getElementsByTagName()
参数为要取得元素的标签名,返回包含另个或者多个元素的NodeList,在HTML文档中该方法返回的是HTMLCollection对象,与NodeList非常类似。可以通过[index/name],item(),namedItem(name)访问
【HTML5 中出现】
getElementsByName()
参数为元素的name,返回符合条件的HTMLCollection
getElementsByClassName()
参数为一个字符串,可以由多个空格隔开的标识符组成。当元素的class属性值包含所有指定的标识符时才匹配。HTML元素的class属性值是一个以空格隔开的列表,可以为空或包含多个标识符。
3) Element类型
1. HTML元素
所有的HTML元素都由HTMLElement类型表示,或者其子类型表示。每个HTML元素都应具有如下一些属性以及html元素特有的属性。
id 元素在文档中的唯一标识符
title 有关元素的附加说明信息
className 与元素class特性对应
src img元素具有的属性
alt img元素具有的属性
lang 元素内容的语言代码,很少使用!
dir 语言方向,ltr,rtl 左到右,右到左、
可以通过属性访问到该属性对应的值
1)取得属性
getAttribute() 参数为实际元素的属性名,calss,name,id,title,lang,dir一般只有在取得自定义特性值的情况下,才会用该方法大多数直接使用属性进行访问,比如style,onclick
2)设置属性
setAttribute() 两个参数,第一个参数为要设置的特性名,第二个参数为对应的值。如果该值存在,替换。
3)移除属性
removeAttribute() 移除指定的特姓
4)attributes属性,其中包含了一个NamedNodeMap,与NodeList类似。
getNamedItem(name)
removeNamedItem(name) 从列表中删除nodeName属性等于name的值
setNamedItem(node) 向列表中添加一个节点
item(pos) 返回位于数字pos位置处的节点
5)创建元素
createElement() 一个参数,要创建元素的标签名。
6)元素的子节点
<ul>
<li>item1</li>
<li>item2</li>
<li>item3</li>
</ul>
ie8及一下版本浏览器 3个子节点
其他浏览器 7个子节点
2. 作为文档树的文档
将文档看做是Element对象树,忽略文档Text,Comment节点。Element中的属性
children :类似于childNodes,返回NodeList对象,但是该对象中仅包含Element对象
firstElementChild :第一个孩子元素节点
lastElementChild :最后一个孩子元素节点
nextElementSibling :下一个兄弟元素节点
previousElementSibling :上一个兄弟元素节点
childElementCount :子元素的数量,返回值和children.length值相等
3. 元素内容
innerHTML 返回元素内容+html结构
textContent 非ie浏览器 只拿文本节点
innerText ie浏览器
insertAjacentHTML()
第一个参数为位置(beforebegin,afterbegin,beforeend,afterend),
第二个参数为内容
<div id="target">this is element html</div>
beforebegin afterbegin beforeend afterend
4) Text类型: 文本类型
文本节点。包含的是可以按照字面解释的存文本内容。
length
文本长度
appendData(text)
追加文本
deleteData(beginIndex,count)
删除文本
insertData(beginIndex,text)
插入文本
replaceData(beginIndex,count,text)
替换文本
splitText(beiginIndex)
从beginIndex位置将当前文本节点分成两个文本节点
substringData(beiginIndex,count)
从beginIndex开始提取count个子字符串
<span>这个是文本节点</span>
document.createTextNode()
创建文本节点,参数为要插入节点中的文本
5) Comment类型: 注释类型
<div id = "myDiv"><!--a comment--></div>
<!--a comment--> Comment类型
2. 事件
javascript与HTML之间的交互是通过事件实现的。事件就是文档或浏览器窗口中发生的一些特定的交互瞬间。
事件三要素:
事件【源】目标(event target)
发生的事件与之相关联或与之相关的对象
事件处理程序(event handler)
处理或相应事件的函数
事件对象(event object)
与特定事件相关且包含有关该事件详细信息的对象。
1) 事件流
描述的是从页面中接受事件的顺序
1. 事件冒泡
事件开始由最具体的元素接收,然后逐级向上传播到不具体的节点。
<html>
<head></head>
<body>
<div>click me</div>
</body>
</html>
当点击了<div>元素,这个click事件会按照如下顺序传播
div->body->html->document
注意:IE8以及更早版本只支持事件冒泡。
2. 事件捕获
不太具体的节点更早接收事件,具体的节点到最后接收事件。当点击了<div>元素,按照如下方式触发click事件
document->html->body->div
3. dom事件流
“DOM2级事件”规定了事件流包括三个阶段:事件捕获阶段,处理目标阶段和事件冒泡阶段。
事件捕获: document->html->body
处理目标: 事件处理
事件冒泡: div->body->html->document
2) 事件处理程序
事件就是用户或浏览器自身执行的某种动作,响应某个事件的函数为事件处理程序,事件处理程序以"on"开头(onclick,onload)
1. HTML事件处理程序
<input type="button" value="clickMe" onclick = "alert('is clicked')">
不能在事件中使用未经转义的HTML语法字符
<input type="button" value="clickMe" onclick = "showMsg()">
<script type="text/javascript">
function showMsg(){
alert("is clicked");
}
</script>
点击按钮会调用showMsg()函数,事件处理程序的代码在执行时,有权访问全局作用域的任何代码。
2. DOM0级事件处理程序
通过javascript制定时间事件程序的传统方式,将一个函数赋值给一个事件处理程序属性。特点是简单,跨浏览器。
var btn = document.getElementById("btn");
btn.onclick = function(){
alert('cliked');
}
dom0级方法制定的事件处理程序被认为是元素的方法,因此这个时候时间处理程序是在元素的作用域中运行,this指向当前元素。
btn.onclick = null; //删除事件处理程序(解绑)
3. DOM2级事件处理程序 非IE 下
addEventListener()
事件绑定
参数:
要绑定的事件名 click keyup
作为事件处理的函数 fn
布尔值:是否在事件捕获阶段调用事件处理程序;false在冒泡阶段调用【默认false】
removeEventListener()
事件删除
参数:
要删除的事件名
作为事件处理的函数
布尔值:true在捕获阶段调用事件处理程序;false在冒泡阶段调用
例如:
//事件绑定
var btn = document.getElementById("btn");
btn.addEventListener("click",function(){
alert(this.id); //该函数在其依附的元素的作用域中运行。
},false);
//事件移除
var btn = document.getElementById("btn");
var handler = function(){
alert(this.id);
}
btn.addEventListener("click",handler,false);
btn.removeEventListener("click",handler,false);//移除
可以添加多个事件处理程序,并且按照添加她们的顺序触发。移除事件传入的参数与添加处理程序时使用的参数相同,添加事件时如果使用匿名函数将无法删除
4. IE事件处理程序
事件处理程序会在全局作用域中运行,因此this指向window对象。为一个对象添加两个相同的事件,事件处理程序的顺序是按照添加相反顺序进行处理【事件没有捕获】
attachEvent() 非IE
事件绑定
参数:
时间处理程序名称
时间处理函数
detachEvent()
事件移除
参数:
时间处理程序名称
时间处理函数
事件处理程序都被添加到冒泡阶段
5. 跨浏览器的事件处理程序
见代码 lib.js
3) 事件对象
1. dom中的事件对象
在触发DOM上的某个事件时,会产生一个事件对象event,这个对象包含着所有与事件相关的信息,默认会将event对象传入到事件处理函数中
dom.onclick = function(event){
console.log(event);
}
dom.addEventListener("click",function(event){
console.log(event);
},false);
属性 类型 说明
bubbles Boolean 事件是否冒泡
cancelable Boolean 是否可以取消事件默认行为
currentTarget Element 当前正在处理事件的那个元素
eventPhase Integer 调用事件处理程序的阶段;1,捕获 2,处于目标 3,冒泡
target Element 事件目标
type String 事件类型
trusted Boolean 事件是否是浏览器生成的
preventDefault() Function 取消事件的默认行为
stopPropagation() Function 取消事件的进一步捕获或者冒泡
在事件处理程序内部,对象this始终等于currentTarget值,而target则只包含事件的实际目标。如果直接将事件处理程序指定给了目标元素,this,currentTarget,target包含相同的值。
2. IE中的事件对象
event可以作为window对象的一个属性存在,使用attachEvent添加事件处理程序的时候,event对象会作为参数传入事件处理函数中
dom.onclick = function(){
console.log(window.event);
window.event.returnValue = false;//阻止默认行为
window.event.cancalBubble = true;//取消冒泡
}
dom.attachEvent("onclick",function(event){
console.log(window.event);
});
属性 类型 说明
cancelBubble Boolean 是否取消时间冒泡,值为true取消冒泡 stopPropagation()
returnValue Boolean 取消时间默认行为,值为false阻止 preventDefault()
srcEvent Element 时间的目标 target
type String 被触发的时间 的类型
3. 跨浏览器的事件对象
事件对象
目标对象
阻止默认行为
阻止冒泡
4) 事件类型
1. UI事件
load
当页面完全加载后再window上触发,当所有框架加载完毕时在框架集上触发,当图像加载完毕时在img元素上触发,当嵌入的内容加载完时在<object>触发
unload
当页面完全卸载后再window上触发,当所有框架都卸载后在框架集上触发,当嵌入的内容卸载完毕后再<object>上触发,(firefox不支持)
select
当用户选择文本框(<input>,<textarea>)中的一个或多个字符时
resize
当浏览器窗口被调整到一个新的高度或者宽度时,会触发
scroll
当用户滚动带滚动条的元素中的内容时,在该元素上触发resize,scroll会在变化期间重复被激发,尽量保持代码简单
2. 焦点事件
blur
元素失去焦点的时候触发
focus
元素获得焦点的时候触发,不支持冒泡
//IE支持
focusin
与focus等价,支持冒泡
focusout
与blur等价,支持冒泡
3. 鼠标与滚轮事件
click
点击主鼠标按钮或者按下回车按键的时候触发。只有在一个元素上相继发生mousedown,mouseup事件,才会触发click事件
dblclick
双击主鼠标按钮时触发.只有在一个元素上相继触发两次click时间才会触发dbclick事件
mousedown
任意鼠标按钮按下时触发
mouseup
释放鼠标按钮触发
mousemove
鼠标在元素内部移动的时候重复触发
mousewheel
滚轮事件
mouseover
鼠标位于元素外部,将其首次移入另一个元素边界之内时触发【支持子元素】
mouseenter
鼠标光标从元素外部首次移动到元素范围内激发,不冒泡。【不支持子元素】
mouseout
在位于元素上方的鼠标光标移入到另外一个元素中。【支持子元素】在被选元素上与mouseleave效果相同
mouseleave
在位于元素上方的鼠标光标移动到元素范围之外时触发,不冒泡【不支持子元素】
4. 相关元素,event特殊属性
1.客户区坐标位置
clientX,clientY 事件发生时,鼠标指针在视口中的水平和垂直坐标
2.页面坐标位置
pageX,pageY 事件发生时,鼠标指针在页面本身而非视口的坐标,页面没有滚动的时候,pageX和pageY的值与clientX和clientY值相等
3.屏幕位置
screenX,screenY
4.修改键
值为boolean类型,用来判断对应的按键是否被按下
shiftKey
ctrlKey
altKey
metaKey
5.鼠标按钮
mousedown,mouseup,该事件的event对象中包含了button属性,表示按下或释放的按钮。
0表示主鼠标按钮
1表示中间的滚动按钮
2表示次鼠标按钮
5. 键盘与文本事件
keydown 按下键盘任意键时触发,如果按住不放会重复触发此事件
keypress 按下键盘字符键时触发,如果按住不放会重复触发此事件
keyup 释放键盘上键时触发
当键盘事件发生时,event对象的keyCode属性中会包含一个代码与键盘上的特定键对应,对数字字母键,keyCode属性的值与ASCII码中对应的小写字母和数字编码相同
详见keycode.txt
**************************************************总结*******************************************
DOM
document Object Model
文档对象模型
文档(html)-->对象模型(多层次节点结构)
dom是提供给我们操作文档的API(引用程序接口)
1. Node
所有节点的都继承自Node,所有的节点对象都可以调用Node构造函数原型中的属性和方法
2. DOM API继承关系
Object
|
Node
Document 9 Element 1
构造函数 |
HTMLElement
-----------------------------
实例 document document.body
3. Node
nodeType 节点类型 1 ,9
nodeName 节点名称(Element 标签名)
nodeValue
表示层级结构的属性
childNodes 所有子节点,类数组对象
parentNode 父节点
nextSibling 下一个兄弟
previousSibling 上一个兄弟
firstChild
lastChild
ownerDocument
hasChildNodes() 判断是否有子节点
4个必须通过父节点调用的方法
appendChild(node);
replaceChild(insert,src);
insertBefore(insert,flag);
removeChild(node);
<div id="outer">
<div id="inner"></div>
</div>
var outer = document.getElementById("outer");
var inner = document.getElementById("inner");
outer.removeChild(inner);
cloneNode(boolean);
true 深复制
false 浅复制
document.body.ownerDocument == document
4. Document
当前文档,window.document就是Document的一个实例对象。
document.body
document.title
document.domain 域名,跨域访问 www.baidu.com
document.images 当前页面中所有img元素
document.forms 当前页面中所有的form表单元素
document.getElementById(id);
通过id获取元素节点
document.getElementsByTagName();
通过标签名获取元素集合
5. Element
元素/标签节点,在HTML中,所有的节点对象都是HTMLElement的实例,HTMLElement继承Element
coreAttr属性
id
title
className
特有属性
src
alt
type
value
......
方法
getAttribute(arrName)//获取自定义属性
setAttribute(arrName,arrValue)
removeAttribute(arrName);
将节点树映射成元素节点树
children 获取所有的元素子节点
firstElementChild
lastElementChild
nextElementSibling
previousElementSibling
document.images.item(index)
document.images[index]
var one = document.images[0];
one.src
6. 将类数组对象转换为数组
var arr = Array.prototype.slice.call(类数组对象,0);
将类数组对象----转换--->arr(数组对象)
7. 事件
1)事件三要素
事件源 节点对象
事件处理函数 匿名函数
事件对象 普通对象
2)事件流
1.事件捕获(Netspace)
点击inner的时候,事件流方向由外而内
outer->center->inner
2.事件冒泡(IE)
点击inner的时候,事件流方向由内而外
inner->center->outer
事件激发的顺序都是由内而外
3)DOM事件流
经历3个阶段
1)事件捕获阶段 外->内
2)处理目标阶段 目标对象执行事件处理函数
3)事件冒泡阶段 内->外
4)事件绑定方法
1. dom0级事件绑定
通过element元素的事件属性来绑定事件处理程序
element.事件属性 = 事件处理函数(匿名函数)
var btn = document.getElementById("btn");
btn.onclick = function(){
};
2. dom2级事件绑定 【同一个类型事件可以添加多个】
通过函数来绑定事件处理程序
1)非IE下事件绑定方式
addEventListener();
参数:
事件类型 click,keyup
事件处理程序 fn
boolean 是否在事件捕获阶段调用事件处理程序。默认为false
removeEventListener();
参数:
事件类型 click,keyup
事件处理程序 fn
boolean 是否在事件捕获阶段调用事件处理程序。默认为false
2)IE下事件绑定方式 IE8,以及以下版本
经历3个阶段
1)事件捕获阶段 不支持 外->内
2)处理目标阶段 目标对象执行事件处理函数
3)事件冒泡阶段 内->外
attachEvent();
参数
事件类型 onclick
事件处理函数
detachEvent();
参数
事件类型 onclick(加on)
事件处理函数
3)兼容事件绑定与解绑
封装思想(插件)
5) 事件对象
事件对象都是由系统在事件激发的时候创建的
1) IE下的事件对象
2) 非IE下的事件对象
当系统调用事件处理函数的时候会将其刚刚创建好的事件对象当做参数传递给事件处理函数。
inner.onclick = function(event){
}
inner.addEventListener("click",function(event){
});
currentTarget 当前目标
target 最终目标
this 当前目标
this == currentTarget
preventDefault(); 阻止事件默认行为
stopPropagation(); 停止事件冒泡
<a href="http://www.baidu.com">百度一下</a>
a的默认行为跳转到目标地址。
<form action="login.action">
<input type="text" name="sno">
<input type="submit">
</form>