jQuery Clone Bug解决代码


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
Javascript 相关文章推荐
一个加载js文件的小脚本
Jun 28 Javascript
JS小功能(列表页面隔行变色)简单实现
Nov 28 Javascript
浅谈JavaScript函数参数的可修改性问题
Dec 05 Javascript
jQuery ui 利用 datepicker插件实现开始日期(minDate)和结束日期(maxDate)
May 22 Javascript
JS显示表格内指定行html代码的方法
Mar 31 Javascript
弹出遮罩层后禁止滚动效果【实现代码】
Apr 29 Javascript
使用RequireJS库加载JavaScript模块的实例教程
Jun 06 Javascript
xmlplus组件设计系列之按钮(2)
Apr 26 Javascript
express.js中间件说明详解
Mar 19 Javascript
微信小程序实现上拉加载功能示例【加载更多数据/触底加载/点击加载更多数据】
May 29 Javascript
AJAX XMLHttpRequest对象创建使用详解
Aug 20 Javascript
js实现有趣的倒计时效果
Jan 19 Javascript
修改jquery.lazyload.js实现页面延迟载入
Dec 22 #Javascript
jquery插件 autoComboBox 下拉框
Dec 22 #Javascript
Jquery截取中文字符串的实现代码
Dec 22 #Javascript
jquery里的each使用方法详解
Dec 22 #Javascript
jQuery学习笔记之jQuery的动画
Dec 22 #Javascript
jQuery学习笔记之jQuery的事件
Dec 22 #Javascript
jQuery学习笔记之jQuery的DOM操作
Dec 22 #Javascript
You might like
php仿ZOL分页类代码
2008/10/02 PHP
PHP 下载文件时如何自动添加bom头及解释BOM头和去掉bom头的方法
2016/01/04 PHP
PHP使用ActiveMQ实例
2018/02/05 PHP
学习js所必须要知道的一些
2007/03/07 Javascript
js实现双向链表互联网机顶盒实战应用实现
2011/10/28 Javascript
JavaScript日期时间与时间戳的转换函数分享
2015/01/31 Javascript
实例解析JS布尔对象的toString()方法和valueOf()方法
2015/10/25 Javascript
jquery组件WebUploader文件上传用法详解
2020/10/23 Javascript
JS判断输入的字符串是否是数字的方法(正则表达式)
2016/11/29 Javascript
Angular.js自定义指令学习笔记实例
2017/02/24 Javascript
教你5分钟学会用requirejs(必看篇)
2017/07/25 Javascript
Bootstrap datepicker日期选择器插件使用详解
2017/07/26 Javascript
vue项目优化之通过keep-alive数据缓存的方法
2017/12/11 Javascript
JS/jQuery实现简单的开关灯效果【案例】
2019/02/19 jQuery
Vue起步(无cli)的啊教程详解
2019/04/11 Javascript
自定义Vue组件打包、发布到npm及使用教程
2019/05/22 Javascript
CKEditor 4.4.1 添加代码高亮显示插件功能教程【使用官方推荐Code Snippet插件】
2019/06/14 Javascript
使用layui 的layedit定义自己的toolbar方法
2019/09/18 Javascript
node后端服务保活的实现
2019/11/10 Javascript
三步搞定:Vue.js调用Android原生操作
2020/09/07 Javascript
vue+element table表格实现动态列筛选的示例代码
2021/01/14 Vue.js
[33:23]Secret vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
python中的装饰器详解
2015/04/13 Python
使用Python编写简单的端口扫描器的实例分享
2015/12/18 Python
python 性能提升的几种方法
2016/07/15 Python
Python实现ping指定IP的示例
2018/06/04 Python
pyqt5利用pyqtDesigner实现登录界面
2019/03/28 Python
Pytorch: 自定义网络层实例
2020/01/07 Python
Django使用Profile扩展User模块方式
2020/05/14 Python
Python如何使用ElementTree解析xml
2020/10/12 Python
html5将图片转换成base64的实例代码
2016/09/21 HTML / CSS
初中数学教学反思
2014/01/16 职场文书
如何写一份好的英文求职信
2014/03/19 职场文书
欢迎横幅标语
2014/06/17 职场文书
python 中[0]*2与0*2的区别说明
2021/05/10 Python
在Centos 8.0中安装Redis服务器的教程详解
2022/03/21 Redis