昨天有个前端的朋友问我一个问题:在动态添加元素后元素绑定的事件不生效。他大致讲了一下,就是一个列表ul,里面的li元素是动态生成的,他事先在js中使用$("ul li").on(),绑定了事件,但是动态增加了li元素后发现点击事件都没生效。。。。
一听我就知道问题所在了,在动态添加了元素之后需要重新为新添加的元素绑定事件才会生效。另外我也很意外,这么简单的问题居然还有人不知道。仔细一想,可能有些人平时不太注意这些问题,然后才会被困扰。那么我在这里也将这个问题发一下,希望遇到这个问题的朋友能快速找到答案并解决。
下面请看demo,里面有注释就不详细写,
二个注意点:
1.动态添加元素后,再通过jq或者其他方式动态绑定事件,事件就会生效;
2.动态添加元素的时候,直接声明元素的onclick事件,事件也是生效的。
Demo:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title></title>
<script type="text/javascript" src="js/jquery-1.8.0.min.js"></script>
</head>
<body>
<style>
ul li {
width: 300px;
}
.wrap {
display: flex;
}
.btn {
margin: 10px;
padding: 10px;
border-radius: 5px;
}
.active {
color: white;
background: blue;
}
</style>
<div class="wrap">
<div class="btn btn1 active">绑定事件</div>
<div class="btn btn2">自带click事件</div>
<div class="btn btn3">不绑定事件</div>
</div>
<ul style="width: 300px;">
<li>原有的li</li>
</ul>
<script>
$(function() {
//1.这样给li绑定事件,只有静态页面中存在了的li才会触发
$("ul li").on("click", showHtml)
$(".btn1").on("click", addLi1);
$(".btn2").on("click", addLi2);
$(".btn3").on("click", addLi3);
//2.动态增加li,增加后再为li绑定事件,事件会触发
function addLi1() {
$(".btn1").removeClass("active").addClass("active").siblings().removeClass("active");
var htm = "";
for(var i = 0; i < 3; i++) {
htm += '<li >新增后绑定事件的li' + i + '</li>';
}
$("ul").append(htm);
//动态添加后为li动态绑定事件
$("ul li").unbind("click").on("click", showHtml);
}
//3.动态添加li,并且在元素上直接绑定事件,事件有效
function addLi2() {
$(".btn2").removeClass("active").addClass("active").siblings().removeClass("active");
var htm = "";
for(var i = 0; i < 3; i++) {
htm += '<li onclick="showHtml(this)">自带click事件的li' + i + '</li>';
}
$("ul").append(htm);
}
//4.动态增加li,增加完成后不再另行绑定事件,不会触发(1)步骤绑定的事件
function addLi3() {
$(".btn3").removeClass("active").addClass("active").siblings().removeClass("active");
var htm = "";
for(var i = 0; i < 3; i++) {
htm += '<li >无事件的li' + i + '</li>';
}
$("ul").append(htm);
}
})
function showHtml(e) {
alert("我有事件");
}
</script>
</body>
</html>