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 相关文章推荐
基于jQuery实现表格数据的动态添加与统计的代码
Jan 31 Javascript
jquery向.ashx文件post中文乱码问题的解决方法
Mar 28 Javascript
JQuery扩展插件Validate—4设置错误提示的样式
Sep 05 Javascript
扩展Jquery插件处理mouseover时内部有子元素时发生样式闪烁
Dec 08 Javascript
JS、CSS以及img对DOMContentLoaded事件的影响
Aug 12 Javascript
jQuery实现form表单元素序列化为json对象的方法
Dec 09 Javascript
Node.js程序中的本地文件操作用法小结
Mar 06 Javascript
AngularJs上传前预览图片的实例代码
Jan 20 Javascript
vue使用iframe嵌入网页的示例代码
Jun 09 Javascript
了解重排与重绘
May 29 Javascript
JS查找孩子节点简单示例
Jul 25 Javascript
vue实现按钮切换图片
Jan 20 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
浅谈php中mysql与mysqli的区别分析
2013/06/10 PHP
php选择排序法实现数组排序实例分析
2015/02/16 PHP
php实现短信发送代码
2015/07/05 PHP
jquery键盘事件使用介绍
2011/11/01 Javascript
多种方法实现JS动态添加事件
2013/11/01 Javascript
JS判断表单输入是否为空(示例代码)
2013/12/23 Javascript
jQuery获取标签文本内容和html内容的方法
2015/03/27 Javascript
原生JS实现仿淘宝网左侧商品分类菜单效果代码
2015/09/10 Javascript
全面解析JavaScript中“&amp;&amp;”和“||”操作符(总结篇)
2016/07/18 Javascript
jQuery替换节点用法示例(使用replaceWith方法)
2016/09/08 Javascript
JavaScript中boolean类型之三种情景实例代码
2016/11/21 Javascript
AngularJS中的缓存使用
2017/01/11 Javascript
js 判断登录界面的账号密码是否为空
2017/02/08 Javascript
javascript基础知识之html5轮播图实例讲解(44)
2017/02/17 Javascript
bootstrap fileinput组件整合Springmvc上传图片到本地磁盘
2017/05/11 Javascript
详解vue-cli 快速搭建单页应用之遇到的问题及解决办法
2018/03/01 Javascript
jQuery对底部导航进行跳转并高亮显示的实例代码
2019/04/23 jQuery
微信小程序开发常见问题及解决方案
2019/07/11 Javascript
react用Redux中央仓库实现一个todolist
2019/09/29 Javascript
微信小程序实现同时上传多张图片
2020/02/03 Javascript
JavaScript实现左右滚动电影画布
2020/02/06 Javascript
JS常见错误(Error)及处理方案详解
2020/07/02 Javascript
谈谈JavaScript中的垃圾回收机制
2020/09/17 Javascript
利用JavaScript为句子加标题的3种方法示例
2021/01/05 Javascript
[02:28]DOTA2 2015国际邀请赛中国区预选赛首日现场百态
2015/05/26 DOTA
利用Python画ROC曲线和AUC值计算
2016/09/19 Python
详解 Python 与文件对象共事的实例
2017/09/11 Python
Python对象属性自动更新操作示例
2018/06/15 Python
numpy 计算两个数组重复程度的方法
2018/11/07 Python
python采集微信公众号文章
2018/12/20 Python
Python使用while循环花式打印乘法表
2019/01/28 Python
Python爬虫——爬取豆瓣电影Top250代码实例
2019/04/17 Python
python使用百度文字识别功能方法详解
2019/07/23 Python
乌克兰的第一家手表店:Deka
2020/03/05 全球购物
勤俭节约倡议书
2014/04/14 职场文书
土建工程师岗位职责
2014/06/10 职场文书