浅谈 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 可以拖动的DIV(二)
Jun 26 Javascript
JavaScript中的substr()方法使用详解
Jun 06 Javascript
js实现滚动条滚动到页面底部继续加载
Dec 19 Javascript
jQuery短信验证倒计时功能实现方法详解
May 25 Javascript
jQuery.uploadify文件上传组件实例讲解
Sep 23 Javascript
JS文件/图片从电脑里面拖拽到浏览器上传文件/图片
Mar 08 Javascript
利用node实现一个批量重命名文件的函数
Dec 21 Javascript
基于Vue2.X的路由和钩子函数详解
Feb 09 Javascript
AngularJS修改model值时,显示内容不变的实例
Sep 13 Javascript
vue2.0移动端滑动事件vue-touch的实例代码
Nov 27 Javascript
js打开word文档预览操作示例【不是下载】
May 23 Javascript
vue.js实现点击图标放大离开时缩小的代码
Jan 27 Vue.js
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实现的简单压缩英文字符串的代码
2008/04/24 PHP
解析二进制流接口应用实例 pack、unpack、ord 函数使用方法
2013/06/18 PHP
codeigniter数据库操作函数汇总
2014/06/12 PHP
PHP使用PDO操作数据库的乱码问题解决方法
2016/04/08 PHP
一个JS翻页效果
2007/07/23 Javascript
Raphael带文本标签可拖动的图形实现代码
2013/02/20 Javascript
js 自制滚动条的小例子
2013/03/16 Javascript
js 剪切板的用法(clipboardData.setData)与js match函数介绍
2013/11/19 Javascript
深入理解Javascript动态方法调用与参数修改的问题
2013/12/10 Javascript
jquery中获得元素尺寸和坐标的方法整理
2014/05/18 Javascript
js识别不同浏览器基于userAgent做判断
2014/07/29 Javascript
深入分析原生JavaScript事件
2014/12/29 Javascript
jQuery实现滚动切换的tab选项卡效果代码
2015/08/26 Javascript
jquery制作图片时钟特效
2020/03/30 Javascript
关于获取DIV内部内容报错的原因分析及解决办法
2016/01/29 Javascript
jQuery 获取多选框的值及多选框中文的函数
2016/05/16 Javascript
JS代码实现百度地图 画圆 删除标注
2016/10/12 Javascript
AngularJS使用ng-Cloak阻止初始化闪烁问题的方法
2016/11/03 Javascript
原生javascript实现文件异步上传的实例讲解
2017/10/26 Javascript
mpvue跳转页面及注意事项
2018/08/03 Javascript
浅谈layui分页控件field参数接收对象的问题
2019/09/20 Javascript
JavaScript相等运算符的九条规则示例详解
2019/10/20 Javascript
vue计算属性无法监听到数组内部变化的解决方案
2019/11/06 Javascript
python生成指定长度的随机数密码
2014/01/23 Python
Python中的startswith和endswith函数使用实例
2014/08/25 Python
Python 正则表达式的高级用法
2016/12/04 Python
Python2.7环境Flask框架安装简明教程【已测试】
2018/07/13 Python
Python创建一个元素都为0的列表实例
2019/11/28 Python
keras中模型训练class_weight,sample_weight区别说明
2020/05/23 Python
Pycharm及python安装详细教程(图解)
2020/07/31 Python
解决Windows下python和pip命令无法使用的问题
2020/08/31 Python
小学优秀教育工作者事迹材料
2014/05/09 职场文书
反洗钱宣传活动总结
2014/08/26 职场文书
领导干部查摆“四风”问题自我剖析材料思想汇报
2014/10/05 职场文书
2015年团队工作总结范文
2015/05/04 职场文书
python 中的jieba分词库
2021/11/23 Python