Parar a propagação de eventos do mouse

238

Qual é a maneira mais fácil de interromper a propagação de eventos do mouse no Angular 2? Devo passar um $eventobjeto especial e stopPropagation()me chamar ou de alguma outra maneira. Por exemplo, no Meteor, posso simplesmente retornar falsedo manipulador de eventos.

Rem
fonte

Respostas:

234

Se você deseja adicionar isso a qualquer elemento sem precisar copiar / colar o mesmo código repetidamente, é possível criar uma diretiva para fazer isso. É tão simples como abaixo:

import {Directive, HostListener} from "@angular/core";

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

Em seguida, basta adicioná-lo ao elemento em que você deseja:

<div click-stop-propagation>Stop Propagation</div>
dnc253
fonte
5
Isto não funciona para mim. O evento click não está parado :(
Diallo
9
não funciona para mim, se eu tiver o outro clique ... <button click-stop-propagation (click) = "test ($ event)"> test </button>
Bibby Chung
Trabalhou para mim. Usando Angular 5.2.9
yarz-tech
1
Pode ser necessário escutar um evento de mouse diferente (por exemplo, mouse, mouseup).
yohosuff
1
@yohosuff faz um bom argumento. Adicione este método à diretiva: @HostListener("mousedown", ["$event"]) public onMousedown(event: any): void { event.stopPropagation(); }
andreisrob 14/02/19
252

O mais simples é chamar parar a propagação em um manipulador de eventos. $eventfunciona da mesma maneira no Angular 2 e contém o evento em andamento (por meio de um clique do mouse, evento do mouse etc.):

(click)="onEvent($event)"

no manipulador de eventos, podemos parar a propagação:

onEvent(event) {
   event.stopPropagation();
}
Universidade Angular
fonte
2
Na minha diretiva personalizada, isso não funciona. <button confirmMessage="are you sure?" (click)="delete()">Delete</button>, e na minha diretiva:, (click)="confirmAction($event)então confirmAction(event) { event.stopPropagation(); };
precisa saber é o seguinte
4
Tente retornar falso também
Joshua Michael Wagoner
parece que no momento em que você lida eventcom a função de manipulador stopPropogation()não está disponível. Eu tive que fazer isso direito na marcação: `(click) =" foo (); $ event.stopPropogation () "
inorganik
Isso não funciona, pelo menos não quando colocado no elemento âncora. A resposta está errada.
Shadow Wizard é Ear For You
143

A chamada stopPropagationao evento impede a propagação: 

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

Por preventDefaultapenas voltarfalse

(event)="doSomething($event); false"
Günter Zöchbauer
fonte
Eu ainda não tentei, mas github.com/angular/angular/issues/4782 e github.com/angular/angular/pull/5892/files indicam que deve funcionar. Eles não têm ;o final no entanto. Eu vou mudar isso.
Günter Zöchbauer
1
Eles estão falando sobre impedir a ação padrão, não passar o evento pelos elementos pai sobre o que é stopPropagation.
Rem
Oh, isso é ruim. Desculpe.
Günter Zöchbauer
2
return false<3
Pawel Gorczynski 23/07
Incrível como respostas erradas são aprovadas automaticamente. O código simplesmente não funciona.
Shadow Wizard é Ear For You
35

Adicionando à resposta da @AndroidUniversity. Em uma única linha, você pode escrever da seguinte maneira:

<component (click)="$event.stopPropagation()"></component>
dinigo
fonte
Ele não deve mudar muito de versão para versão uma vez que eles tentam manter o padrão html templates :)
dinigo
Funciona perfeitamente com o angular 5 também.
precisa saber é o seguinte
10

Se você estiver em um método vinculado a um evento, simplesmente retorne false:

@Component({
  (...)
  template: `
    <a href="https://stackoverflow.com/test.html" (click)="doSomething()">Test</a>
  `
})
export class MyComp {
  doSomething() {
    (...)
    return false;
  }
}
Thierry Templier
fonte
1
Ele faz trabalho para eventos de clique. Pelo menos na versão mais recente do Angular2.
26416 Jon
6
Retornando falsechamadas preventDefaultnão stopPropagation.
Günter Zöchbauer 4/17/17
O retorno de chamada false interrompe a propagação no DOM. Verifique seus fatos @ GünterZöchbauer Isso é mencionado no ng-book.
moeabdol
3
@moeabdol, um link pode pelo menos demonstrar o que você afirma, mas na verdade preventDefaulté chamado. github.com/angular/angular/blob/… , github.com/angular/angular/blob/…
Günter Zöchbauer 5/17
1
Corrigir! @ GünterZöchbauer Obrigado por esclarecer isso. Eu gostaria de poder compartilhar um link. Eu segui o conselho de Nate Murray em seu livro "ng-book The Complete Book on Angular 4" de retornar falso; no final de uma função para interromper a propagação de eventos no DOM. Ele descreve exatamente da maneira que você mencionou. Desculpe pelo mal entendido.
moeabdol
8

Isso funcionou para mim:

mycomponent.component.ts:

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

mycomponent.component.html:

<button mat-icon-button (click)="action($event);false">Click me !<button/>
Brahim JDIDOU
fonte
Esta solução funcionou para mim em angular 5 .. Obrigado.
inbha 30/03
5

Eu precisava stopPropigatione preventDefaultpara impedir que um botão expandisse um item de acordeão que estava acima.

Assim...

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

Nada funcionou para o IE (Internet Explorer). Meus testadores conseguiram interromper meu modal clicando na janela pop-up nos botões atrás dele. Então, ouvi um clique na minha tela modal div e forcei o foco novamente em um botão pop-up.

<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)
} 
PatrickW
fonte
3

eu usei

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

em suma, apenas separe outras coisas / chamadas de função com ';' e adicione $ event.stopPropagation ()

Ray Dragon
fonte
2

Acabei de fazer o check-in em um aplicativo Angular 6, o event.stopPropagation () funciona em um manipulador de eventos sem passar $ event

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


doSomething(){
   // write any code here

   event.stopPropagation();
}
Dipendu Paul
fonte
1

Desativar link href com JavaScript

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

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

Como também deve funcionar no TypeScript com Angular (Minha versão: 4.1.2)

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

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

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

    return false;
}

Mas isso não desabilita a execução do routerLink!

Javan R.
fonte
0

A adição de função false after interromperá a propagação de eventos

<a (click)="foo(); false">click with stop propagation</a>
Fabian Rios
fonte
0

Isso resolveu meu problema, impedindo que um evento fosse disparado por crianças:

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

JulianRot
fonte
0

Tente esta diretiva

@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);
        }
    }
}

Uso

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

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