diff --git a/assets/script/game/map/SinfoComp.ts b/assets/script/game/map/SinfoComp.ts index 588f422a..b4c20a96 100644 --- a/assets/script/game/map/SinfoComp.ts +++ b/assets/script/game/map/SinfoComp.ts @@ -131,6 +131,13 @@ export class SinfoComp extends CCComp { this.close_btn?.on(NodeEventType.TOUCH_END, this.onCloseClick, this); } + onDisable() { + // 节点离场(含被 LayerManager 移入缓存池)即注销全局触摸, + // 防止残留监听导致 detached 节点再次响应关闭 + this.unscheduleAllCallbacks(); + input.off(Input.EventType.TOUCH_END, this.onGlobalTouch, this); + } + onDestroy() { super.onDestroy(); if (this.node && this.node.isValid) { @@ -150,9 +157,12 @@ export class SinfoComp extends CCComp { onAdded(params: SInfoParams) { this.params = params; this.render(); - // 延迟一帧注册全局触摸,避免本次点击立即触发关闭 + // 延迟一帧注册全局触摸,避免本次点击立即触发关闭; + // 回调内校验节点仍在舞台,防止同帧开关导致监听泄漏 this.scheduleOnce(() => { - input.on(Input.EventType.TOUCH_END, this.onGlobalTouch, this); + if (this.node && this.node.isValid && this.node.activeInHierarchy) { + input.on(Input.EventType.TOUCH_END, this.onGlobalTouch, this); + } }, 0); } @@ -189,6 +199,9 @@ export class SinfoComp extends CCComp { /** 关闭弹窗 */ private close() { + // 防御重复关闭:节点已被移除(如关闭按钮与全局触摸同帧先后触发, + // removeByNode 默认不销毁节点,此时 isValid 仍为 true 但 parent 为 null) + if (!this.node || !this.node.isValid || !this.node.parent) return; oops.gui.removeByNode(this.node); }