ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

egret事件流(捕获,目标,冒泡)的实现

2021-01-23 17:58:57  阅读:218  来源: 互联网

标签:egret target 捕获 list let 冒泡 group3 group2 event


场景

假设group1是group2的父级,group2是group3的父级,我点击group3区域,那按html事件流应该是
group1->group2->group3->group3->group2->group1
在这里插入图片描述
egret基于canvas,不能使用html的事件流,egret的实现如下
1,先找到目标,此处为group3
2,遍历父级,存入列表,得到的list为【group3,group2,group1】

	let list: DisplayObject[] = [];
    while (target) {
        list.push(target);
        target = target.$parent;
    }

3,对list反转得到captureList为【group1,group2,group3】

	let captureList = list.concat();
    captureList.reverse();//使用一次reverse()方法比多次调用unshift()性能高。

4.拼接到一起,得到【group1,group2,group3,group3,group2,group1】,此时事件流列表已经拿到了,只要依次触发就行

list = captureList.concat(list);

egret的源码如下

    /**
         * @private
         * 获取事件流列表。注意:Egret框架的事件流与Flash实现并不一致。
         *
         * 事件流有三个阶段:捕获,目标,冒泡。
         * Flash里默认的的事件监听若不开启useCapture将监听目标和冒泡阶段。若开始capture将只能监听捕获当不包括目标的事件。
         * 可以在Flash中写一个简单的测试:实例化一个非容器显示对象,例如TextField。分别监听useCapture为true和false时的鼠标事件。
         * 点击后将只有useCapture为false的回调函数输出信息。也就带来一个问题「Flash的捕获阶段不能监听到最内层对象本身,只在父级列表有效」。
         *
         * 而HTML里的事件流设置useCapture为true时是能监听到目标阶段的,也就是目标阶段会被触发两次,在捕获和冒泡过程各触发一次。这样可以避免
         * 前面提到的监听捕获无法监听目标本身的问题。
         *
         * Egret最终采用了HTML里目标节点触发两次的事件流方式。
         */
        $getPropagationList(target: DisplayObject): DisplayObject[] {
            let list: DisplayObject[] = [];
            while (target) {
                list.push(target);
                target = target.$parent;
            }
            let captureList = list.concat();
            captureList.reverse();//使用一次reverse()方法比多次调用unshift()性能高。
            list = captureList.concat(list);
            return list;
        }

        /**
         * @private
         */
        $dispatchPropagationEvent(event: Event, list: DisplayObject[], targetIndex: number): void {
            let length = list.length;
            let captureIndex = targetIndex - 1;
            for (let i = 0; i < length; i++) {
                let currentTarget = list[i];
                event.$currentTarget = currentTarget;
                if (i < captureIndex)
                    event.$eventPhase = EventPhase.CAPTURING_PHASE;
                else if (i == targetIndex || i == captureIndex)
                    event.$eventPhase = EventPhase.AT_TARGET;
                else
                    event.$eventPhase = EventPhase.BUBBLING_PHASE;
                currentTarget.$notifyListener(event, i < targetIndex);
                if (event.$isPropagationStopped || event.$isPropagationImmediateStopped) {
                    return;
                }
            }
        }

标签:egret,target,捕获,list,let,冒泡,group3,group2,event
来源: https://blog.csdn.net/weixin_42276579/article/details/113058267

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有