停止鼠标事件传播

Stop mouse event propagation

在 Angular 中停止鼠标事件传播的最简单方法是什么?

我应该传递特殊的 $event 对象并自己调用 stopPropagation() 还是有其他方法。

例如在 Meteor 中,我可以从事件处理程序中简单地 return false

对事件调用 stopPropagation 会阻止传播:

(event)="doSomething($event); $event.stopPropagation()"

对于preventDefault只是returnfalse

(event)="doSomething($event); false"

事件绑定允许执行多个语句和表达式按顺序执行(由 ; 分隔,就像在 *.ts 文件中一样。
如果为假,最后一个表达式的结果将导致调用 preventDefault。所以要小心表达式 returns (即使只有一个)

如果您在绑定到事件的方法中,只需 return false:

@Component({
  (...)
  template: `
    <a href="/test.html" (click)="doSomething()">Test</a>
  `
})
export class MyComp {
  doSomething() {
    (...)
    return false;
  }
}

最简单的方法是在事件处理程序上调用停止传播。 $event 在 Angular 2 中工作相同,并包含正在进行的事件(通过鼠标单击、鼠标事件等):

(click)="onEvent($event)"

在事件处理程序上,我们可以在那里停止传播:

onEvent(event) {
   event.stopPropagation();
}

我不得不 stopPropagationpreventDefault 以防止按钮展开它上面的手风琴项目。

所以...

@Component({
  template: `
    <button (click)="doSomething($event); false">Test</button>
  `
})
export class MyComponent {
  doSomething(e) {
    e.stopPropagation();
    // do other stuff...
  }
}

如果您希望能够将此添加到任何元素而不必一遍又一遍地 copy/paste 相同的代码,您可以制定一个指令来执行此操作。就这么简单:

import {Directive, HostListener} from "@angular/core";
    
@Directive({
    selector: "[click-stop-propagation]"
})
export class ClickStopPropagation
{
    @HostListener("click", ["$event"])
    public onClick(event: any): void
    {
        event.stopPropagation();
    }
}

然后将它添加到你想要它的元素上:

<div click-stop-propagation>Stop Propagation</div>

用 JavaScript

禁用 href link
<a href="#" onclick="return yes_js_login();">link</a>

yes_js_login = function() {
     // Your code here
     return false;
}

如何在 TypeScript 中使用 Angular(我的版本:4.1.2)

模板
<a class="list-group-item list-group-item-action" (click)="employeesService.selectEmployeeFromList($event); false" [routerLinkActive]="['active']" [routerLink]="['/employees', 1]">
    RouterLink
</a>
打字稿
public selectEmployeeFromList(e) {

    e.stopPropagation();
    e.preventDefault();

    console.log("This onClick method should prevent routerLink from executing.");

    return false;
}

But it does not disable the executing of routerLink!

添加到@AndroidUniversity 的答案中。在一行中你可以这样写:

<component (click)="$event.stopPropagation()"></component>

IE (Internet Explorer) 没有任何效果。我的测试人员能够通过单击它后面的按钮上的弹出窗口 window 来破坏我的模式。因此,我在我的模态屏幕上听到了点击 div 并强制重新聚焦在弹出按钮上。

<div class="modal-backscreen" (click)="modalOutsideClick($event)">
</div>


modalOutsideClick(event: any) {
   event.preventDefault()
   // handle IE click-through modal bug
   event.stopPropagation()
   setTimeout(() => {
      this.renderer.invokeElementMethod(this.myModal.nativeElement, 'focus')
   }, 100)
} 

在函数后添加 false 将停止事件传播

<a (click)="foo(); false">click with stop propagation</a>

我刚刚检查了一个 Angular 6 应用程序,event.stopPropagation() 在事件处理程序上运行,甚至没有传递 $event

(click)="doSomething()"  // does not require to pass $event


doSomething(){
   // write any code here

   event.stopPropagation();
}

这解决了我的问题,防止事件被 children:

触发

doSmth(){
  // what ever
}
        <div (click)="doSmth()">
            <div (click)="$event.stopPropagation()">
                <my-component></my-component>
            </div>
        </div>

试试这个指令

@Directive({
    selector: '[stopPropagation]'
})
export class StopPropagationDirective implements OnInit, OnDestroy {
    @Input()
    private stopPropagation: string | string[];

    get element(): HTMLElement {
        return this.elementRef.nativeElement;
    }

    get events(): string[] {
        if (typeof this.stopPropagation === 'string') {
            return [this.stopPropagation];
        }
        return this.stopPropagation;
    }

    constructor(
        private elementRef: ElementRef
    ) { }

    onEvent = (event: Event) => {
        event.stopPropagation();
    }

    ngOnInit() {
        for (const event of this.events) {
            this.element.addEventListener(event, this.onEvent);
        }
    }

    ngOnDestroy() {
        for (const event of this.events) {
            this.element.removeEventListener(event, this.onEvent);
        }
    }
}

用法

<input 
    type="text" 
    stopPropagation="input" />

<input 
    type="text" 
    [stopPropagation]="['input', 'click']" />

这对我有用:

mycomponent.component.ts:

action(event): void {
  event.stopPropagation();
}

mycomponent.component.html:

<button mat-icon-button (click)="action($event);false">Click me !<button/>

我用过

<... (click)="..;..; ..someOtherFunctions(mybesomevalue); $event.stopPropagation();" ...>...

简而言之,只需将其他 things/function 调用与“;”分开即可并添加 $event.stopPropagation()

提供的大部分解决方案都是针对Angular11以上的版本,对于Angular11以下的版本,我找到了一个可以使用的解决方法:

export class UiButtonComponent implements OnInit, OnDestroy {

  @Input() disabled = false;

  clickEmitter: Subject<any> = new Subject();

  constructor(private elementRef: ElementRef) { }

  ngOnInit(): void {
    this.elementRef.nativeElement.eventListeners()
      .map(listener => this.clickEmitter.pipe(filter(event => Boolean(event))).subscribe(event => listener(event)));
    this.elementRef.nativeElement.removeAllListeners();
    this.elementRef.nativeElement.addEventListener('click', (event) => {
      if (!this.disabled) {
        this.clickEmitter.next(event);
      }
    });
  }

  ngOnDestroy(): void {
    this.clickEmitter.complete();
  }
}

我基本上将每个侦听器带到当前组件并将其放在 Observable 上,然后,我只注册一个侦听器并在那里管理操作。

上面的示例是在给定布尔变量的情况下禁用按钮上的单击事件的示例。