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打开新窗口同时关闭旧窗口
Jan 16 Javascript
jquery EasyUI的formatter格式化函数代码
Jan 12 Javascript
深入理解JavaScript系列(15) 函数(Functions)
Apr 12 Javascript
javascript学习笔记(三) String 字符串类型介绍
Jun 19 Javascript
extjs tabpanel限制选项卡数量实现思路及代码
Apr 02 Javascript
jQuery实现textarea自动增长宽高的方法
Dec 18 Javascript
vue.js,ajax渲染页面的实例
Feb 11 Javascript
如何手动实现es5中的bind方法详解
Dec 07 Javascript
深入理解JS异步编程-Promise
Jun 03 Javascript
js获取对象,数组所有属性键值(key)和对应值(value)的方法示例
Jun 19 Javascript
vue中axios防止多次触发终止多次请求的示例代码(防抖)
Feb 16 Javascript
vue element实现表格合并行数据
Nov 30 Vue.js
修改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
Discuz! 5.0.0论坛程序中加入一段js代码,让会员点击下载附件前自动弹出提示窗口
2007/04/18 PHP
php之readdir函数用法实例
2014/11/13 PHP
Zend Framework连接Mysql数据库实例分析
2016/03/19 PHP
php中preg_replace正则替换用法分析【一次替换多个值】
2017/01/17 PHP
jquery实现输入框实时输入触发事件代码
2016/12/21 Javascript
详解微信小程序 wx.uploadFile 的编码坑
2017/01/23 Javascript
详解微信小程序 相对定位和绝对定位
2017/05/11 Javascript
Node.js模拟发起http请求从异步转同步的5种用法
2018/09/26 Javascript
详解如何在vue项目中使用lodop打印插件
2018/09/27 Javascript
详解vuex持久化插件解决浏览器刷新数据消失问题
2019/04/15 Javascript
JS错误处理与调试操作实例分析
2020/04/13 Javascript
Vue CLI3移动端适配(px2rem或postcss-plugin-px2rem)
2020/04/27 Javascript
vue中v-for循环选中点击的元素并对该元素添加样式操作
2020/07/17 Javascript
[01:16:01]VGJ.S vs Mski Supermajor小组赛C组 BO3 第一场 6.3
2018/06/04 DOTA
Python常用模块用法分析
2014/09/08 Python
python操作mysql数据库
2017/03/05 Python
Python如何生成树形图案
2018/01/03 Python
Python爬虫爬取一个网页上的图片地址实例代码
2018/01/16 Python
20个常用Python运维库和模块
2018/02/12 Python
如何将json数据转换为python数据
2020/09/04 Python
python获取时间戳的实现示例(10位和13位)
2020/09/23 Python
python从ftp获取文件并下载到本地
2020/12/05 Python
详解HTML5中垂直上下居中的解决方案
2017/12/20 HTML / CSS
详解移动端h5页面根据屏幕适配的四种方案
2020/04/15 HTML / CSS
路易威登和香奈儿手袋:LuxeDH
2017/01/12 全球购物
Ashford台湾:以折扣价提供奢华的男女用表款
2019/12/04 全球购物
数据库设计的包括哪两种,请分别进行说明
2016/07/15 面试题
当当网软件测试笔试题
2015/11/24 面试题
史上最全面的Java面试题汇总!
2015/02/03 面试题
促销活动方案模板
2014/02/24 职场文书
早会主持词
2014/03/17 职场文书
出生公证委托书
2014/04/03 职场文书
警示教育活动总结
2014/05/05 职场文书
个人课题方案
2014/05/08 职场文书
化工实习心得体会
2014/09/09 职场文书
医院消毒隔离制度
2015/08/05 职场文书