前言:
动态生成的 DOM 元素之所以无法绑定事件,是因为 JS 在初次加载时就已经把对应的DOM 元素事件监听工作做完了,在事件监听的容器中已经包含了对应的 DOM 元素对象,而由用户交互而动态生成的 DOM 元素由于无法引起页面重载,所以自然无法再加入到事件监听容器中。
解决方案:可以通过事件委托的方式来实现为动态生成的元素绑定事件。
事件委托原理:以父元素的名义定义事件,但事件内部却是通过 e.target 实时获取到用户点击的子元素,并对该子元素进行操作处理。
重点在于事件中触发的 Event 事件对象中的 e.target 这个对象可以实时获取当前页面点击的 DOM 元素对象,这就很灵性了,我们完全可以点击动态生成的 DOM 元素,并在事件委托函数中对该元素做出处理。
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
ul {
list-style: none;
height: auto;
margin: 20px auto;
overflow: hidden;
}
li {
width: 70px;
height: 200px;
float: left;
background-color: cadetblue;
}
li:nth-of-type(2n) {
background-color: blueviolet;
}
</style>
</head>
<body>
<ul>
<li></li>
<li></li>
</ul>
<button>生成 li</button>
<script>
let lis = document.querySelectorAll('li');
lis.forEach(li => {
li.addEventListener('click',()=> {
console.log(1);
})
});
let button = document.querySelector('button');
button.addEventListener('click',()=> {
let li = document.createElement('li');
document.querySelector('ul').appendChild(li);
});
</script>
</body>
</html>
效果:
可以看出,为使用事件委托之前,动态生成的 DOM 元素是无法绑定事件的。
所以可以通过事件委托的方式来解决:
<script>
let ul = document.querySelector('ul');
ul.addEventListener('click',(e)=> {
let target = e.target; // 获取当前点击的目标子元素
console.log(target);
if(target.nodeName = 'LI'){
console.log(1);
}
});
let button = document.querySelector('button');
button.addEventListener('click', () => {
let li = document.createElement('li');
document.querySelector('ul').appendChild(li);
});
</script>
效果: