jQuery event 分析

jQuery event 相关

核心方法 $.fn.on/off
其他, bind/one/delegate 啥的都是调这个

[TOC]

$.event

包含几个静态方法 add/remove/fix …
实际工作由这里的方法完成

$.Event

这是 jQuery Event class,jQuery事件系统中的 event对象是这个类的实例

  • originalEvent 原来的DOM事件
  • delegateTarget delegate到的target,例如
    1
    2
    3
    4
    5
      $(document).on('click','.some-class',function(e){
    /** handler here */
    e.delegateTarget === document; // true
    $(e.currentTarget).hasClass('some-class'); // true
    });

$.fn.on

syntax: on(event,selector,data,handler)

前面说了$.data , 那个cache结构

1
2
3
4
5
6
7
id = elem[$.expando]
cache = $.cache[id] = {
data: {
// 这是 $.fn.data , $.data 操作的地方
}
// 内部 internal private 数据 如 parsedAttrs
}

现在发现,这个内部internal数据,包括很多,其中就有 event system的数据
在 jQuery.event.add 里面的 elemData 就是这里说的 cache.

其中

  • handler是 add 方法内部的一个函数,用以调用 $.event.dispatch
  • events 就是 pub/sub 模式的注册表喽,常见的 EventEmitter实例的 this._events

event namespace

没看懂 event 的 namespace 到底怎么搞的,为啥要sort ???

namespace 使用

拿bootstrap的说吧,这里的event 可以带namespace

  1. on(event,selector,handler)
  2. trigger(event)
  3. off(event)
1
2
3
4
$(document).on('click.bs.modal.data-api', '[data-toggle="modal"]',
function (e) {
// handler
}

这里只要写上 [data-toggle=modal] 的,click会调用modal对话框.在event里面直接写click也是可以的,但是有namespace就可以

  • 根据namespace 至调用符合namespace的handler
  • 根据namespace可以remove掉该namespace的所有handler

    1
    $(document).off('click.bs.modal.data-api')

    这样就移除了所有 data-toggle=modal 的效果,但是其他组件,如tooltip还可以使用

namespace 分析

前面看的时候发现jq对namespace进行了sort,想不明白…
其实namespace是很宽松的,局部匹配即可,先后顺序也没有关系.

拿前面的click.bs.modal.data-api 演示

  1. 绑定事件

    1
    2
    3
    $(document).on('click.bs.modal.data-api',function(){
    console.log(arguments);
    });
  2. 构造 $.Event对象 trigger

    1
    2
    var e = $.Event('click.bs.modal.data-api');
    $(document).trigger(e);
  3. $.Event 实例的 namespace,namespace_re 属性是在trigger过程中构建的,下面可以看看这些属性

    1
    2
    e.namespace // "bs.data-api.modal"
    e.namespace_re // /(^|\.)bs\.(?:.*\.|)data-api\.(?:.*\.|)modal(\.|$)/

    可以看到

    • namespace 就是 [bs,modal,data-api] sort后的
    • namespace_re 则是

      1
      new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" )

      因此 click.data-api , click.bs , click.bs.data-api 都能触发.

看完怎么感觉 namespace 按 startWith 匹配更好呢 !