在讲这个之前需要先理解下bind事件存在的问题
看下面代码:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title>bind存在的问题</title>
</head>
<script type="text/javascript" src="../jquery-1.8.3.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$(".abc").bind("click",{name:"abc"},function(event){
//alert(event.data.name);
alert("aaa");
})
$("#content").append("<div class='abc' >BBB</div>");
})
</script>
<body>
<div id="content">
<div class="abc">AAA</div>
</div>
</body>
</html>
<div id="content">
<div class="abc">AAA</div>
</div>
</body>
</html>
运行上面的代码大家可能会发现,后面增加的class也为acb的div此时并没有绑定事件。这个与代码的执行顺序有关,这里不多做解释。
那么我们能否有办法解决让后面添加的div也同时绑定事件呢?
使用JQuery中的live方法就可以解决。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title>解决bind存在的问题,使用Live解决</title>
</head>
<script type="text/javascript" src="../jquery-1.8.3.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$(".abc").live("click",{name:"abc"},function(event){
//alert(event.data.name);
alert($(this).html());
})
$("#content").append("<div class='abc' >BBB</div>");
})
</script>
<body>
<div id="content">
<div class="abc">AAA</div>
</div>
</body>
</html>
再次运行程序,我们会发现后面加入的div也绑定了事件。
那么为什么可以这样实现呢?如果要了解这个必须先理解事件委派和事件冒泡
看下面代码:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title>事件委派</title>
</head>
<script type="text/javascript" src="../jquery-1.8.3.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$(document).bind("click",function(event){
var obj = $(event.target).closest(".abc");
if( obj[0] == event.target)
{
alert("aaa");
}
})
})
</script>
<body>
<div id="content">
<div class="abc">AAA</div>
<div class="abc1">BBB</div>
<div class="abc2">CCC</div>
<div class="abc3">ddd</div>
</div>
<div class="abc">AAA</div>
</body>
</html>
以上代码我们为document绑定了事件,那么在其子元素发生了事件之后,子元素就会把事件冒泡给父元素,然后父元素可以根据event.target来判断事件源到底是哪个DOM节点,从而执行方法。从这个例子希望大家能够理明确一点,子元素发生了事件之后,自己并不处理事件,而是将事件委派给父元素来处理。
下面看下live的原理:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title>理解live的原理</title>
</head>
<script type="text/javascript" src="../jquery-1.8.3.js"></script>
<script type="text/javascript">
/**
* 通过这种方式可以让委派对象根据事件源来决定是否执行方法
*/
$(document).ready(function(){
$(document).bind("click",function(event){
var obj = $(event.target).closest(".abc");
if( obj[0] == event.target)
{
alert($(obj[0]).html());
}
});
$("#content").append("<div class='abc'>CCC</div>");
$("#aaa").append("<div class='abc'>BBB</div>");
})
</script>
<body>
<div id="content">
<div class="abc">AAA</div>
</div>
<div id="aaa"></div>
</body>
</html>
下面代码我们可以发现了后加的节点也绑定了事件。
但是以上代码会存在一个问题:因为我们是对document绑定了事件,在方法里面判断事件源是class为abc的才执行,但是如果我们想要
事件源是class为abc,并且父节点的id=content的话,那么就要把docuemnt改成#content,那么
$("#aaa").append("<div class='abc'>BBB</div>")加进去的div就不会执行了。
如果上面的代码使用live来实现的话,
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title>live实现</title>
</head>
<script type="text/javascript" src="../jquery-1.8.3.js"></script>
<script type="text/javascript">
/**
* 通过这种方式可以让委派对象根据事件源来决定是否执行方法
*/
$(document).ready(function(){
$(".abc","#content").live("click",function(event){
var obj = $(event.target).closest(".abc");
if( obj[0] == event.target)
{
alert($(obj[0]).html());
}
});
$("#content").append("<div class='abc'>CCC</div>");
$("#aaa").append("<div class='abc'>BBB</div>");
})
</script>
<body>
<div id="content">
<div class="abc">AAA</div>
</div>
<div id="aaa"></div>
</body>
</html>