浅谈 jQuery 事件源码定位问题


Posted in Javascript onJune 18, 2014

昨天群里有人问了个事件源码定位的问题,简单描述下是这样的。

在一个不是自己写的页面上,如何快速定位到他绑定的事件代码在哪?(页面用的是jQuery)
这个问题,说难不难,说简单也没那么简单,万一用的是委托之类也会麻烦点。

在 chrome 的控制台里有个 Event Listeners,这里会显示你所选择元素的事件,如果是原生事件,他会直接显示,
你点击一下事件就会跳到对应代码里了,可是 jQuery 绑定的事件却不是这样的,你点击后只会跳到 jQuery 源码里,
min后的jQuery源码密密麻麻的,看着都眼花。

浅谈 jQuery 事件源码定位问题

浅谈 jQuery 事件源码定位问题

关于jQuery对于事件的管理,大牛们也分析的非常透彻了,我就不??铝耍?蛭?皇俏颐墙裉煲?档闹氐恪?br /> 我们要说的重点是怎么定位到事件源码处。因为jQuery版本众多,而且重构过多次,所以要分情况来说了。

基本上 1.2.6-1.8 和 1.9 两种情况,经过测试,大体上定为下面2个版本
1.2.6-1.8 用  $.data( elem, "events", undefined, true ); 
1.9+ 用  $._data( elem, "events" ); 

PS: 你现在也可以按 F12 打开控制台看看结果,当然也可以复制下面的源码自己测试。
由于谷歌被墙的厉害,所以把cdn换成百度的了。2014-06-07

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>test</title>
  <script src="http://libs.baidu.com/jquery/1.4.0/jquery.js"></script>
</head>

<body>
  <input type="button" id="testbtn" value="testbtn" />
  <script>
    var version = ["1.2.6", "1.3.0", "1.4.0", "1.5.0", "1.6.0", "1.7.0", "1.8.0", "1.9.0", "1.10.0"],
      elem = $("#testbtn")[0], // 待操作的元素
      url, // jquery 地址
      jq = null, // 保存新的jquery句柄
      jqver, // jqury 版本
      fn; // 函数句柄

    for (var i = 0; i < version.length; i++) {
      url = "http://libs.baidu.com/jquery/" + version[i] + "/jquery.min.js";

      $.getScript(url, function() {
        jq = $.noConflict(true); // 释放控制权
        jqver = jq.fn.jquery; // 当前 jquery 版本
        fn = new Function('ver_' + jqver.replace(/\./g, "_"), ''); // 生成类似 function (ver_1_9_0) {} 这样的函数
        jq(elem).click(fn).click(fn).bind("test", fn); // 普通事件和自定义事件

        console.log(
          jqver,
          jq.data && jq.data(elem, "events", undefined, true),
          jq._data && jq._data(elem, "events")
        );
      });
    }
  </script>
</body>
</html>

如果不出意外,你可以在控制台看到这样的显示结果
浅谈 jQuery 事件源码定位问题

展开后可以看到绑定的函数参数里的版本和当前版本是对应的。
浅谈 jQuery 事件源码定位问题

 

可以看到
1.2.6-1.4 只支持  $.data( elem, "events", undefined, true ); 
1.5-1.8 两者都支持
1.9-1.11 只支持  $._data( elem, "events" ); 

那么我们可以写个函数简单的兼容下,然他全兼容即可

function lookEvents (elem) {
  return $.data ? $.data( elem, "events", undefined, true ) : $._data( elem, "events" );
}

现在调用 lookEvents 就可以得到对应的 events 对象了。

虽然可以看到了我们绑定的自定义事件,但还是不知道他在哪个文件哪一行啊。

下面我们就来定位他的具体位置,我们就拿 1.7 的试试。
PS: 下面操作都是在控制台完成,我的环境是 chrome 34

function lookEvents (elem) {
  return $.data ? $.data( elem, "events", undefined, true ) : $._data( elem, "events" );
}
var event = lookEvents($("#testbtn")[0]); // 获取绑定的事件
event.click[0].handler // 获取click事件的第一个事件源码地址

复制到控制台,按回车运行后,不出意外可以看到下面这个结果。

浅谈 jQuery 事件源码定位问题

有没有看到右下角的 1.html:36 这个就是源码所在的文件和对应的行号了。
你可以直接点击 1.html:36 跳到对应的代码处,是不是觉得很给力啊。

浅谈 jQuery 事件源码定位问题

上面方法适用于 1.5+ 版本的 jQuery,对于 1.2.6-1.4 的版本,稍微有点不同,不过也非常简单。

function lookEvents (elem) { return $.data ? $.data( elem, "events", undefined, true ) : $._data( elem, "events" );}var event = lookEvents($("#testbtn")[0]); // 获取绑定的事件event.click; // 查看有几个click事件,如果要查看其他事件直接输入 event 然后回车即可

上面看到的编码就是对应事件句柄了,比如我这的 1,2 事件(如下图显示), 这个编号不是按顺序的,这个要注意。
 event.click[1] // 获取click事件的 id是1 的事件源码地址 
不出意外可以看到下面这个结果。

浅谈 jQuery 事件源码定位问题

从操作来说,不管是 1.2.6-1.4 还是 1.5+ 版本 都差不多,只是 1.5+ 利用数组模式管理函数句柄了,比较方便。
好了,该说的都说完了,小伙伴们各种测试起来吧。

Javascript 相关文章推荐
javascript 尚未实现错误解决办法
Nov 27 Javascript
qTip 基于JQuery的Tooltip插件[兼容性好]
Sep 01 Javascript
基于jquery完美拖拽,可返回拖动轨迹
Mar 29 Javascript
js中符号转意问题示例探讨
Aug 19 Javascript
js中apply方法的使用详细解析
Nov 04 Javascript
js实现的简洁网页滑动tab菜单效果代码
Aug 24 Javascript
JavaScript的设计模式经典之建造者模式
Feb 24 Javascript
深入理解JavaScript 函数
Jun 06 Javascript
confirm确认对话框的实现方法总结
Jun 17 Javascript
JavaScript通过改变文字透明度实现的文字闪烁效果实例
Apr 27 Javascript
微信小程序 空白页重定向解决办法
Jun 27 Javascript
jquery动态赋值id与动态取id方法示例
Aug 21 jQuery
js调试系列 源码定位与调试[基础篇]
Jun 18 #Javascript
js调试系列 控制台命令行API使用方法
Jun 18 #Javascript
js调试系列 初识控制台
Jun 18 #Javascript
ext前台接收action传过来的json数据示例
Jun 17 #Javascript
Ext GridPanel加载完数据后进行操作示例代码
Jun 17 #Javascript
ext中store.load跟store.reload的区别示例介绍
Jun 17 #Javascript
基于jquery实现的文字向上跑动类似跑马灯的效果
Jun 17 #Javascript
You might like
PHP实现的统计数据功能详解
2016/12/06 PHP
Yii框架参数化查询中IN查询只能查询一个的解决方法
2017/05/20 PHP
ThinkPHP5.0框架使用build 自动生成模块操作示例
2019/04/11 PHP
AutoSave/自动存储功能实现
2007/03/24 Javascript
利用jquery操作select下拉列表框的代码
2010/06/04 Javascript
关于js注册事件的常用方法
2013/04/03 Javascript
JavaScript中的运算符种类及其规则介绍
2013/09/26 Javascript
js定时器怎么写?就是在特定时间执行某段程序
2013/10/11 Javascript
js获取上传文件大小示例代码
2014/04/10 Javascript
基于jQuery插件实现环形图标菜单旋转切换特效
2015/05/15 Javascript
基于jQuery滑动杆实现购买日期选择效果
2015/09/15 Javascript
浅谈jQuery绑定事件会叠加的解决方法和心得总结
2016/10/26 Javascript
easyui datebox 时间限制,datebox开始时间限制结束时间,datebox截止日期比起始日期大的实现代码
2017/01/12 Javascript
基于 Immutable.js 实现撤销重做功能的实例代码
2018/03/01 Javascript
javascript实现固定侧边栏
2021/02/09 Javascript
使用 Python 实现微信群友统计器的思路详解
2018/09/26 Python
django小技巧之html模板中调用对象属性或对象的方法
2018/11/30 Python
Python调用Windows API函数编写录音机和音乐播放器功能
2020/01/05 Python
pytorch-RNN进行回归曲线预测方式
2020/01/14 Python
Python类及获取对象属性方法解析
2020/06/15 Python
分享30个新鲜的CSS3打造的精美绚丽效果(附演示下载)
2012/12/28 HTML / CSS
让ie浏览器成为支持html5的浏览器的解决方法(使用html5shiv)
2014/04/08 HTML / CSS
美国中小型企业领先的办公家具供应商:Office Designs
2016/11/26 全球购物
德国珠宝和手表在线商店:VALMANO
2019/03/24 全球购物
Myprotein西班牙官网:欧洲第一大运动营养品牌
2020/02/24 全球购物
值类型与引用类型有什么不同?请举例说明?并分别列举几种相应的数据类型
2015/10/24 面试题
男方父母婚礼答谢词
2014/01/25 职场文书
企业宣传口号
2014/06/12 职场文书
本科毕业生求职信
2014/06/15 职场文书
学校机关党总支领导班子整改工作方案
2014/10/26 职场文书
见习报告格式范文
2014/11/08 职场文书
党员活动总结
2015/02/04 职场文书
使用Html+Css实现简易导航栏功能(导航栏遇到鼠标切换背景颜色)
2021/04/07 HTML / CSS
Java基础之详解HashSet的使用方法
2021/06/30 Java/Android
Python中super().__init__()测试以及理解
2021/12/06 Python
python神经网络 tf.name_scope 和 tf.variable_scope 的区别
2022/05/04 Python