5-14 事件trigger
本节编程练习不计算学习进度,请电脑登录imooc.com操作

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

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

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

总结

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

任务

  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  5. <script src="http://www.imooc.com/static/lib/jquery/1.9.1/jquery.js" type="text/javascript"></script>
  6. <title>自定义事件的实现</title>
  7. </head>
  8. <body>
  9.  
  10. <div id="aaron">
  11. <div id='test'>
  12. <ul>
  13. <p>trigger触发</p>
  14. </ul>
  15. </div>
  16. </div>
  17.  
  18. <div id="show"></div>
  19.  
  20. <script type="text/javascript">
  21.  
  22. var aaron = $('#aaron');
  23.  
  24. $("body").click(function(event,data){
  25. show('body '+data)
  26. })
  27.  
  28. $(window).click(function(event,data){
  29. show('window '+data)
  30. })
  31.  
  32. aaron.on('click','p', function() {
  33. show('p')
  34. });
  35.  
  36. aaron.on('click', function(event,data) {
  37. show('aaron '+data)
  38. });
  39.  
  40. aaron.trigger('click',2222);
  41.  
  42. function show(data){
  43. $("#show").append('<li>'+ data +'</li>')
  44. }
  45.  
  46. </script>
  47.  
  48. </body>
  49. </html>
下一节