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 相关文章推荐
一些常用弹出窗口/拖放/异步文件上传等实用代码
Jan 06 Javascript
jQuery实现不断闪烁文字的方法
May 15 Javascript
JavaScript中使用Math.floor()方法对数字取整
Jun 15 Javascript
简单实现js选项卡切换效果
Feb 03 Javascript
jQuery 选择同时包含两个class的元素的实现方法
Jun 01 Javascript
Bootstrap + AngularJS 实现简单的数据过滤字符查找功能
Jul 27 Javascript
JS获取当前地理位置的方法
Oct 25 Javascript
基于jquery trigger函数无法触发a标签的两种解决方法
Jan 06 jQuery
vue fetch中的.then()的正确使用方法
Apr 17 Javascript
TypeScript 引用资源文件后提示找不到的异常处理技巧
Jul 15 Javascript
一文秒懂JavaScript构造函数、实例、原型对象以及原型链
Aug 25 Javascript
小程序实现上下切换位置
Nov 16 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之第八天
2006/10/09 PHP
简单的cookie计数器实现源码
2013/06/07 PHP
php强制运行广告的方法
2014/12/01 PHP
Yii配置文件用法详解
2014/12/04 PHP
PHP实现PDO的mysql数据库操作类
2014/12/12 PHP
Zend Framework教程之前端控制器Zend_Controller_Front用法详解
2016/03/07 PHP
PHP全局使用Laravel辅助函数dd
2019/12/26 PHP
用JavaScript实现动画效果的方法
2013/07/20 Javascript
JS查找字符串中出现次数最多的字符
2016/09/05 Javascript
js实现3D图片展示效果
2017/03/09 Javascript
基于JavaScript实现活动倒计时效果
2017/04/20 Javascript
微信小程序实现action-sheet弹出底部菜单功能【附源码下载】
2017/12/09 Javascript
超详细动手搭建一个VuePress 站点及开启PWA与自动部署的方法
2019/01/27 Javascript
vue 项目打包时样式及背景图片路径找不到的解决方式
2019/11/12 Javascript
JS造成内存泄漏的几种情况实例分析
2020/03/02 Javascript
解决Vue中使用keepAlive不缓存问题
2020/08/04 Javascript
ES5和ES6中类的区别总结
2020/12/21 Javascript
Selenium 模拟浏览器动态加载页面的实现方法
2018/05/16 Python
Python3.6.0+opencv3.3.0人脸检测示例
2018/05/25 Python
tensorflow实现图像的裁剪和填充方法
2018/07/27 Python
django富文本编辑器的实现示例
2019/04/10 Python
在pyqt5中QLineEdit里面的内容回车发送的实例
2019/06/21 Python
anaconda中更改python版本的方法步骤
2019/07/14 Python
pandas的排序和排名的具体使用
2019/07/31 Python
Pycharm中Python环境配置常见问题解析
2020/01/16 Python
Python 利用Entrez库筛选下载PubMed文献摘要的示例
2020/11/24 Python
与世界上最好的跑步专业品牌合作:Fleet Feet
2019/03/22 全球购物
Eclipse面试题
2014/03/22 面试题
写好求职信第一句话的技巧
2013/10/26 职场文书
自我评价范文点评
2013/12/04 职场文书
毕业生求职自荐书范文
2014/03/27 职场文书
小学先进集体事迹材料
2014/05/31 职场文书
球队口号
2014/06/18 职场文书
群众路线教育实践活动心得体会(四风)
2014/11/03 职场文书
捐资助学感谢信
2015/01/21 职场文书
2016婚礼主持词开场白
2015/11/24 职场文书