浅谈 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中eval函数的使用方法与示例
Apr 09 Javascript
jquery实现输入框动态增减的实例代码
Jul 14 Javascript
jquery新的绑定事件机制on方法的使用方法
Apr 15 Javascript
JavaScript使用ActiveXObject访问Access和SQL Server数据库
Apr 02 Javascript
基于JavaScript如何实现私有成员的语法特征及私有成员的实现方式
Oct 28 Javascript
深入浅析Bootstrap列表组组件
May 03 Javascript
jQuery实现产品对比功能附源码下载
Aug 09 Javascript
微信运维交互机器人的示例代码
Nov 12 Javascript
JS 遍历 json 和 JQuery 遍历json操作完整示例
Nov 11 jQuery
解决Layui 表格自适应高度的问题
Nov 15 Javascript
jquery 插件重新绑定的处理方法分析
Nov 23 jQuery
vue父子模板传值问题解决方法案例分析
Feb 26 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
php验证session无效的解决方法
2014/11/04 PHP
Thinkphp关闭缓存的方法
2015/06/26 PHP
网页的分页下标生成代码(PHP后端方法)
2016/02/03 PHP
PHP如何根据文件头检测文件类型实例代码
2018/10/14 PHP
php获取小程序码的实现代码(B类接口)
2020/06/13 PHP
JavaScript计算字符串中每个字符出现次数的小例子
2013/07/02 Javascript
json数据与字符串的相互转化示例
2013/09/18 Javascript
jQuery阻止事件冒泡具体实现
2013/10/11 Javascript
javascript实现删除前弹出确认框
2015/06/04 Javascript
JS实现兼容性较好的随屏滚动效果
2015/11/09 Javascript
JavaScript常用函数工具集:lao-utils
2016/03/01 Javascript
JavaScript实现图片滑动切换的代码示例分享
2016/03/06 Javascript
Bootstrap组件(一)之菜单
2016/05/11 Javascript
基于JQuery实现图片上传预览与删除操作
2016/05/24 Javascript
微信小程序 获取相册照片实例详解
2016/11/16 Javascript
nodejs之get/post请求的几种方式小结
2017/07/26 NodeJs
vue-cli创建的项目,配置多页面的实现方法
2018/03/15 Javascript
JS滚轮控制图片缩放大小和拖动的实例代码
2018/11/20 Javascript
详解ES6 Promise的生命周期和创建
2019/08/18 Javascript
vue 查看dist文件里的结构(多种方式)
2020/01/17 Javascript
Python 时间处理datetime实例
2008/09/06 Python
python scp 批量同步文件的实现方法
2019/01/03 Python
Python tornado上传文件的功能
2020/03/26 Python
CSS的pointer-events属性详细介绍(作用和注意事项)
2014/04/23 HTML / CSS
HTML5 Canvas标签使用收录
2009/07/07 HTML / CSS
函授本科毕业生自我鉴定
2013/10/16 职场文书
预备党员转正思想汇报
2014/01/12 职场文书
会计求职信范文
2014/05/24 职场文书
中专毕业生的自荐书
2014/07/01 职场文书
酒店七夕情人节活动策划方案
2014/08/24 职场文书
英语课前三分钟演讲稿(6篇)
2014/09/13 职场文书
党员教师四风问题对照检查材料
2014/09/26 职场文书
文言文辞职信
2015/02/28 职场文书
Python爬虫之爬取二手房信息
2021/04/27 Python
vue实现可以快进后退的跑马灯组件
2022/04/08 Vue.js
vue里使用create, mounted调用方法
2022/04/26 Vue.js