版本: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; } }