目录
DOM操作回调函数的优化
DOM
文档模型对象(Document Object Model):通过DOM可以来任意修改网页的各个内容。
文档:文档指的是网页,一个网页就是一个文档。
对象:对象指将网页中的每一个节点都转换为对象,转换完对象以后,就可以以一种纯面向对象的形式来操作网页了。
模型:模型用来表示节点和节点之间的关系,方便操作页面。
节点(Node):节点是构成网页的最基本的单元,网页中的每一个部分都可以称为是一个节点
虽然都是节点,但是节点的类型却是不同的。
常用的节点分为以下几种:
节点种类 | 描述 |
---|---|
文档节点 (Document) | 代表整个网页 |
元素节点(Element) | 代表网页中的标签 |
属性节点(Attribute) | 代表标签中的属性 |
文本节点(Text) | 代表网页中的文本内容 |
DOM操作
一般DOM操纵增删改查等,都需要和事件以及按钮(或其他)进行绑定,如果是按钮,点击页面某个按钮,则会执行对应绑定好的回调函数,通过在回调函数里面进行增删改查是个不错的选择。所以,本总结将DOM操作从事件、查、增、删、改来进行总结。
DOM操作之事件
事件指的是用户和浏览器之间的交互行为。比如点击按钮等,可以为事件来绑定回调函数来响应事件。
绑定事件的方法主要有两种:
1.可以在标签的事件属性中设置相应的JS代码
<button onclick="js代码。。。">按钮</button>
2.可以通过为对象的指定事件属性设置回调函数的形式来处理事件
<button id="btn">按钮</button>
<script>
var btn = document.getElementById("btn");
btn.onclick = function(){
};
</script>
注意细节:
上述第二种方式操作时会存在一定问题,因为浏览器在加载页面的时候,是自上而下的顺序加载的,加载一行执行一行,如果将js代码编写到页面的上边,当代码执行时,页面中的DOM对象还没有加载,此时将会无法正常获取到DOM对象,导致DOM操作失败。
解决办法:
1.可以将JS代码编写到body的下边。
2.将js代码编写到window.onload = function(){}中,window.onload 对应的回调函数会在整个页面加载完毕以后才执行,所以可以确保代码执行时,DOM对象已经加载完毕了
<script>
window.onload = function(){
var btn = document.getElementById("btn");
btn.onclick = function(){
};
};
</script>
DOM操作之查询
在网页中浏览器已经为我们提供了document对象,其代表的是整个网页,是window对象的属性,可以在页面中直接使用。
查询方法
查询方法如下所示:
方法 | 描述 |
---|---|
document.getElementById(“id属性值”); | 根据元素的id属性查询一个元素节点对象 |
document.getElementsByName(“name属性值”); | 根据元素的name属性值查询一组元素节点对象 |
document.getElementsByTagName(“标签名”); | 根据标签名来查询一组元素节点对象 |
查询属性
查询元素的属性:
语法:
元素.属性名
示例:ele.id、ele.value等
注意细节:class属性不能采用这种方式,读取class属性时需要使用 元素.className
修改元素的属性:
元素.属性名 = 属性值
查询节点元素的方式一般是通过具体的元素节点来查询,通过标签名查询当前元素的指定后代元素 。
查询的方式有:
方式 | 描述 |
---|---|
元素.childNodes | 获取当前元素的所有子节点,但是会获取到空白的文本子节点 |
元素.children | 获取当前元素的所有子元素 |
元素.firstChild | 获取当前元素的第一个子节点,但会获取到空白的文本子节点 |
元素.lastChild | 获取当前元素的最后一个子节点 |
元素.parentNode | 获取当前元素的父元素 |
元素.previousSibling | 获取当前元素的前一个兄弟节点 |
元素.nextSibling | 获取当前元素的后一个兄弟节点 |
firstElementChild | 获取当前元素的第一个子元素 |
元素.firstChild.nodeValue | 读取第一个子节点的文本内容 |
注意细节:
- childNodes属性会获取包括文本节点在呢的所有节点,根据DOM标签标签间空白也会当成文本节点。在IE8及以下的浏览器中,不会将空白文本当成子节点。
- previousElementSibling获取前一个兄弟元素,IE8及以下不支持。
- firstElementChild不支持IE8及以下的浏览器,如果需要兼容他们尽量不要使用。
其他
此外,document对象的其他属性和方法有:
属性或方法 | 描述 |
---|---|
document.all | 获取页面中的所有元素,相当于document.getElementsByTagName(“*”); |
document.documentElement | 获取页面中html根元素 |
document.body | 获取页面中的body元素 |
document.getElementsByClassName() | 根据元素的class属性值查询一组元素节点对象(这个方法不支持IE8及以下的浏览器) |
document.querySelector() | 根据CSS选择器去页面中查询一个元素(如果匹配到的元素有多个,则它会返回查询到的第一个元素) |
document.querySelectorAll() | 根据CSS选择器去页面中查询一组元素(会将匹配到所有元素封装到一个数组中返回,即使只匹配到一个,也是返回数组。使用则需要通过操作数组方式来使用) |
DOM操作之增加
增加操作需要从以下几步进行:
- 创建好一个元素节点对象。
- 为元素节点创建一个文本节点对象。
- 再将文本节点对象绑定给元素节点。
- 找到增加节点的目标位置的父节点对象。
- 通过父节点对象增加子节点对象的方式进行添加。
注意细节:
- document.createElement(“TagName”)用于创建一个元素节点对象。(TagName是创建元素节点的标签名字)
- document.createTextNode(“textContent”)用于创建一个文本节点对象。
- 元素节点.appendChild(文本节点对象)用于将文本信息添加到元素节点对象中去。
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DOM-添加</title>
</head>
<style>
#divMain {
location: center;
position: relative;
}
#div1 {
position:absolute;
width: 200px;
height: 500px;
margin-left: 200px;
}
#divB {
position: absolute;
width: 100px;
height: 300px;
}
button {
margin: 10px;
width: 100px;
height: 40px;
text-align: center;
background-color: pink;
}
</style>
<body>
<div id="divMain">
<div id="div1">
<ul id="place">
<li id="li1">li1</li>
<li id="li2">li2</li>
<li id="li3">li3</li>
</ul>
</div>
<div id="divB">
<button id="button1">常规添加一个li标签</button>
<button id="buttonHTML">通过innerHTML添加一个li标签</button>
<button id="button2">添加一个在li2之前的li标签</button>
</div>
</div>
</body>
<script>
//为按钮1绑定事件
var botton = document.getElementById("button1");
botton.onclick = function () {
//上述介绍的元素方法,但此方法代码冗长。
// //添加什么标签,就写什么参数
// var li = document.createElement("li");
// //添加标签的文本信息
// var liText = document.createTextNode("这是常规方法添加的li节点");
// //把文本信息添加到标签中去(将文本和标签拼接)
// li.appendChild(liText);
// //获取父节点对象
// var place = document.getElementById("place");
// //把li节点添加到父节点对象中去
// place.appendChild(li);
//对上述代码优化:(优先使用这种方式!!!!!!!!)
//添加什么标签,就写什么参数
var li = document.createElement("li");
//直接通过li添加HTML信息
li.innerHTML = "<li>这是常规方法添加的li节点</li>";
//获取父节点对象
var place = document.getElementById("place");
//把li节点添加到父节点对象中去
place.appendChild(li);
}
//为按钮buttonHTML绑定事件(此方法影响地方较大,可能会影响先前绑定的事件,不推荐使用)
var botton = document.getElementById("buttonHTML");
botton.onclick = function () {
//获取父节点对象
var place = document.getElementById("place");
place.innerHTML += "<li>这是通过innerHTML来添加的标签</li>";
}
//为按钮2绑定事件(在固定位置,li2之前创建节点)
var botton = document.getElementById("button2");
botton.onclick = function () {
//添加什么标签,就写什么参数
var li = document.createElement("li");
//添加标签的文本信息
var liText = document.createTextNode("添加一个在li2之前的li标签");
//把文本信息添加到标签中去(将文本和标签拼接)
li.appendChild(liText);
//获取父节点对象和对应子节点对象
var li2 = document.getElementById("li2");
var place = document.getElementById("place");
//把li节点添加到父节点对象中去
place.insertBefore(li,li2);
}
</script>
</html>
DOM操作之删除
DOM删除,常规主要有以下步骤:
- 获取父节点对象
- 获取子节点对象
- 通过父节点对象来删除子节点对象
注意细节:
- 删除子节点方式:父节点.removeChild(子节点对象)
- 代码中,优化情况主要是通过子节点自身的属性parentNode,来获取到父节点,然后再调用removeChild()来讲目标子节点进行删除。
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DOM-添加</title>
</head>
<style>
#divMain {
location: center;
position: relative;
}
#div1 {
position:absolute;
width: 200px;
height: 500px;
margin-left: 200px;
}
#divB {
position: absolute;
width: 100px;
height: 300px;
}
button {
margin: 10px;
width: 100px;
height: 40px;
text-align: center;
background-color: pink;
}
</style>
<body>
<div id="divMain">
<div id="div1">
<ul id="place">
<li id="li1">li1</li>
<li id="li2">li2</li>
<li id="li3">li3</li>
</ul>
</div>
<div id="divB">
<button id="button4">删除li3标签</button>
</div>
</div>
</body>
<script>
//为按钮4绑定事件(删除li3标签)
var botton = document.getElementById("button4");
botton.onclick = function () {
//常规方法
// //获取父节点对象和对应子节点对象
// var li3 = document.getElementById("li3");
// var place = document.getElementById("place");
// //把li节点添加到父节点对象中去
// place.removeChild(li3);
// 优化方法:不获取父节点对象的方法
var li3 = document.getElementById("li3");
//通过自身节点来直接获取父节点,再利用父节点来删除目标元素
li3.parentNode.removeChild(li3);
}
</script>
</html>
DOM操作之修改
DOM修改,主要有以下步骤:(修改也可以理解为替换操作)
- 创建好一个元素节点对象。
- 为元素节点创建一个文本节点对象。
- 再将文本节点对象绑定给元素节点。
- 获取父节点对象。
- 将目标节点替换成网页中(必须是父元素的子元素)的已存在子元素节点。
注意细节:
- 修改(替换)是通过:父元素对象.replaceChild(旧节点,新节点)
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DOM-添加</title>
</head>
<style>
#divMain {
location: center;
position: relative;
}
#div1 {
position:absolute;
width: 200px;
height: 500px;
margin-left: 200px;
}
#divB {
position: absolute;
width: 100px;
height: 300px;
}
button {
margin: 10px;
width: 100px;
height: 40px;
text-align: center;
background-color: pink;
}
</style>
<body>
<div id="divMain">
<div id="div1">
<ul id="place">
<li id="li1">li1</li>
<li id="li2">li2</li>
<li id="li3">li3</li>
</ul>
</div>
<div id="divB">
<button id="button3">替换li1标签</button>
</div>
</div>
</body>
<script>
//为按钮3绑定事件(替换li1标签)
var botton = document.getElementById("button3");
botton.onclick = function () {
//添加什么标签,就写什么参数
var li = document.createElement("li");
//添加标签的文本信息
var liText = document.createTextNode("这是替换li1标签的li标签");
//把文本信息添加到标签中去(将文本和标签拼接)
li.appendChild(liText);
//获取父节点对象和对应旧的子节点对象
var li1 = document.getElementById("li1");
var place = document.getElementById("place");
//把新的li节点添加到父节点对象中去
place.replaceChild(li,li1);
}
</script>
</html>
DOM操作回调函数的优化
但增删改查操作一旦变多之后,这需要写大量的重复代码,这时候可以将重复代码整理成一个函数模型,直接拿来调用即可。这样可以简化代码。
直接上代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>指定元素绑定单击响应函数</title>
</head>
<body>
<button id="test1">按钮</button>
</body>
<script>
<!-- 定义函数模型:指定元素绑定单击响应函数-->
function myClick(idStr, fun) {
var temp = document.getElementById(idStr);
temp.onclick = fun;
}
//调用函数进行测试,第一个参数为test1,第二个参数为一个function函数
myClick("test1",function (){
alert("测试成功");
});
</script>
</html>