想实现一个效果
① 点击btn按钮 可以添加一个li标签(li标签里面有文本内容和点击删除的span标签)
② 点击每个li标签 可以实现li标签变换背景颜色
③ 点击每个li标签中的span标签 可以实现删除所在的li标签
1. 普通过程函数书写
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
list-style: none;
}
li {
height: 30px;
line-height: 30px;
background-color: lightblue;
margin-bottom: 5px;
}
span {
float: right;
width: 20px;
height: 20px;
font-size: 20px;
cursor: pointer;
}
#btn {
width: 100px;
height: 30px;
}
</style>
</head>
<body>
<ul id="list">
<li><span>×</span></li>
<li><span>×</span></li>
<li><span>×</span></li>
<li><span>×</span></li>
<li><span>×</span></li>
<li><span>×</span></li>
</ul>
<button id="btn">添加li</button>
<script type="text/javascript">
// 要求: 点击btn 添加li 点击li 背景颜色改变, 点击span 删除li
// 获取元素
var ul = document.getElementById("list");
var btn = document.getElementById("btn");
// 获取所有li 和 span
var lis = document.getElementsByTagName("li");
var spans = document.getElementsByTagName("span");
// 改变li的背景色
for (var i = 0; i < lis.length; i++) {
lis[i].onclick = click;
}
// 循环span
for (var i = 0; i < spans.length; i++) {
spans[i].onclick = i_click;
}
// 添加事件
btn.onclick = function() {
// 创建li
var li = document.createElement("li");
li.onclick = click;
// 创建span
var span = document.createElement("span");
span.onclick = i_click;
span.innerHTML = "×";
// 添加span
li.appendChild(span);
// 添加li元素
ul.appendChild(li)
}
// 提取函数
function click() {
this.style.backgroundColor = "red"
}
// 定义函数
function i_click() {
this.parentNode.parentNode.removeChild(this.parentNode);
this.onclick = null;
this.parentNode.onclick = null;
}
// 内存泄漏: 不能被回收的内存我们称它为泄露的内存, 这种现象叫做内存泄漏。
// 解决方式: 当移除一个元素的时候, 确保它的身上没有事件。
</script>
</body>
</html>
会发现出现几个问题:
① 内存泄漏: 不能被回收的内存我们称它为泄露的内存, 这种现象叫做内存泄漏。
解决方式: 当移除一个元素的时候, 确保它的身上没有事件。
② 无法给动态生成的节点添加事件
解决方式:第一个问题进行再添加节点的时候添加事件,但是都会给每个添加的新元素进行添加新的相同事件,造成事件数量特别多,占用巨大的内存,所以进行优化,封装成一个函数进行添加事件
③ 最终发现 只是实现一个小功能,但是用了这么多的代码去实现,复杂而且重用性不高
2. 使用委托模式
① 给事件发生的上一层最近的父元素绑定事件
② 用event.target去寻找事件触发的具体对象 进行实现事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
list-style: none;
}
li {
height: 30px;
line-height: 30px;
background-color: lightblue;
margin-bottom: 5px;
}
span {
float: right;
width: 20px;
height: 20px;
font-size: 20px;
cursor: pointer;
}
#btn {
width: 100px;
height: 30px;
}
</style>
</head>
<body>
<ul id="list">
<li><span>×</span></li>
<li><span>×</span></li>
<li><span>×</span></li>
<li><span>×</span></li>
<li><span>×</span></li>
<li><span>×</span></li>
</ul>
<button id="btn">添加li</button>
<script type="text/javascript">
// 要求: 点击btn 添加li 点击li 背景颜色改变, 点击span 删除li
// 获取元素
var ul = document.getElementById("list");
var btn = document.getElementById("btn");
// 添加点击事件
btn.onclick = function() {
ul.innerHTML += "<li><span>×</span></li>"
}
// 委托模式可以解决: 1 预言未来元素 2 防止内存泄漏 3 减少事件数量
ul.onclick = function(e) {
// console.log(e.target)
// 进行判定点击的是哪个元素
if (e.target.nodeName.toLowerCase() === "span") {
// 此时e.target是span
this.removeChild(e.target.parentNode);
} else if (e.target.nodeName.toLowerCase() === "li") {
// 此时e.target是li
e.target.style.backgroundColor = "red"
}
}
</script>
</body>
</html>