昨天有個前端的朋友問我一個問題:在動態添加元素後元素綁定的事件不生效。他大致講了一下,就是一個列表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() {
$(".btn2").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() {
$(".btn3").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() {
$(".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);
}
})
function showHtml(e) {
alert("我有事件");
}
</script>
</body>
</html>