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 相关文章推荐
JavaScript CSS菜单功能 改进版
Dec 20 Javascript
jQuery(非HTML5)可编辑表格实现代码
Dec 11 Javascript
js弹出模式对话框,并接收回传值的方法
Mar 12 Javascript
简单常用的幻灯片播放实现代码
Sep 25 Javascript
javascript不可用的问题探究
Oct 01 Javascript
JS辨别访问浏览器判断是android还是ios系统
Aug 19 Javascript
jquery图片播放浏览插件prettyPhoto使用详解
Dec 19 Javascript
jQuery ajax请求返回list数据动态生成input标签,并把list数据赋值到input标签
Mar 29 Javascript
JS实现鼠标框选效果完整实例
Jun 20 Javascript
jquery心形点赞关注效果的简单实现
Nov 14 Javascript
浅谈Node Inspector 代理实现
Oct 19 Javascript
layui给下拉框、按钮状态、时间赋初始值的方法
Sep 10 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上传文件的增强函数
2010/07/21 PHP
深入Nginx + PHP 缓存详解
2013/07/11 PHP
查找php配置文件php.ini所在路径的二种方法
2014/05/26 PHP
php+xml实现在线英文词典查询的方法
2015/01/23 PHP
PHP中生成UUID自定义函数分享
2015/06/10 PHP
PHP的Yii框架中移除组件所绑定的行为的方法
2016/03/18 PHP
Yii框架中jquery表单验证插件用法示例
2016/10/18 PHP
yii框架使用分页的方法分析
2019/07/25 PHP
JavaScript中的16进制字符(改进)
2011/11/21 Javascript
jquery插件珍藏(图片局部放大/信息提示框)
2013/01/08 Javascript
javascript 获取模态窗口的滚动位置代码
2013/08/06 Javascript
jQuery EasyUI右键菜单实现关闭标签/选项卡
2016/10/10 Javascript
在JSP中如何实现MD5加密的方法
2016/11/02 Javascript
AngularJS自定义指令详解(有分页插件代码)
2017/06/12 Javascript
使用Vue动态生成form表单的实例代码
2018/04/26 Javascript
浅谈AngularJS中$http服务的简单用法
2018/05/15 Javascript
Angular5中状态管理的实现
2018/09/03 Javascript
基于elementUI实现图片预览组件的示例代码
2019/03/31 Javascript
在vue中获取微信支付code及code被占用问题的解决方法
2019/04/16 Javascript
JavaScript 斐波那契数列 倒序输出 输出100以内的质数代码实例
2019/09/11 Javascript
关于在LayUI中使用AJAX提交巨坑记录
2019/10/25 Javascript
Javascript中的奇葩知识,你知道吗?
2021/01/25 Javascript
六个窍门助你提高Python运行效率
2015/06/09 Python
Python3 修改默认环境的方法
2019/02/16 Python
pandas factorize实现将字符串特征转化为数字特征
2019/12/19 Python
Python输出指定字符串的方法
2020/02/06 Python
详解用Python进行时间序列预测的7种方法
2020/03/13 Python
keras中模型训练class_weight,sample_weight区别说明
2020/05/23 Python
英国最大的线上保健品零售商之一:Vitamin Planet
2016/12/01 全球购物
FirstCry阿联酋儿童和婴儿产品网上购物:FirstCry.ae
2021/02/22 全球购物
加拿大著名的奢侈品购物网站:SSENSE(支持中文)
2020/06/25 全球购物
软件生产职位结构化面试主要考察要素及面试题库
2015/06/12 面试题
社会实践自我鉴定
2013/11/07 职场文书
集体备课反思
2014/02/12 职场文书
主持人开幕词
2015/01/29 职场文书
「约定的梦幻岛」作画发布诺曼生日新绘
2022/03/21 日漫