文档对象模型(DOM)
针对HTML和XML文档的一个API,DOM描绘了一个层次化的节点树,允许开发人员添加,移除和修改页面的一部分。
分级
DOM1级
定义了HTML和XML文档的底层结构,为基本的文档结构和查询提供了接口。
DOM2级
对DOM1级进行扩展。
- DOM2级核心:在1级核心基础上构建,为节点添加了更多方法和属性。
- DOM2级视图:为文档定义了基于样式信息的不同视图。
- DOM2级事件:说明了如何使用事件与DOM文档交互
- DOM2级样式:定义了如何以编程的方式来访问和改变css样式信息。
- DOM2级遍历和范围:引入了遍历DOM文档和选择其特定部分的接口
- DOM2级HTML:在1级HTML基础上构建,添加了更多属性,方法和新街口
DOM3级
3级DOM通过引入统一方式载入和保存文档和文档验证方法对DOM进行进一步扩展。
节点与元素节点
- 节点包括有:元素节点,文本节点,属性节点,注释节点等
- 每一个节点对象有三个重要的属性:
- nodeType:节点的类型,其中1表示元素节点,2表示属性节点,3表示文本节点
- nodeName:节点的名字。标签节点就是大写的标签名字,属性节点就是小写的属性名字,文本节点就是#text
- nodeValue:节点的值。标签节点的值时null,属性节点的值是属性值,文本节点的值是文本。
注意:一个元素的父元素和父节点都指的是包含该元素的父元素,是一个标签。但是一个元素的子元素和子节点不是同一个东西。元素的子元素特指包含在这个元素内部的所有标签。而元素的子节点则是包含在这个元素内部的所有节点,包括文本节点,属性节点,元素节点和注释节点等。
<ul>
<li class="name">这是第1个li</li>
<li>这是第2个li</li>
<li>这是第3个li</li>
<li>这是第4个li</li>
<li>这是第5个li</li>
</ul>
在上述例子中,ul标签的子节点有11个,而子元素只有5个。
获取子节点的方法
- parentNode.获取父节点。最顶端是#document
- childNodes:获取所有的子节点。
- firstChild:获取第一个子节点。
- lastChild:获取最后一个子节点。
- nextSiblings:获取后一个兄弟节点
- perviousSiblings:获取前一个兄弟节点。
- hasChildNodes:判断该元素是否有子节点。
获取子元素的方法
- parentElement:获取当前元素的父元素。
- children:获取当前元素的所有子元素。
- childElementCount:当前元素的所有子元素的个数。
- firstElementChild:返回第一个子元素节点
- lastElementChild:返回最后一个子元素节点
- nextElementsibling:返回下一个兄弟元素节点。
- previousElementSibling:返回前一个兄弟元素节点。
- attributes:获取元素的属性节点。(标签内部添加的类似于name,class,id之类的)
注意:获取子元素节点的方法除了children之外,其余的方法IE9以下都不兼容。
DOM的其他操作
增加
document.createElement()
//参数传递的是标签名字
插入
parentNode.appendChild()
;//在父级元素的后面增加一个子元素parentNode.insertBefore(a,b)
;//第一个参数是新节点,第二个参数是老节点。表示将新节点插入到老的节点之前。
删除
parent.removeChild()
;//传入的参数是被选中的要删除的节点。
替换
parent.replaceChild
(新节点,旧节点)//将旧节点替换成新节点。
节点拷贝
cloneNode()
//不传参数的时候是浅拷贝,只是拷贝当前元素,如果传入参数true时,表示深拷贝,会将当前节点以及其包含的子节点都拷贝一份。
注意:拷贝只是拷贝元素,并不拷贝元素身上绑定的事件。
操作属性:
获取属性
getAttribute('属性名')
设置属性
setAttribute('属性名','属性值')
注意:
这里如果该DOM元素已经有了这个属性,通过上述方式设置属性就会把元素原来有的那个属性给覆盖掉。
情景:假设divObj是一个DOM节点,它此时有一个类样式为base,而我们想给它在base这个类样式的基础上再添加一个active的样式
❌:
divObj.setAttribute('class','active');
当这行代码执行结束之后,divObj的类样式只有active,没有base,因为base被覆盖掉了
✔:
let array=divObj.className.split(' ');//获取到所有的类样式组成的数组
array.push('active');//将active添加到这个数组里面,
divObj.className = array.join(' ');//再将这个数组转为字符串赋值给divObj的className
移除属性
removeAttribute('属性名')
innerHTML属性
在读模式下,innerHTML属性返回与调用元素的所有子节点对应的HTML标记,在写模式下,innerHTML会根据指定的值创建新的DOM树,然后用这个DOM树完全替换调用元素先前的所有子节点。(读模式下会返回带html标签的字符串,写模式下会将传入的字符串解析成为html标签,然后覆盖掉这个DOM元素之前的所有子元素。)
innerText
通过innerText属性可以操作元素中包含的所有文本内容,包括子文档树中的文本,在通过innerText读取值的时候,它会按照由浅入深的顺序,将子文档中所有文本拼接起来;再通过innerText写入值时,会覆盖。如果写入的字符串中有html标签元素,也不会解析成html标签渲染到页面上,会当成普通的字符串输出。
注意:这个方法IE支持,FF不支持,FF中有一个类似方法textContent。
计算的属性
虽然可以通过DOM对象.style.属性名称
的方式获取到元素的属性样式,但是,这种方式仅限于通过内联的形式写在元素标签的style
属性里的样式信息,如果时通过外链或者写在<style></style>
标签的样式信息,这种方法就无能为力了。这时候,要是想要获取相关的信息,需要通过getComputedStyle()
方法来获取。
<style>
#app{
width:500px;
height:500px;
}
#app::after{
content:'hello';
display:inlien-block;
width:20px;
}
</style>
<div id='app' style = 'background-color:red'></div>
<script>
var app = document.getElementById('app');
app.style.width//无法获取到500px
window.getComputedStlye(app,null).width//500px;第二个参数是可选的,可以是一个表示伪元素的字符串
//要想获得这个after伪元素的样式可以通过以下方式来获取到:
window.getComputedStyle(app,':after').width;
</script>
注意:getComputedStyle()方法FF支持,IE不支持,IE支持的是currentStyle,即要在IE上获取到width,通过app.currentStyle.width
。这个方法Edge不支持,只有IE支持。
元素大小
offset系列
offsetWidth:元素在水平方向上占的空间大小,包括元素宽度,边框宽度等。
offsetHeight:元素在垂直方向上占的空间大小。
offsetLeft:元素的外左边框与父元素内左边框的距离。
offsetTop:元素的外上边框与父元素的内上边框之间的距离。
client系列
- clientHeight:元素内容区域加上上下的内边距
- clientTop:元素内容区域加上左右的内边距。
- clientLeft:元素左边框的宽度
- clientTop: 元素上边框的宽度
注意:clientX和clientY是在注册鼠标移动事件的时候显示鼠标在屏幕上的位置用的。e.clientX;e是事件源对象
scroll系列
- scrollHeight:在内容超过包裹元素的情况下,是内容的总高度,在没有超过情况下,是包裹内容的元素的高度
- scrollWidth:在内容超过包裹元素的情况下,是内容的宽度,在没有超过情况下,是包裹内容的元素的宽度
- scrollTop:卷曲上去的高度
- scrollLeft:向右卷曲出去的宽度。
事件
事件流:从页面中接受事件的顺序。IE是事件冒泡流,FF事件捕获流。
DOM事件流:事件捕获阶段——>处于目标阶段——>事件冒泡阶段
事件处理
- DOM0级事件处理:
- 绑定事件:
元素.on事件 = 事件处理函数
- 解绑事件:
元素.on事件 = null
- 绑定事件:
- DOM2级事件处理:
- 绑定事件:
元素.addEventListener(事件名称(不带on),事件处理函数,true/false(在捕获阶段执行/在冒泡阶段执行))
- 解绑事件:
元素.removeEventListener(事件名称)
- 绑定事件:
IE事件处理:
绑定事件:元素.attachEvent(带on的事件名,事件处理函数)
解绑事件:元素.detachEvent(带on的事件名)
事件对象
除了IE之外:事件处理函数中传入的形参e就是事件对象
- e.preventDefault();//阻止默认事件
- e.stopPropergation()//阻止事件冒泡
- e.target//事件源对象
- e.eventPhase//事件目前所处的阶段
IE:window.event
- window.event.cancleBubble = true//取消事件冒泡
- window.event.srcElement = e.target
TIPS:不会冒泡的事件有abort blur error focus load mouseenter/mouseleave resize unload submit