CocosCreator 事件模型,事件阻擋,事件穿透


版本:2.4.3

 

一 事件模型

二 事件阻擋

三 事件穿透

四 currentTarget和Target

 

一 事件模型

點擊后依次進入捕獲,目標和冒泡階段。

 

 

 

二 事件阻擋

如下圖,現在實現只讓白色響應事件,不讓紅色響應事件。(注意層級關系,紅色包含着白色)

 

 給紅色和白色添加點擊事件

this.white.on(cc.Node.EventType.TOUCH_END, ()=>{console.log("white click")},this);
this.red.on(cc.Node.EventType.TOUCH_END, ()=>{console.log("red click")},this);

 

 

 

點擊紅色 (捕獲階段,目標階段紅色,冒泡階段到canvas節點)

點擊白色  (捕獲階段,目標階段白色,冒泡階段到紅色節點,所以紅白都能響應)

點擊白色和紅色重疊區域(同上)

 

給在上方的白色掛上一個Block Input Events組件

 

 

事件會被阻擋,點擊白色或紅白重疊區域只有白色響應事件,紅色不會響應點擊事件。 (捕獲階段,目標階段白色,禁止傳遞,於是沒有冒泡到紅色節點)

 

在白色綁定了blockInputEvents組件的情況下,紅色監聽使用useCapture=true,在捕獲階段生效。則點擊紅白重疊區域,紅色和白色都能響應。

因為捕獲階段到紅色節點生效,目標階段白色生效,白色阻止事件傳播,所以冒泡不到紅色節點。因為捕獲階段就生效,所以冒泡阻擋不阻擋無所謂。

this.red.on(cc.Node.EventType.TOUCH_END, () => { console.log("red click") }, this, true);
this.white.on(cc.Node.EventType.TOUCH_END, () => { console.log("white click") }, this);

 

 

看一下BlockInputEvents源碼,使用了stopPropagation阻止了事件的傳遞。

 

 

 

三 事件穿透

現在實現讓紅色和白色都能響應事件。 (注意red和white的層級關系,事件阻擋例子里是包含關系,這里是上下層關系)

點擊白色

 

 點擊紅色

 

點擊白紅色重疊區域,默認情況下只有上方的白色響應事件,紅色不會響應點擊事件。

 

編寫一個穿透事件組件,並給上層的白色添加該組件。

const { ccclass, property } = cc._decorator;

/**
 * 該組件將所屬節點內的所有輸入事件穿透到下層節點,一般用於上層 UI 的背景。
 * 該組件沒有任何 API 接口,直接添加到場景即可生效。
 */
@ccclass
export class ThroughInputEvents extends cc.Component {
    onLoad(): void {
        (this.node as any)._touchListener.setSwallowTouches(false);
    }
}

  

添加穿透事件組件后,再次點擊紅白重疊區域,則白色和紅色都能響應事件

 

這是白色物體設置setSwallowTouches不能吞噬事件,會保持事件的傳遞。

 

四 currentTarget和Target

 

 

        this.red.on(cc.Node.EventType.TOUCH_END, (e)=>{console.log("red:",e)},this);
        this.white.on(cc.Node.EventType.TOUCH_END, (e)=>{console.log("white:",e)},this);

 

點擊白色,輸出如下,currentTarget是冒泡階段的響應,target是目標階段的響應。

點擊白色后,事件經過捕獲階段,到達目標階段是白色節點,然后冒泡到紅色節點。

 

 

 

點擊紅色,輸入如下。

點擊紅色,通過捕獲階段,到達目標階段紅色,冒泡后因為沒有其他節點在監聽,所以冒泡的currentTarget仍然是紅色節點。

如果canvas也監聽點擊的話,冒泡后currentTarget會是canvas。

 

利用currentTarget和Target,可以簡化一下按鈕監聽。例如3個按鈕使用同一個響應函數處理,用target來區別點擊了哪一個按鈕。

 

 

    start() {
        this.red.on(cc.Node.EventType.TOUCH_END, this.onBtnTap, this);
        this.white.on(cc.Node.EventType.TOUCH_END, this.onBtnTap, this);
        this.green.on(cc.Node.EventType.TOUCH_END, this.onBtnTap, this);
    }

    private onBtnTap(e: cc.Event.EventTouch) {
        switch (e.target) {
            case this.red:
                console.log("red touch");
                break;
            case this.white:
                console.log("white touch");
                break;
            case this.green:
                console.log("green touch");
                break;
        }
    }

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM