Arrêter la propagation des événements de souris

239

Quelle est la façon la plus simple d'arrêter la propagation des événements de souris dans Angular 2? Dois-je passer un $eventobjet spécial et m'appeler stopPropagation()ou il existe un autre moyen. Par exemple, dans Meteor, je peux simplement revenir falsedu gestionnaire d'événements.

Rem
la source

Réponses:

235

Si vous voulez pouvoir l'ajouter à n'importe quel élément sans avoir à copier / coller le même code encore et encore, vous pouvez créer une directive pour ce faire. C'est aussi simple que ci-dessous:

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

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

Ensuite, ajoutez-le simplement à l'élément sur lequel vous le souhaitez:

<div click-stop-propagation>Stop Propagation</div>
dnc253
la source
5
Ça ne marche pas pour moi. L'événement click n'est pas arrêté :(
Diallo
9
ne fonctionne pas pour moi, si j'ai l'autre clic ... <bouton click-stop-propagation (click) = "test ($ event)"> test </button>
Bibby Chung
A travaillé pour moi. Utilisation d'Angular 5.2.9
yarz-tech
1
Vous devrez peut-être écouter un événement de souris différent (par exemple, mousedown, mouseup).
yohosuff
1
@yohosuff fait un bon point. Ajoutez cette méthode à la directive: @HostListener("mousedown", ["$event"]) public onMousedown(event: any): void { event.stopPropagation(); }
andreisrob
253

Le plus simple est d'appeler stop propagation sur un gestionnaire d'événements. $eventfonctionne de la même manière dans Angular 2, et contient l'événement en cours (par lui un clic de souris, un événement de souris, etc.):

(click)="onEvent($event)"

sur le gestionnaire d'événements, on peut y arrêter la propagation:

onEvent(event) {
   event.stopPropagation();
}
Université angulaire
la source
2
Dans ma directive personnalisée, cela ne fonctionne pas. <button confirmMessage="are you sure?" (click)="delete()">Delete</button>, et dans ma directive:, (click)="confirmAction($event)alors confirmAction(event) { event.stopPropagation(); };
Saeed Neamati
4
Essayez de retourner faux aussi
Joshua Michael Waggoner
semble qu'au moment où vous gérez eventla fonction de gestionnaire stopPropogation()n'est pas disponible. Je devais le faire directement dans le balisage: `(click) =" foo (); $ event.stopPropogation () "
inorganik
Cela ne fonctionne pas, du moins pas lorsqu'il est placé dans l'élément d'ancrage. La réponse est fausse.
Shadow Wizard est Ear For You
143

L'appel stopPropagationà l'événement empêche la propagation: 

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

Pour preventDefaultjuste revenirfalse

(event)="doSomething($event); false"
Günter Zöchbauer
la source
Je ne l'ai pas essayé moi-même mais github.com/angular/angular/issues/4782 et github.com/angular/angular/pull/5892/files indiquent que cela devrait fonctionner. ;Mais ils n'en ont pas à la fin. Je vais changer ça.
Günter Zöchbauer
1
Ils parlent d'empêcher une action par défaut, et non de faire passer l'événement à travers les éléments parents de quoi parle stopPropagation.
Rem
Oh, c'est mon mal. Désolé.
Günter Zöchbauer
2
retour false<3
Pawel Gorczynski
Incroyable à quel point les mauvaises réponses obtiennent des votes automatiques. Le code ne fonctionne tout simplement pas.
Shadow Wizard est Ear For You
35

Ajout à la réponse de @AndroidUniversity. En une seule ligne, vous pouvez l'écrire comme ceci:

<component (click)="$event.stopPropagation()"></component>
dinigo
la source
Cela ne devrait pas changer tellement d'une version à l'autre car ils essaient de garder la norme de modélisation HTML :)
dinigo
Fonctionne parfaitement avec angular 5 également.
imans77
10

Si vous êtes dans une méthode liée à un événement, renvoyez simplement false:

@Component({
  (...)
  template: `
    <a href="https://stackoverflow.com/test.html" (click)="doSomething()">Test</a>
  `
})
export class MyComp {
  doSomething() {
    (...)
    return false;
  }
}
Thierry Templier
la source
1
Il fait le travail pour les événements de clic. Au moins dans la dernière version d'Angular2.
Jon
6
Renvoyer les falseappels preventDefaultnon stopPropagation.
Günter Zöchbauer
Appeler return false arrête la propagation dans le DOM. Vérifiez vos faits @ GünterZöchbauer Il est mentionné dans le livre ng.
moeabdol
3
@moeabdol un lien pourrait au moins démontrer ce que vous prétendez, mais preventDefaultest en fait appelé. github.com/angular/angular/blob/… , github.com/angular/angular/blob/…
Günter Zöchbauer
1
Correct! @ GünterZöchbauer Merci d'avoir clarifié cela. J'aimerais pouvoir partager un lien. J'ai suivi les conseils de Nate Murray dans son livre "ng-book The Complete Book on Angular 4" de retourner faux; à la fin d'une fonction pour arrêter la propagation des événements dans le DOM. Il le décrit exactement comme vous l'avez mentionné. Désolé pour le malentendu.
moeabdol
8

Cela a fonctionné pour moi:

mycomponent.component.ts:

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

mycomponent.component.html:

<button mat-icon-button (click)="action($event);false">Click me !<button/>
Brahim JDIDOU
la source
Cette solution a fonctionné pour moi en angulaire 5 .. Merci.
inbha
5

Je devais stopPropigationet preventDefaultafin d'empêcher un bouton d'étendre un élément d'accordéon qu'il se trouvait au-dessus.

Alors...

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

Rien ne fonctionnait pour IE (Internet Explorer). Mes testeurs ont réussi à casser mon modal en cliquant sur la fenêtre contextuelle sur les boutons situés derrière. J'ai donc écouté un clic sur ma div écran modal et forcé le recentrage sur un bouton popup.

<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
la source
3

j'ai utilisé

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

en bref, séparez simplement les autres choses / appels de fonction par ';' et ajoutez $ event.stopPropagation ()

Ray Dragon
la source
2

Je viens de vérifier dans une application Angular 6, le event.stopPropagation () fonctionne sur un gestionnaire d'événements sans même passer $ event

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


doSomething(){
   // write any code here

   event.stopPropagation();
}
Dipendu Paul
la source
1

Désactiver le lien href avec JavaScript

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

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

Comment cela devrait également fonctionner dans TypeScript avec Angular (Ma version: 4.1.2)

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

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

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

    return false;
}

Mais cela ne désactive pas l'exécution de routerLink!

Javan R.
la source
0

L'ajout de la fonction false after arrêtera la propagation des événements

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

Cela a résolu mon problème, pour éviter qu'un événement ne soit déclenché par un enfant:

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

JulianRot
la source
0

Essayez cette directive

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

Usage

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

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