jQuery Clone Bug解决代码 |
本文标签:jQuery,Clone,Bug 首先,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="http://www.jb51.net">返回</a> <div class="demo">click me</div> <script src="http://demo.jb51.net/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 |