[关闭]
@lxjwlt 2015-01-02T20:13:24.000000Z 字数 2033 阅读 2714

jQuery自定义事件

我:之前研究过jQuery的事件绑定
面试官:不是有addEventListener吗?
我: ......

之前看过jQuery的事件绑定的源代码,惊叹是何等神人能想出这样实现方法,jQuery.on事件绑定不是原生addEventListener可以代替的,它解决了以下问题:

如果再有人反着白眼问我,不是有addEventListener吗?我只想说,jQuery团队在事件绑定上编写的几百行代码可不是白写的。

本文会简要的介绍一下jQuery自定义事件的使用场景。

事件绑定

我们为document绑定两个click事件:

  1. $(document).on('click', function handler_1() {});
  2. $(document).on('click', function handler_2() {});

我们想一下,jQuery内部是用下面这种形式实现么?

  1. document.addEventListener('click', function handler_1() {});
  2. document.addEventListener('click', function handler_2() {});

是也不是,因为元素的事件绑定肯定是要用到addEventListener的,但在jQuery内部实现中,每个元素对应的每个事件,只会调用一次addEventListener,用来触发事件分派函数

  1. document.addEventListener('click', function() {
  2. // 筛选并调用符合条件的事件函数
  3. });

handler_1,handler_2两个事件函数去哪了?实际上,jQuery是利用jquery.data函数将这两个函数存在document专属的存储空间里,当触发了click事件的同时也触发了事件分派函数,该函数会遍历document专属的存储空间,根据一系列的条件筛选事件函数,这些条件包括子选择符,事件组名等等,最后将筛选出来的函数一一执行。

自定义事件

由于jQuery这种实现事件绑定的机制,自定义事件变得非常简单。

  1. $(document).on('smile', function () {});

上述代码,document元素绑定了一个自定义事件smile,我们可以用trigger或triggerHandler来触发这个事件:

  1. $(document).trigger('smile');
  2. $(document).triggerHandler('smile');

trigger和triggerHandler的区别在于,trigger方法触发的事件会顺着DOM树向上冒泡,而triggerHandler方法只是调用该元素上对应的事件函数,不会冒泡。

自定义事件一般用于给元素绑定一系列的动作,比如,我们要实现弹框效果,我们需要一个掩层和若干窗体。

  1. <div id="overlay">
  2. <div class="window window--login"></div>
  3. <div class="window window--register"></div>
  4. ...
  5. </div>

弹框需要两个动作: 关闭窗体和打开窗体。考虑到窗体可能动态增加,我们用到了动态事件绑定(动态绑定的原理在于,子元素触发的事件总会冒泡到父元素上,所以我们只需要把事件函数绑定在父元素上)

  1. $('#overlay').on('close', '.window', function() {});
  2. $('#overlay').on('open', '.window', function() {});

由于动态绑定依赖冒泡来触发事件函数,所以当我们 只能使用 trigger,来触发动态绑定的事件。比如我们要打开登录窗口:

  1. $('.window--login').tigger('open');

通过自定义事件,我们将DOM元素和其DOM操作一一对应起来。

事件返回值

如果某些情况下,我们需要知道事件函数的返回值,我们可以用jQuery.Event生成一个event对象,用这个对象来触发事件函数,事件函数的返回值将保存在event对象的result属性中,这样,我们就能够获取事件函数的返回值了:

  1. $(document).on('customEvent', function() { return 'hello world!'; });
  2. var event = $.Event('customEvent');
  3. $(document).trigger(event);
  4. event.result; // 'hello world'

参考

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注