停止鼠标事件传播


238

停止鼠标事件在Angular 2中传播的最简单方法是什么?我应该传递特殊$event对象并给stopPropagation()自己打电话还是有其他方法。例如,在Meteor中,我可以简单地false从事件处理程序中返回。

Answers:


234

如果您希望能够将此添加到任何元素而不必一遍又一遍地复制/粘贴相同的代码,则可以指定一条指令来执行此操作。它很简单,如下所示:

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>

5
它对我不起作用。点击事件不会停止:(
Diallo '18

9
不工作对我来说,如果我有其他点击... <点击按钮停止传播(点击)=“测试($事件)”>测试</按钮>
毕比涌

为我工作。使用Angular 5.2.9
yarz-tech

1
您可能需要监听其他鼠标事件(即mousedown,mouseup)。
yohosuff

1
@yohosuff很好。将此方法添加到指令中: @HostListener("mousedown", ["$event"]) public onMousedown(event: any): void { event.stopPropagation(); }
andreisrob,

252

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

(click)="onEvent($event)"

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

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

2
在我的自定义指令中,它不起作用。<button confirmMessage="are you sure?" (click)="delete()">Delete</button>,然后在我的指令中:(click)="confirmAction($event);然后confirmAction(event) { event.stopPropagation(); }
Saeed Neamati

4
尝试返回false以及
约书亚迈克尔·瓦戈纳

似乎到了您event在处理程序函数中进行处理的时间stopPropogation()不可用。我必须在标记中正确执行:`(click)=“ foo(); $ event.stopPropogation()”
inorganik,

这是行不通的,至少在放置到锚定元素中时无效。答案是错误的。
暗影巫师为您耳边

143

调用stopPropagation该事件可防止传播: 

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

为了preventDefault刚回来false

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

我自己还没有尝试过,但是github.com/angular/angular/issues/4782github.com/angular/angular/pull/5892/files表明它应该可以工作。他们没有;结尾。我会改变的。
君特Zöchbauer

1
他们说的是防止默认操作,而不是通过父元素单步执行stopPropagation的操作。
Rem 2016年

哦,那是我的坏。抱歉。
君特Zöchbauer

2
return false<3
Pawel Gorczynski '18

错误答案如何自动获得赞誉。该代码根本行不通。
暗影巫师为您耳边

35

从@AndroidUniversity添加到答案。在一行中,您可以这样编写:

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

它在版本之间的变化不应该太大,因为他们试图保持html模板标准:)
dinigo

也可以与角度5完美配合。
imans77 '19

10

如果您处于绑定到事件的方法中,则只需返回false:

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

1
确实适用于点击事件。至少在最新版本的Angular2中。
2016年

6
返回false调用preventDefault没有stopPropagation
君特Zöchbauer

调用return false会停止在DOM中的传播。检查您的事实@GünterZöchbauer在ng书中提到过。
moeabdol

3
@moeabdol链接至少可以证明您的要求,但实际上preventDefault已被调用。github.com/angular/angular/blob/...github.com/angular/angular/blob/...
君特Zöchbauer

1
正确!@GünterZöchbauer感谢您澄清这一点。我希望我可以分享一个链接。我遵循内特·默里(Nate Murray)在他的书“ ng-book Angular 4的完整书”中的建议,即返回假。在函数的末尾停止DOM中的事件传播。他完全按照您提到的方式进行描述。很抱歉对于这个误会。
moeabdol

8

这为我工作:

mycomponent.component.ts:

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

mycomponent.component.html:

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

这个解决方案在角度5对我有用。谢谢。
inbha

5

我必须stopPropigation并且preventDefault为了防止按钮扩展它上面放置的手风琴项目。

所以...

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

3

IE(Internet Explorer)无效。通过单击弹出窗口后面的按钮,我的测试人员能够破坏我的模式。因此,我听了我的模态屏幕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)
} 

3

我用了

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

简而言之,只需用“;”分隔其他事物/函数调用 并添加$ event.stopPropagation()


2

我刚刚在Angular 6应用程序中签入,event.stopPropagation()在事件处理程序上运行,甚至没有传递$ event

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


doSomething(){
   // write any code here

   event.stopPropagation();
}

1

禁用带有JavaScript的href链接

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

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

在Angular的TypeScript中它也应该如何工作(我的版本: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;
}

但是它不会禁用routerLink的执行!



0

这解决了我的问题,从防止儿童事件引发的事件开始:

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


0

试试这个指令

@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']" />
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.