zoukankan      html  css  js  c++  java
  • 浅谈 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://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>

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

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

    可以看到
    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+ 利用数组模式管理函数句柄了,比较方便。
    好了,该说的都说完了,小伙伴们各种测试起来吧。


    来自:http://www.poluoluo.com/jzxy/201406/279822.html

  • 相关阅读:
    To select the file to upload we can use the standard HTML input control of type
    Cascading Menu Script using Javascript Explained
    网站首页head区代码规范
    轻松掌握 Java 泛型
    JDK 5.0 中的泛型类型学习
    如何在firefox下获取下列框选中option的text
    是同步方法还是 synchronized 代码? 详解多线程同步规则
    javascript select option对象总结
    Select的动态取值(Text,value),添加,删除。兼容IE,FireFox
    javascript在ie和firefox下的一些差异
  • 原文地址:https://www.cnblogs.com/apollokk/p/6713861.html
Copyright © 2011-2022 走看看