DOM节点操作
浏览器读取HTML文件并解析后,可以生成页面结构,那么在结构生成之后还可不可以再修改这个结构呢,这就需要用到我们的DOM节点操作
节点操作主要有以下内容:
* 获取节点
* 创建节点
* 修改节点
* 插入节点
* 删除节点
* innerHTML
获取节点
- 父子关系
- parentNode
- firstChild/lastChild/childNodes
- childNodes/childern
- 兄弟关系
- previousSibling/nextSibling
- previousElementSibling/nextElementSibling
直接通过节点关系,可维护性差,所以我们通过接口获取节点
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<p id="hello" class="mooc">
hello<span>mooc</span>
<img src="user.jpg">
</p>
<div>前端</div>
</body>
</html>
对于id = "hello"
有一个对应的接口getElementById
对于标签p,我们可以通过getElementByTagName获取节点
对于class="mooc"
我们可以通过getElementByClassName获取节点
还有一个重要的方法querySelector/All通过选择器获取节点
getElementById
element = document.getElementById(id)
获取文档当中制定id的元素,id是唯一的,所以得到的节点也就是唯一的
在上面的例子中可以用document.getElementById("hello")
,我们将获取到p节点,是一个对象,包含着属性和接口
一段范例用代码
<div id="users">
<h2>学习</h2>
<ul>
<li class="user">
<img src="1.jpg" >
<a href="/user/1">satoshi</a>
</li>
<li class="user">
<img src="2.jpg" >
<a href="/user/2">青草</a>
</li>
<li class="user">
<img src="3.jpg" >
<a href="/user/3">XXX</a>
</li>
</ul>
</div>
getElementByTagName
collection = element.getElemrntsByTagName(tagName)
这个方法返回一个对象数组,每个对象分别对应着文档里有给定标签的元素
比如在上面的例子中,我们通过
var users = getElementById("users");
users.getElemrntsByTagName("li")
得到的是一个具有三个li的列表,我们可以通过下标获取元素,users.getElemrntsByTagName("li")[2]
表示的就是XXX这个对象。
我们重点看一下这个方法的返回值,var a = users.getElemrntsByTagName("li")
,这时,a是[li, li, li],当我们用一些方法删除节点青草后,a就变成了[li, li],我们可以看出,这个方法的返回值是动态的
getElementsByTagName也可以把通配符”*”作为参数,它可以返回具有所有节点的数组,比如
users.getElementByTagName("*")
我们得到一个列表[h2, ul, li, img, a, li, img, a, li, img, a],包含着users下所有的节点。
getElementsByClassName
collection = element.getElementsByClassName(className)
这个方法的返回值也是一个数组,我们用users.getElementByClassNane("user")
,得到具有user类的元素,也可以利用下标访问元素。
我们可以同时将多个类作为参数users.getElementByClassNane("user selected")
,中间用逗号分开即可。
这个方法只能应用于比较新的浏览器,对于IE678,我们有一个兼容办法
function getElementsByClassName(node,className){
if(node.getElementsByClassName){ //特性侦测
return node.getElementsByClassName(className); //优先使用W3C规范
}
else{
var results = new Array();
var elems = node.getElementsByTagName("*"); //获取所有后代元素
for(var i = 0;i<elems.length;i++){
if(elems[i].className.indexOf(classname) != -1){
results[results.length] = elems[i]; //扩容
}
}
return results;
}
}
这个新的函数不适用于将多个类名作为参数的情况,第一个参数是节点,第二个参数是类名,对于上面的例子,我们可以写作var userlist = getElementsByClassName(users,"user")
;
function getElementsByClassName(elem,clazz){
if(document.getElementsByClassName){
return elem.getElementsByClassName(clazz);
}else{
//获取所有子节点
var elements = elem.getElementsByTagName('*');
//储存满足条件的子元素
var result = [];
var element,classname,flag;
//获取类名数组
clazz = clazz.split(" ");
// 遍历子节点
for(i in elements){
var classname = elements[i].className;
flag = true;
//遍历类名
for(j in clazz){
if(classname.indexOf(clazz[j]) == -1){
flag = false;
break;
}
}
if(flag){
result.push(elements[i]);
}
}
return result;
}
}
这个函数支持多个类名
querySelector/All
list = element.querySelector/All(selector)
两者的区别是,querySelector返回的是第一个符合条件的元素;querySelectorAll返回的是一个列表
参数是一个选择器,那我们该怎么写呢var users = document.querySelector(#users)
这样我们通过id选择器,就获得了div#users
再加上users.querySelectorAll(".user")
,这样我们得到了[li, li, li]
我们可以有更加灵活的方式document.querySelector(#users .user)
这样我们科技迅速获取节点。
注意,这种方法返回的list不是动态的
小结
name | only document | sole(唯一的) | live(动态的) |
---|---|---|---|
getElementById | * | * | |
getElementsByTagName | * | ||
getElementsByClassName | * | ||
querySelectorAll | |||
querySelector | * |
下一篇我们将对其他操作做出总结