浅谈 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 相关文章推荐
jqplot通过ajax动态画折线图的方法及思路
Dec 08 Javascript
jQuery实现级联菜单效果(仿淘宝首页菜单动画)
Apr 10 Javascript
JavaScript中使用stopPropagation函数停止事件传播例子
Aug 27 Javascript
一个JavaScript用逗号分割字符串实例
Sep 22 Javascript
JavaScript实现仿新浪微博大厅和腾讯微博首页滚动特效源码
Sep 15 Javascript
javascript实现拖动元素交换位置
Nov 29 Javascript
相册展示PhotoSwipe.js插件实现
Aug 25 Javascript
基于Angular.js实现的触摸滑动动画实例代码
Feb 19 Javascript
angular bootstrap timepicker TypeError提示怎么办
Jun 13 Javascript
微信小程序 按钮滑动的实现方法
Sep 27 Javascript
微信小程序—setTimeOut定时器的问题及解决
Jul 26 Javascript
vue 解决无法对未定义的值,空值或基元值设置反应属性报错问题
Jul 31 Javascript
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
ThinkPHP使用PHPExcel实现Excel数据导入导出完整实例
2014/07/22 PHP
thinkPHP5.0框架应用请求生命周期分析
2017/03/25 PHP
Laravel中Facade的加载过程与原理详解
2017/09/22 PHP
JavaScript Accessor实现说明
2010/12/06 Javascript
浅析node.js中close事件
2014/11/26 Javascript
node.js中的http.createClient方法使用说明
2014/12/15 Javascript
jQuery操作DOM之获取表单控件的值
2015/01/23 Javascript
Jquery Mobile 自定义按钮图标
2015/11/18 Javascript
jquery在ie7下选择器的问题导致append失效的解决方法
2016/01/10 Javascript
JavaScript使用delete删除数组元素用法示例【数组长度不变】
2017/01/17 Javascript
详谈js使用in和hasOwnProperty获取对象属性的区别
2017/04/25 Javascript
jquery实现tab选项卡切换效果(悬停、下方横线动画位移)
2017/05/05 jQuery
原生JS检测CSS3动画是否结束的方法详解
2019/01/27 Javascript
JQuery的加载和选择器用法简单示例
2019/05/13 jQuery
使用jQuery实现掷骰子游戏
2019/10/24 jQuery
如何基于filter实现网站整体变灰功能
2020/04/17 Javascript
[56:24]DOTA2上海特级锦标赛主赛事日 - 3 胜者组第二轮#1Liquid VS MVP.Phx第二局
2016/03/04 DOTA
[01:16:16]DOTA2-DPC中国联赛定级赛 RNG vs Phoenix BO3第二场 1月8日
2021/03/11 DOTA
使用Python的web.py框架实现类似Django的ORM查询的教程
2015/05/02 Python
Python解决走迷宫问题算法示例
2018/07/27 Python
pip指定python位置安装软件包的方法
2019/07/12 Python
Python实现屏幕录制功能的代码
2020/03/02 Python
Python Selenium实现无可视化界面过程解析
2020/08/25 Python
python中re模块知识点总结
2021/01/17 Python
H5新属性audio音频和video视频的控制详解(推荐)
2016/12/09 HTML / CSS
英国领先的葡萄酒专家:Majestic Wine
2017/05/30 全球购物
简单的JAVA编程面试题
2013/03/19 面试题
家长给老师的道歉信
2014/01/13 职场文书
综合实践教学反思
2014/01/31 职场文书
副总经理岗位职责
2014/03/16 职场文书
教室布置标语
2014/06/26 职场文书
工作业绩不及格检讨书
2014/10/28 职场文书
妈妈再爱我一次观后感
2015/06/08 职场文书
2015中秋节晚会主持词
2015/07/01 职场文书
HTML5中 rem适配方案与 viewport 适配问题详解
2021/04/27 HTML / CSS
go语言中fallthrough的用法说明
2021/05/06 Golang