Ionic3双菜单关闭异常:点击遮罩层未按预期关闭右侧菜单
我之前做多层侧边菜单的时候也碰到过一模一样的问题!结合你描述的现象,十有八九是事件冒泡在搞鬼——虽然你说z-index设置正常,menuB的遮罩视觉上盖在menuA上面,但如果遮罩的点击事件没阻止冒泡,点击动作会穿透到下层的menuA遮罩逻辑里,导致第一次点遮罩先关了menuA,第二次才轮到menuB。而滑动、X按钮能正常关闭menuB,是因为这些操作是直接绑定在menuB自身元素上,不会触发跨层级的事件冒泡。
下面给你几个具体的解决思路,按顺序试应该就能搞定:
1. 给menuB的遮罩点击事件阻止冒泡
既然你用的是Angular(从@Input能看出来),可以直接在遮罩的点击事件绑定里加上$event.stopPropagation(),或者在处理方法里手动阻止:
比如模板里:
<!-- menuB的遮罩元素 --> <div class="menu-b-backdrop" (click)="closeMenuB($event)"> </div>
组件代码里:
closeMenuB(event: Event) { // 先阻止事件继续往下冒泡到menuA的遮罩 event.stopPropagation(); // 再执行关闭menuB的逻辑 this.isMenuBOpen = false; }
这样点击menuB遮罩时,事件就不会传到下层的menuA遮罩,只会触发menuB的关闭逻辑。
2. 给菜单关闭逻辑加优先级判断
如果你的遮罩是全局共用的(比如整个页面只有一个遮罩层),那可以在全局的遮罩点击处理方法里,先判断menuB是否打开,优先处理它的关闭:
handleGlobalBackdropClick() { // 先检查menuB是否打开,是就先关它 if (this.isMenuBOpen) { this.isMenuBOpen = false; return; // 直接返回,不处理menuA } // 再处理menuA的关闭 if (this.isMenuAOpen) { this.isMenuAOpen = false; } }
这种方式哪怕事件冒泡了,逻辑上也会优先处理高优先级的menuB,避免误关menuA。
3. 用CSS控制遮罩的点击事件接收
如果menuA和menuB是各自独立的遮罩,那可以在menuB打开时,给menuA的遮罩设置pointer-events: none,让它暂时不接收任何点击事件:
/* 默认状态下menuA遮罩可以接收点击 */ .menu-a-backdrop { pointer-events: auto; } /* 当menuB打开时,menuA遮罩禁用点击 */ .menu-a-backdrop.menu-b-active { pointer-events: none; }
这样点击遮罩时,只会触发menuB遮罩的事件,根本碰不到menuA的遮罩逻辑。
快速验证方法
你可以在menuA和menuB的关闭方法里各加一行console.log,比如console.log('关闭menuA')和console.log('关闭menuB'),然后点击遮罩看控制台输出——如果先出现“关闭menuA”再出现“关闭menuB”,那百分百是事件冒泡的问题,按上面的方法处理就好。
内容的提问来源于stack exchange,提问作者Chaki

