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 相关文章推荐
json原理分析及实例介绍
Nov 29 Javascript
js重写alert控件(适合学习js的新手朋友)
Aug 24 Javascript
JS实现控制表格只显示行边框或者只显示列边框的方法
Mar 31 Javascript
在javascript中随机数 math random如何生成指定范围数值的随机数
Oct 21 Javascript
jQuery的deferred对象使用详解
Sep 25 Javascript
D3.js封装文本实现自动换行和旋转平移等功能
Oct 14 Javascript
EditPlus中的正则表达式 实战(4)
Dec 15 Javascript
浅谈js停止事件冒泡 阻止浏览器的默认行为(阻止超连接 #)
Feb 08 Javascript
angular十大常见问题
Mar 07 Javascript
js实现canvas保存图片为png格式并下载到本地的方法
Aug 31 Javascript
详解JavaScript中的强制类型转换
Apr 15 Javascript
Vue实现仿iPhone悬浮球的示例代码
Mar 13 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实现即时输出、实时输出内容方法
2015/05/27 PHP
PHP版QQ互联OAuth示例代码分享
2015/07/05 PHP
Laravel框架使用Seeder实现自动填充数据功能
2018/06/13 PHP
IE和Firefox在JavaScript应用中的兼容性探讨
2008/04/01 Javascript
一个可以随意添加多个序列的tag函数
2009/07/21 Javascript
js闭包实现按秒计数
2015/04/23 Javascript
jquery使用经验小结
2015/05/20 Javascript
JavaScript中pop()方法的使用教程
2015/06/09 Javascript
JavaScript清空数组元素的两种方法简单比较
2015/07/10 Javascript
判断JS对象是否拥有某属性的方法推荐
2016/05/12 Javascript
jQuery Ajax 全局调用封装实例代码详解
2016/06/02 Javascript
JS实现选定指定HTML元素对象中指定文本内容功能示例
2017/02/13 Javascript
javascript 使用正则test( )第一次是 true,第二次是false
2017/02/22 Javascript
bootstrap3-dialog-master模态框使用详解
2017/08/22 Javascript
weui框架实现上传、预览和删除图片功能代码
2017/08/24 Javascript
vue里如何主动销毁keep-alive缓存的组件
2019/03/21 Javascript
回顾Javascript React基础
2019/06/15 Javascript
Javascript异步编程async实现过程详解
2020/04/02 Javascript
详解Python中的文本处理
2015/04/11 Python
对python字典元素的添加与修改方法详解
2018/07/06 Python
python numpy存取文件的方式
2020/04/01 Python
对python中各个response的使用说明
2020/03/28 Python
python调用API接口实现登陆短信验证
2020/05/10 Python
使用matlab 判断两个矩阵是否相等的实例
2020/05/11 Python
使用python-cv2实现Harr+Adaboost人脸识别的示例
2020/10/27 Python
浅析Python的命名空间与作用域
2020/11/25 Python
使用Html5、CSS实现文字阴影效果
2018/01/17 HTML / CSS
基于html5绘制圆形多角图案
2016/04/21 HTML / CSS
法国和欧洲海边和滑雪度假:Pierre & Vacances
2017/01/04 全球购物
荷兰游戏商店:Allyouplay
2019/03/16 全球购物
机械电子工程专业推荐信范文
2013/11/20 职场文书
销售经理工作职责范文
2013/12/03 职场文书
《圆明园的毁灭》教学反思
2014/02/28 职场文书
酒店开业庆典策划方案
2014/05/28 职场文书
同事打架检讨书
2015/05/06 职场文书
Java8 Stream API 提供了一种高效且易于使用的处理数据的方式
2022/04/13 Java/Android