jQuery最常用的一个功能就是对DOM的操作,与之相关的比如对事件的绑定和Ajax动态内容加载。当我们绑定事件到Ajax load回来的内容上或其他动态创建的元素上时会发现事件没响应,和你预想的结果不同,就像没这会事儿一样。这是前端开发 非常蛋疼的问题。jQuery在1.3的版本里面引入了.live()方法,后来jQuery团队有在这基础上加入了.delegate()和.on()方法来解决这种尴尬的局面。大家可以根据你自己项目使用的jQuery版本不同选择下面的不同方法解决这个问题。
举个例子,假设我们有这样一个页面:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script>
$(document).ready(function(){
$('button').click(function(){
$('ol').append('<li><a href="#">动态增加的节点</a></li>');
});
});
</script>
</head>
<body>
<ol>
<li>
<a href="#">静态节点连接</a>
</li>
</ol>
<button>增加节点</button><pre name="code" class="html">// 简单粗暴,直接绑定到DOM对象
$(document).on('click', 'a', function(){
alert( $(this).text() );
return false;
});
</body></html>
我们要解决的问题就是当点增加节点按钮时动态在ol下面添加一个节点并且给这个节点绑定alert事件。
jQuery > 1.7.0 - 使用 .on() 事件绑定方法
如果你项目中使用的jQuery版本高于1.7.0,那么推荐使用
.on() 方法,这个方法能够直接绑定和代理事件。根据我们要实现的需求,我们需要使用代理事件来解决问题,也就是说我们吧事件的绑定交给父级元素,如何使用选择器去实现事件绑定,来看一下代码:
//正确的做法
$('ol').on('click', 'a', function(){
alert( $(this).text() );
});
我们是首先把事件绑定到父级元素/或者说是容器,再通过类选择器找到"a"元素,然后把事件传递到动态创建的子元素上。我们必须要把事件绑定放到父级,不然像下面这样的代码是不得行的:
//这样的代码是不行的 $('a').on('click', function(){ alert( $(this).text() ); });
如果是单个事件的绑定,那推荐使用这种事件绑定方法,这样能够很好的提升性能。如果你不知道父类元素,你甚至可以绑定到 document 对象,不过这样绑定像click这样的简单事件还行,换成是mousemove那可能对性能就有比较大的影响更多关于 .on() 方法的介绍,请看官方说明http://api.jquery.com/on/// 简单粗暴,直接绑定到DOM对象 $(document).on('click', 'a', function(){ alert( $(this).text() ); });
1.7 > jQuery >1.4.2 - 使用 .delegate() 事件绑定方法
.delegate()方法是 .on() 方法的前辈,在使用方法和性能方面都和.on() 方法类似,看代码:// 具体父级元素绑定 $('ol').delegate('a', 'click', function(){ alert( $(this).text() ); }); // 绑定到DOM对象 $(document).delegate('a', 'click', function(){ alert( $(this).text() ); });
更多关于 .delegate() 方法的介绍,请看官方说明http://api.jquery.com/delegate/
1.4.2 > jQuery > 1.3 - 使用 .live() 事件绑定方法
.live()这个方法应该是属于元老级的了,在jQuery 1.3的版本里面首次出现,就是为了解决绑定事件到动态元素的问题,这个在jQuery 1.7的版本里属于是弃用的方法,jQuery 1.9以后就直接删除了。
需要注意的是这个方法是实现原理是把事件绑定到document对象,然后通过选择器和目标事件比较,如果匹配就触发事件,前提条件要好保证事件的必须是连续正常执行的,如果其中一个事件出问题了,那所有的事件都不会触发,另外,如果从document上取消事件绑定,那么所有通过.live()方法绑定的事件都会取消。看代码:// .live()实现动态绑定 $('li').live('click', function(){ alert( $(this).text() ); });
更多关于 .live() 方法的介绍,请看官方说明http://api.jquery.com/live/
1.3 > jQuery - 使用 .bind() 事件绑定方法
如果你的项目还在使用jQuery 1.3~以前的版本,那好最升级一下,实在没法升级,那就按照下面两个方法来解决这个问题。1、自己实现事件的传递,类似上面的.live()方法
2、明确的对动态加载的内容做操作,比如加上相应的css,重新绑定事件$('ol').click(functino(event){ if( $(event.target).is('a') ){ alert( $(this).text() ); } });
$(document).ready(function(){ $('button').click(function(){ $('ol').append('<li class="dynamic-item"><a href="#">动态增加的节点</a></li>'); // 然后在绑定新的事件 $('a.dynamic-item:last').click(functino(){ alert( $(this).text() ); return false; }); }); });
注:
不要把同一事件绑定到相同元素多次尽量避免使用直接绑定到document对象,可以预先定义一个div, 比如<div id="ajax-loaded-container"></div>, 然后使用$('#ajax-loaded-container .my-link').click(...)这样的方法去实现需要动态绑定的css也可以在服务器端的css文件里预先定义好