章节
问答
课签
笔记
评论
占位
占位

事件trigger

针对自定义事件 jQuery 有一个 trigger 方法,代码其实不是很复杂,但是由于关联性太强了所以非常绕。我们根据案例分析下:

通过 trigger 手动触发了 foo 元素的 click 事件,body 的 click 事件。

$("body").click(function(event,data){
    console.log('body')
})
var foo = $('#foo');
foo.on('click', function(event,data) {
    console.log(data);
});
foo.trigger('click','慕课网');

元素 foo 本身绑定了一个 click 事件,但是我们知道 click 这种原生事件是靠 addEventListener 绑定交互驱动的,但是 jQuery 的 trigger 能够在任意时刻模拟这个交互行为。

从这一个功能点上我们就不难发现为什么 jQuery 要设计元素与数据分离了,如果是直接绑定的话就完全无法通过 trigger 的机制调用,trigger 的实现首先得益于事件的分离机制,因为没有直接把事件相关的与元素直接绑定采用了分离处理,所以我们通过 trigger 触发与 addEventListener 触发的处理流程都是一致的,不同的只是触发的方式而已。通过 trigger 触发的事件是没有事件对象、冒泡这些特性的,所以我们需要有一个方法能模拟出事件对象,然后生成一个遍历树模拟出冒泡行为,那么这个任务就交给了 trigger 方法了。

trigger 与 dispatch 方法的区别

很多人会迷惑trigger 与 dispatch 方法的区别。这里提到一个概念是元素内处理,trigger 是元素外部处理。

  • 简单的来说,jQuery 的事件我们应用从更抽象的一层去理解它的元素层次划分其实是非常清晰的,首先每一个元素都可以绑定事件与冒泡,那么这个针对每个层的单独元素的处理是划分给了 dispatch 方法。在 dispatch 方法中我们通过 target 与 currentTarget(绑定事件的元素)生成一条冒泡线,依次往父层元素遍历取出每一个层级元素对应的数据相应的执行,由于在这个模拟冒泡的操作过程中,jQuery 模拟出的事件对应被所有的这些操作共享,所以在任何一个元素的事件处理中调用了停止冒泡,那么这个循环就停止了,也就达到了 stopPropagation 的目的,这里我们要注意事件的冒泡是在绑定事件元素内部发生的
  • 原生事件提供了一个最重要参数 - 事件对象,trigger 是模拟触发,所以我们需要模拟一个这样的数据对象,其次 trigger 也要支持冒泡,但是这里有一个区别 dispatch 的地方,trigger 冒泡的 target 的对象是确定的,所以 target 就是自己本身,所以冒泡的路径其实是一个从自己本身到 window 的一条外部路线。

jQuery 设计好的地方就是对元素层级的划分,内部冒泡与外部冒泡独立处理,相互不会影响,但是又有千丝万缕的关系,具体我们来看看处理的结构。

初看 trigger 源码部分真有点晕,处理的 hack 太多了:

  1. 命名空间的过滤
  2. 模拟事件对象
  3. 制作一个触发的路径队列eventPath
  4. 对 eventPath 进行模拟冒泡的触发
  5. 在一个层级调用 dispatch 处理各自的内部事件关系(委托)

总结

所以整个 trigger 的核心,还是围绕着数据缓存在处理的,通过 on 机制在 jQuery.event.add 的时候预处理好了。trigger 的处理就是模拟冒泡的一个调度,具体的触发还是交给 jQuery.event.dispatch 方法了,通过 trigger 很好的模拟了浏览器事件流程,但是美中不足的是对象的事件混淆其中,这就造成了触发对象事件的时候最后会调用对象的相应方法。

任务

?不会了怎么办
||

提问题

写笔记

截图
提交
||

请验证,完成请求

由于请求次数过多,请先验证,完成再次请求

加群二维码

打开微信扫码自动绑定

您还未绑定服务号

绑定后可得到

  • · 粉丝专属优惠福利
  • · 大咖直播交流干货
  • · 课程更新,问题答复提醒
  • · 账号支付安全提醒

举报

0/150
提交
取消
全部 精华 我要发布
全部 我要发布
最新 点赞
只看我的

手记推荐

更多

本次提问将花费2个积分

你的积分不足,无法发表

为什么扣积分?

本次提问将花费2个积分

继续发表请点击 "确定"

为什么扣积分?