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 相关文章推荐
一个可以兼容IE FF的加为首页与加入收藏实现代码
Nov 02 Javascript
网络之美 JavaScript中Get和Set访问器的实现代码
Sep 19 Javascript
jQuery多条件筛选如何实现
Nov 04 Javascript
jQuery中数据缓存$.data的用法及源码完全解析
Apr 29 Javascript
JS+HTML5手机开发之滚动和惯性缓动实现方法分析
Jun 12 Javascript
Bootstrap源码解读排版(1)
Dec 23 Javascript
JS判断两个对象内容是否相等的方法示例
Apr 10 Javascript
JS使用tofixed与round处理数据四舍五入的区别
Oct 25 Javascript
vue2 mint-ui loadmore实现下拉刷新,上拉更多功能
Mar 21 Javascript
使用puppeteer爬取网站并抓出404无效链接
Dec 20 Javascript
小程序云函数调用API接口的方法
May 17 Javascript
vue实现一个6个输入框的验证码输入组件功能的实例代码
Jun 29 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实现将GB编码转换为UTF8
2006/11/25 PHP
PHP Zip压缩 在线对文件进行压缩的函数
2010/05/26 PHP
PDO预处理语句PDOStatement对象使用总结
2014/11/20 PHP
PHP简单读取PDF页数的实现方法
2016/07/21 PHP
php中上传文件的的解决方案
2018/09/25 PHP
PHP的mysqli_set_charset()函数讲解
2019/01/23 PHP
laravel5.1框架基础之Blade模板继承简单使用方法分析
2019/09/05 PHP
利用Dojo和JSON建立无限级AJAX动态加载的功能模块树
2007/03/24 Javascript
Javascript 同时提交多个Web表单的方法
2009/02/19 Javascript
关于window.pageYOffset和document.documentElement.scrollTop
2011/04/05 Javascript
js open() 与showModalDialog()方法使用介绍
2013/09/10 Javascript
jquery实现向下滑出的二级导航下滑菜单效果
2015/08/25 Javascript
JavaScript版经典游戏之扫雷游戏完整示例【附demo源码下载】
2016/12/12 Javascript
微信小程序开发(二)图片上传+服务端接收详解
2017/01/11 Javascript
react native与webview通信的示例代码
2017/09/25 Javascript
jQuery中库的引用方法
2018/01/06 jQuery
js合并两个数组生成合并后的key:value数组
2018/05/09 Javascript
vue element动态渲染、移除表单并添加验证的实现
2019/01/16 Javascript
使用Python的Treq on Twisted来进行HTTP压力测试
2015/04/16 Python
Python中的数据对象持久化存储模块pickle的使用示例
2016/03/03 Python
Python实现线程状态监测简单示例
2018/03/28 Python
如何通过Python实现标签云算法
2019/07/02 Python
django 多对多表的创建和插入代码实现
2019/09/09 Python
Anconda环境下Vscode安装Python的方法详解
2020/03/29 Python
德国古洛迷亚百货官网:GALERIA Kaufhof
2017/06/20 全球购物
介绍Java的内部类
2012/10/27 面试题
大学生求职简历的自我评价范文
2013/10/12 职场文书
会计专业毕业生自我鉴定
2013/10/29 职场文书
优良学风班申请材料
2014/02/13 职场文书
工程项目经理任命书
2014/06/05 职场文书
个人股份转让协议书范本
2014/10/26 职场文书
2014年团总支工作总结
2014/11/21 职场文书
委托公证书格式
2015/01/26 职场文书
python scipy 稀疏矩阵的使用说明
2021/05/26 Python
最新动漫情报:2022年7月新番定档超过30部, OVERLORD骨王第四季也在其中噢
2022/05/04 日漫
2022微信温控新功能上线
2022/05/09 数码科技