美文网首页
JS自定义事件

JS自定义事件

作者: HeyDelilah | 来源:发表于2018-03-02 14:21 被阅读0次

    2018年2月28日

    背景

    业务开发中遇到JS消息没被成功接收的问题。顺带复习一下 JS 事件。

    为实现不同模块间的消息传递,我最初使用的是 jQuery triggeron。但不知何原因(猜测和模块加载、打包有关),模块间使用的并非是同一个 jQuery。也就是说消息队列挂在了不同的 $ 下,故模块间无法通信了。改为使用 CustomEvent 去传递消息。

    CustomEvent

    var event = new  CustomEvent('eventName', { 'detail':data}); // 要传递的数据,放在detail 里面 
    Target.dispatchEvent(event);
    Target.addEventListener('eventName', function(){...} );
    

    事件流

    事件是先经过捕获阶段,从上往下传;再经历冒泡阶段,从下往上传。

    addEventListener 默认是在冒泡阶段调用函数,可添加第三参数 true,让事件在捕获阶段调用函数。

    我一开始是使用 document 去发送和监听事件的。但联想到事件流,猜测是否子元素也可以监听这个document发出的事件?这里混淆了一点概念。

    什么才是真正的子类?

    若要触发的是 Target 容器,此时的 Target 就是“最子类了”,虽然它自己还有的子类 “child”,但事件流和这个child是无关的。所以这里的 child 容器接收不到消息是正常的。

    接着在测试中,遇到了另一个无关紧要的问题。

    问题

    当 addEventListener 使用“冒泡阶段处理函数”时,父容器接收不到消息了。

    而若是使用“捕获阶段处理函数”,则事件流正常。console结果如下:

    在事件冒泡阶段调用处理函数

    elem.addEventListener('build', function (e) { ... });

    Target get the message: HELLO

    在事件捕获阶段调用处理函数 elem.addEventListener('build', function (e) { ... }, true);

    document get the message: HELLO
    Parent get the message: HELLO
    Target get the message: HELLO

    原因

    CustomEvent 默认是把冒泡功能禁用了。 需要手动传参去开启:

    var event = new CustomEvent('eventName', { 'detail':'HELLO', 'bubbles': true});

    JS 事件模型

    JS 事件本质是观察者模式(Publish/Subscribe)。

    肤浅地理解:

    有一个全局变量;
    每当 “on/listen/监听/注册/订阅” 一个事件时,就把对应的 key(事件名)和 value(callback)存进去。
    每当 “trigger/dispatch/发布” 时,就找到相应的key(事件名),把对应的value(数组)里的每一个 callback,都执行一遍

    但浏览器对此的实现更为复杂,它还得满足一系列的规则(JS事件流):

    比如:$(A).trigger( "event_1" )
    那么只有 A 以及 A 的父类容器,才有资格入选;
    且这些入选者中,要提前有 监听(on)了这个 "event_1" 事件;
    且浏览器会根据指令(捕获or冒泡),选择 callback 被调用的顺序。

    相关链接

    1. JS中事件冒泡与捕获:https://segmentfault.com/a/1190000005654451
    2. CustomEvent:https://developer.mozilla.org/zh-CN/docs/Web/API/CustomEvent
    3. JS事件模型 : https://segmentfault.com/a/1190000006934031

    相关文章

      网友评论

          本文标题:JS自定义事件

          本文链接:https://www.haomeiwen.com/subject/stjaxftx.html