浅谈 jQuery 事件源码定位问题

原文:浅谈 jQuery 事件源码定位问题

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

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

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

关于jQuery对于事件的管理,大牛们也分析的非常透彻了,我就不啰嗦了,因为不是我们今天要说的重点。
我们要说的重点是怎么定位到事件源码处。因为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 打开控制台看看结果,当然也可以复制下面的源码自己测试。

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test</title>
    <script src="http://ajax.googleapis.com/ajax/libs/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", "1.11.0"],
        elem = $("#testbtn")[0], // 待操作的元素
        url, // jquery 地址
        jq = null, // 保存新的jquery句柄
        jqver, // jqury 版本
        fn; // 函数句柄

    for (var i=0; i<version.length; i++) {
        url = "http://ajax.googleapis.com/ajax/libs/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>

如果不出意外,你可以在控制台看到这样的显示结果

展开后可以看到绑定的函数参数里的版本和当前版本是对应的。

 

可以看到
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事件的第一个事件源码地址

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

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

上面方法适用于 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 的事件源码地址 
不出意外可以看到下面这个结果。

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

时间: 2024-10-29 08:55:52

浅谈 jQuery 事件源码定位问题的相关文章

浅谈 jQuery 事件源码定位问题_jquery

昨天群里有人问了个事件源码定位的问题,简单描述下是这样的. 在一个不是自己写的页面上,如何快速定位到他绑定的事件代码在哪?(页面用的是jQuery) 这个问题,说难不难,说简单也没那么简单,万一用的是委托之类也会麻烦点. 在 chrome 的控制台里有个 Event Listeners,这里会显示你所选择元素的事件,如果是原生事件,他会直接显示, 你点击一下事件就会跳到对应代码里了,可是 jQuery 绑定的事件却不是这样的,你点击后只会跳到 jQuery 源码里, min后的jQuery源码密

浅谈jQuery构造函数分析_jquery

在我的上一篇文章里面 阐述了jQuery的大致框架,知道了所有代码都是写在了一个自调用匿名函数里面,并且传入了window对象,源码是这样的: (function( window, undefined ) {...})( window ); 我们通过alert(jquery) 知道它是一个对象,那么这个对象是怎么构造出来的呢?我们使用$(document)类似的写法获取元素,就好像直接调用了普通的方法一样,jQuery就是普通的函数吗?如果是构造函数为什么不是 new $(document)的常

浅谈bootstrap源码分析之tab(选项卡)_javascript技巧

实现tab选项卡的应用,此插件相对比较简单 源码文件: tab.js 实现原理 1.单击一个元素时,首先将原来高亮的元素取消 2.然后给被单击元素进行高亮 3.如果单击元素是下拉框中某个选项,则选中本身,还要选中下拉框 5.如果定义了动画,先执行动画,然后回调 源码分析: 1.Show方法,是在单击一个元素的时候触发,会触发如下四个事件 1.1.Hiden.bs.tab:隐藏上一个元素 1.2.Show.bs.tab:显示当前元素 1.3.Hideen.bs.tab:隐藏上一个元素完成 1.4.

浅谈jQuery.easyui的datebox格式化时间

  这篇文章主要介绍了浅谈jQuery.easyui的datebox格式化时间的方法,需要的朋友可以参考下 方法很简单,这里就不多废话了,直接奉上代码: ? 1 2 3 4 5 6 $.fn.datebox.defaults.formatter = function (date) { var y = date.getFullYear(); var m = date.getMonth() + 1; var d = date.getDate(); return y + '/' + (m < 10 ?

浅谈jquery中delegate()与live()

  这篇文章主要介绍了浅谈jquery中delegate()与live()的相关资料,需要的朋友可以参考下 delegate() 方法为指定的元素(属于被选元素的子元素)添加一个或多个事件处理程序 例如给id是showspan的div中的span标签添加事件 ? 1 2 3 4 5 6 7 8 9 10 <div id="showspan"><span>showspan**showspan</span></div> <span>

浅谈jquery事件处理

  浅谈jquery事件处理         在以jQuery为基础库的前端开发体系中,经常会在一个页面上通过各种标识绑定许许多多的事件.就算简单的使用了事件代理,也还是造成了事件的分散,不好维护和管理. 那么,如何解决这个问题呢?而我,想到了backbone中的events.如下: 代码如下: events: { "click .icon": "open", "click .button.edit": "openEditDialog&

浅谈Jquery核心函数_jquery

      在Jquery中,所有的DOM对象都将封装成Jquery对象,而且只有Jquery对象才能使用Jquery方法或者属性来执行相应的操作. 所以Jquery提供了一个可以将DOM对象封装成Jquery对象的函数,就是Jquery核心函数jquery(),也称为工厂函数. jquery核心函数有7个重载,分别如下: jquery()  该函数返回一个空的jquery对象. jquery(elements)  该函数将一个或多个DOM元素转化为Jquery对象(或jquery集合) jqu

浅谈jquery.form.js的ajaxSubmit和ajaxForm的使用_jquery

• 依赖的脚本文件 <script src="../Javascript/jquery-1.11.1.min.js" type="text/javascript"></script> <script src="../Javascript/jquery.form.js" type="text/javascript"></script> • ajaxSubmit 和ajaxForm区

浅谈JQuery+ajax+jsonp 跨域访问_jquery

Jsonp(JSON with Padding)是资料格式 json 的一种"使用模式",可以让网页从别的网域获取资料. 一. 客户端 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv=&q