Posted in Javascript onDecember 22, 2010
首先,jQuery事件绑定的时候,所有事件用$.data()方法存储到了$.cache里面,用data('events')可以反复获取到它们:
var $div = $('div.demo'), data = $div.data(); // 获取所有绑定事件: var events = data.events; // 除了window对象绑定事件的比较特殊: var windowEvents = $(window).data('__events__');
在必要的时候,可以检索有没有绑定相关处理函数:
var clickHandler = function(){ console.log('click test'); }; $div.click(clickHandler); events.click.some(function(ev){ return ev.handler === clickHandler; });
BUG示例
<script type="text/javascript"> Array.prototype.xyzz = function (arg) { console.log(1,this,arg); }; Array.prototype.xyzzz = function (arg) { console.log(2,this,arg); }; $(function() { $('button').click(function () { $('div.demo').clone(true).appendTo( 'body' ); }) $('div.demo').click(function () { console.log('click..'); }) }); </script>
BUG来源
// event.js, jQuery.event.add: // jQuery 1.4.1 handlers = events[ type ] = {}; // jQuery 1.4.2+ handlers = events[ type ] = []; // manipulation.js, jQuery.clone : , cloneCopyEvent(): for ( var type in events ) { for ( var handler in events[ type ] ) { jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data ); } }
在1.4.2之后,events[ type ]为数组,for...in循环会获取到数组原型上扩展的所有方法,接着绑定到DOM对象上。
解决
不扩展数组原型,不使用clone(true)方法。
hasOwnProperty检查。
使用each循环:
var self = this; for ( var type in events ) { jQuery.each(events[ type ],function(idx,evt) { jQuery.event.add( self, type, evt.handler, evt.data ); }); }
完整演示代码:
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8" /> <title>jQuery Clone Bug</title> <style type="text/css"> .demo{ margin:1em;background:#07a; height:10em; width:10em; } </style> </head> <body> <button>doClone</button> <a href="https://3water.com">返回</a> <div class="demo">click me</div> <script src="http://demo.3water.com/jslib/jquery/jquery-1.4.4.js"></script> <script type="text/javascript"> Array.prototype.xyzz = function (arg) { console.log(1,this,arg); }; Array.prototype.xyzzz = function (arg) { console.log(2,this,arg); }; $(function() { $('button').click(function () { $('div.demo').clone(true).appendTo( 'body' ); }) $('div.demo').click(function () { console.log('click..'); }) }); // var events = $('div.demo:eq(0)').data().events // manipulation.js : cloneCopyEvent // :line 372 // for ( var type in events ) { // for ( var handler in events[ type ] ) { // console.log(handler); // } // } // console.log($.isArray(events['click'])) // 原因 // event.js : event.add // :line 106 // handlers = events[ type ] = []; </script> </body> </html>
在线演示 /js/jquery_clone_bug/jQuery_clone_bug_demo.htm
jQuery Clone Bug解决代码
声明:登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。
Reply on: @reply_date@
@reply_contents@