Angular指令拦截按钮点击事件:未登录时阻止组件click执行
解决Angular指令阻止组件click事件的问题
嘿,我明白你遇到的困扰了!你现在的指令监听了mousedown事件,但就算阻止了它的默认行为和冒泡,组件绑定的click事件还是会触发——这是因为click事件是由mousedown + mouseup两个事件共同触发的,只拦截mousedown没法中断整个click事件的触发流程。
给你两种靠谱的解决方案,优先选第一种就行,简单高效:
方案一:直接监听click事件拦截
把指令里的mousedown监听换成click,这样就能直接在click事件触发的阶段阻止组件的绑定执行,代码修改如下:
import {Directive, HostListener} from '@angular/core'; @Directive({ selector: '[appIsLogin]' }) export class IsLoginDirective { isLoginIn = false; constructor() { } @HostListener('click', ['$event']) onClick(event: Event): boolean { if (!this.isLoginIn) { console.log('未登录,阻止click事件执行'); // 阻止事件传播,避免组件的click绑定触发 event.stopPropagation(); // 阻止按钮默认行为(如果有的话) event.preventDefault(); // 阻止同元素上其他监听器执行,更保险 event.stopImmediatePropagation(); return false; } return true; } }
这样修改后,当用户未登录时,点击按钮会触发指令里的click监听,直接拦截事件,组件的sayHello()就不会执行了。
方案二:通过mousedown拦截后续事件(可选)
如果你一定要保留mousedown的监听,那需要额外拦截mouseup事件,因为click必须等mouseup完成才会触发。代码如下:
import {Directive, HostListener, ElementRef} from '@angular/core'; @Directive({ selector: '[appIsLogin]' }) export class IsLoginDirective { isLoginIn = false; constructor(private el: ElementRef) { } @HostListener('mousedown', ['$event']) onMouseDown(event: MouseEvent): boolean { if (!this.isLoginIn) { console.log('mousedown'); event.preventDefault(); event.stopPropagation(); event.stopImmediatePropagation(); // 临时监听mouseup,阻止后续事件触发 const handleMouseUp = (e: MouseEvent) => { e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); // 用完移除监听器,避免内存泄漏 this.el.nativeElement.removeEventListener('mouseup', handleMouseUp); }; this.el.nativeElement.addEventListener('mouseup', handleMouseUp); return false; } return true; } }
不过这种方式代码更繁琐,还得处理监听器的移除,所以优先推荐方案一。
内容的提问来源于stack exchange,提问作者Alan He
相关产品推荐
相关产品推荐

