概念
DOM 树
- 当浏览器加载HTML页面的时候,首先就是DOM结构的计算,计算出来的DOM结构就是DOM树(把页面中的HTML标签像树状结构-样,分析出之间的层级关系)
- DOM树描述了标签和标签之间的关系(节点间的关系) ,我们只要知道任何一个标签,都可以依据DOM中提供的属性和方法,获取到页面中任意一个标签或者节点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DOM</title>
</head>
<body>
<div class="box" id="box">
<ul>
<li>新闻</li>
<li>电影</li>
<li>音乐</li>
</ul>
<div>最新新闻</div>
<div>最新电影</div>
<div>最新音乐</div>
</div>
</body>
</html>
其树状结构如图
DOM元素的获取方法
getElementById("id属性的值")
- 在整个文档中通过元素的ID属性值,获取到这个元素对象
- getElementByld是获取元素的方法,而document限定了获取元素的范围,我们把这个范围称之为:“上下文[context]"
- getElementByld的上下文只能是document。因为严格意义上,一个页面中的ID是不能重复的,浏览器规定在整个文档中只可以获取这个唯一的ID
- 在IE6~7浏览器中,会把表单元素(input)的name属性值当做ID来使用。建议name值不要和其它id值有冲突
getELementsByTagName("标签名")
[context].getELementsByTagName("标签名")
在指定的上下文中,通过元素的标签名获取一组元素集合(HTMLCollection) ,上下文是我们自己来指定的。- 它会把当前上下文中,所有后代层级内的标签都获取到
- 基于这个方法获取到的结果永远都是一个集合(不管里面是否有内容,也不管有几项,它是一个容器或者集合) ,如果想操作集合中具体的某一项,需要基于索引获取到才可以
HTMLCollection的特点:
- 首先它是对象数据类型的,结构和数组非常相似(数字作为索引,Length代表长度),但是不是数组,我们把它叫做“类数组”,不能直接使用数组中的方法。
- 每一项对应一个元素对象,有自己的内置属性
getElementsByName("name属性的值")
document.getElementsByName("name属性的值")
上下文只能是document,通过元素的name属性值获取一组节点集合(NodeList),也是一个类数组- 在IE浏览器中(IE9及以下版本),只对表单元素的name属性起作用(正常来说:我们项目中只会给表单元素设置name ,用于给表单元素分组。给非表单元素设置name ,其实是一个不太符合规范的操作)
getElementsByClassName("类样式的名字")
[context].getElementsByClassName("类样式的名字")
在指定的上下文中,通过元素的类名获取一组元素集合(HTMLCollection)- 真实项目中,我们经常是基于样式类来给元素设置样式,所以在JS中,我们也会经常基于样式类来获取元素,但是此方法在IE6~8下不兼容
querySelector("选择器名")
[context].querySelector("选择器名")
在指定的上下文中基于选择器(类似于CSS选择器)获取到指定的元素对象(获取的是一个元素,哪怕选择器匹配了多个,该方法只获取第一个)
querySelectorAll("选择器名")
- 在querySelector的基础上,我们获取到选择器匹配到的所有元素, 结果是一个节点集合(NodeList)
querySelector/querySelectorAll
都是不兼容IE6~8浏览器的,并且这两个方法性能消耗较大
document.head
- 获取HEAD对象
document.body
- 获取BODY对象
document.documentElement
- 获取HTML对象
<body>
<ul class="box1" id="box2" name="box3">
<li name='row' class="li">第一行第一行第一行第一行第一行第一行第一行第一行第一行第一行</li>
<li name='row' class="li">第二行</li>
<li name='row'>第三行</li>
<li name='row'>第四行</li>
<li name='row'>第五行</li>
<li name='row'>第六行</li>
</ul>
<script>
var oBox = document.getElementById('box2');
=>通过getElementById获取的元素是一个对象数据类型的值(包含多种内置属性)
=>如果页面中的ID重复了, 我们基于这个方法只能获取到第一个元素,后面相同ID
=>元素无法获取
var boxList=oBox.getElementsByTagName('li');
=>此时的上下文是oBOX
boxList[0];=>通过索引获取具体的li
boxList.length;=>获取集合中li的数量
=>集合中的每一项存储的值又是一个元素对象(对象类型,包含许多内置属性)
boxList[1] .style.color='red' ;
=>修改集合中第二个LI的文字颜色
var nameList=document.getElementsByName('row');
=>获得所有name属性值为row的元素,获取的结果是一个元素集合(NodeList)
nameList[0].style.backgroundColor='red';
=>修改集合中第一个li的背景颜色
var oBox1=document.getElementsByClassName('box1');
=>获取ul元素集合(HTMLCollection),该集合里面只有一个元素ul
var oBox2=document.querySelector('.box1');
=>获取ul对象
var li1=document.querySelector('.li');
=>当有多个相同类名的元素,只会获取第一个,本行代码只获取第一行的li对象
document.querySelectorAll('[name="row"]')
=>相当于属性选择器
document.querySelectorAll('.box1>li')
=>获取类名为box1下的li元素
var liList=document.querySelectorAll('.li');
=>当有多个相同类名的元素,获取所有的元素,形成一个元素集合(NodeList)
</script>
DOM元素的增删改
creatElement
- 创建一个元素标签(元素对象)
document. createElement( [标签名])
appendChild
- 把一个元素对象插入到指定容器的末尾
[container].appendChild([newEle])
insertBefore
- 把一个元素对象插入到指定容器中某一个元素标签之前
[container].insertBefore([newEle],[oldEle])
var newP=document.createElement('p');
newP.innerHTML='新加入的p标签!!!';=>用于给标签添加内容
newP.style.backgroundColor='green';
document.body.append(newP);
var newA=document.createElement('a')
newA.innerText='新加入的a标签!!!';
newA.style.backgroundColor='blue';
document.body.insertBefore(newA,newP);
效果如下:
cloneNode
- 把某个节点克隆
[curEle].cloneNode()
:浅克隆,只克隆当前的标签[curEle].cloneNode(true)
:深克隆,当前标签及其里面的内容一起克隆
removeChild
- 在指定容器中删除某一个元素
[container].removeChild([oldEle])
var cloneA=newA.cloneNode();
cloneA.innerText='克隆的a标签!!!';
document.body.appendChild(cloneA);
document.body.removeChild(newA)
set/get/removeAttribute
- 设置/获取/删除 当前元素的某一个自定义属性
=>基于当前元素作为一个对象,在对象对应的堆内存中新增一个自定义的属性
var objP=document.getElementsByTagName('p')[0]
objP.myIndex=10; =>设置新增的属性值
console.dir(objP); =>获取
delete objP.myIndex; =>删除
=>基于DOM方法完成自定义属性的设置
newP.setAttribute('myColor','green'); =>设置
newP.getAttribute('myColor'); =>获取
newP.removeAttribute('myColor'); =>删除
=>!!!上下两种机制属于独立的运作体制,不能互相混淆使用!!!
上下两种机制属于独立的运作体制,不能互相混淆使用
- 第一种是基于对象键值对操作方式,修改当前元素对象的堆内存空间来完成(建议使用第一种,一定程度上可以防止攻击)
- 第二种
set/get/removeAttribute
是直接修改页面中HTML标签的结构来完成(此种办法设置的自定义属性可以在结构上呈现出来) - 基于
setAttribute
设置的自定义属性值都是字符串