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.

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>

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

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"

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>

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

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/>

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...
  }
}

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

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 ()


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

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!


0

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

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

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>


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']" />
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.