浅谈 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 相关文章推荐
jquery 1.3.2 IE8中的一点点的小问题解决方法
Jul 10 Javascript
JavaScript 获取当前时间戳的代码
Aug 05 Javascript
javascript对talbe进行动态添加、删除、验证实现代码
Mar 29 Javascript
浅析document.createDocumentFragment()与js效率
Jul 08 Javascript
javascript中match函数的用法小结
Feb 08 Javascript
JavaScript知识点总结之如何提高性能
Jan 15 Javascript
Three.js学习之文字形状及自定义形状
Aug 01 Javascript
浅谈jQuery中的checkbox问题
Aug 10 Javascript
基于vue.js实现的分页
Mar 13 Javascript
5分钟学会Vue动画效果(小结)
Jul 21 Javascript
vue指令之表单控件绑定v-model v-model与v-bind结合使用
Apr 17 Javascript
Vue.js 实现地址管理页面思路详解(地址添加、编辑、删除和设置默认地址)
Dec 11 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
escape、encodeURI 和 encodeURIComponent 的区别
2009/03/02 Javascript
js showModalDialog 弹出对话框的简单实例(子窗体)
2014/01/07 Javascript
js 加密压缩出现bug解决方案
2014/11/25 Javascript
浅析javascript操作 cookie对象
2014/12/26 Javascript
JS实现FLASH幻灯片图片切换效果的方法
2015/03/04 Javascript
基于jQuery实现仿淘宝套餐选择插件
2015/03/04 Javascript
JavaScript File API实现文件上传预览
2016/02/02 Javascript
jQuery实现的多滑动门,多选项卡效果代码
2016/03/28 Javascript
Bootstrap每天必学之附加导航(Affix)插件
2016/04/25 Javascript
jquery 动态合并单元格的实现方法
2016/08/26 Javascript
JS变量中有var定义和无var定义的区别以及es6中let命令和const命令
2017/02/19 Javascript
JS浏览器BOM常见操作实例详解
2020/04/27 Javascript
[53:52]OG vs EG 2018国际邀请赛淘汰赛BO3 第二场 8.23
2018/08/24 DOTA
Python入门_条件控制(详解)
2017/05/16 Python
Python3.5字符串常用操作实例详解
2019/05/01 Python
Django工程的分层结构详解
2019/07/18 Python
关于PyTorch 自动求导机制详解
2019/08/18 Python
Python实现微信机器人的方法
2019/09/06 Python
python接口自动化如何封装获取常量的类
2019/12/24 Python
python实现堆排序的实例讲解
2020/02/21 Python
Python环境配置实现pip加速过程解析
2020/11/27 Python
浅析CSS3 中的 transition,transform,translate之间区别和作用
2020/03/26 HTML / CSS
浅谈three.js中的needsUpdate的应用
2012/11/12 HTML / CSS
万豪国际住宅与别墅集团:Homes & Villas by Marriott International
2020/10/08 全球购物
Python中pass语句的作用是什么
2016/06/01 面试题
后勤自我鉴定
2013/10/13 职场文书
《和我们一样享受春天》教学反思
2014/02/07 职场文书
大学生暑期实践感言
2014/02/26 职场文书
事业单位竞聘上岗实施方案
2014/03/28 职场文书
《东方明珠》教学反思
2014/04/20 职场文书
《梅花魂》教学反思
2014/04/30 职场文书
2014学习优秀共产党员先进事迹材料思想汇报
2014/09/14 职场文书
接待员岗位职责
2015/02/13 职场文书
部队2015年终工作总结
2015/04/02 职场文书
2019商业计划书格式、范文
2019/04/24 职场文书
Nginx配置https原理及实现过程详解
2021/03/31 Servers