Zatrzymaj propagację zdarzeń myszy

238

Jaki jest najprostszy sposób na zatrzymanie propagacji zdarzeń myszy w Angular 2? Czy powinienem przekazać $eventprzedmiot specjalny i zadzwonić, stopPropagation()czy jest jakiś inny sposób. Na przykład w Meteorze mogę po prostu wrócić falsez modułu obsługi zdarzeń.

Rem
źródło

Odpowiedzi:

234

Jeśli chcesz mieć możliwość dodawania tego do dowolnych elementów bez konieczności ciągłego kopiowania / wklejania tego samego kodu, możesz stworzyć odpowiednią dyrektywę. To jest tak proste jak poniżej:

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

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

Następnie po prostu dodaj go do elementu, na którym chcesz:

<div click-stop-propagation>Stop Propagation</div>
dnc253
źródło
5
Nie działa mi. Nie można zatrzymać zdarzenia kliknięcia :(
Diallo,
9
nie działa dla mnie, jeśli mam inne kliknięcie ... <przycisk click-stop-propagation (click) = "test ($ event)"> test </button>
Bibby Chung
Pracował dla mnie. Korzystanie z
Angulara
1
Może być konieczne wykrycie innego zdarzenia myszy (np. Mousedown, mouseup).
yohosuff
1
@yohosuff ma rację. Dodaj tę metodę do dyrektywy: @HostListener("mousedown", ["$event"]) public onMousedown(event: any): void { event.stopPropagation(); }
andreisrob
252

Najprostszym jest wywołanie zatrzymania propagacji w module obsługi zdarzeń. $eventdziała tak samo w Angular 2 i zawiera trwające zdarzenie (kliknięcie myszą, zdarzenie myszy itp.):

(click)="onEvent($event)"

w module obsługi zdarzeń możemy tam zatrzymać propagację:

onEvent(event) {
   event.stopPropagation();
}
Angular University
źródło
2
W mojej niestandardowej dyrektywie to nie działa. <button confirmMessage="are you sure?" (click)="delete()">Delete</button>I moim dyrektywy: (click)="confirmAction($event), a następnie confirmAction(event) { event.stopPropagation(); };
Saeed Neamati,
4
Spróbuj również
Joshua Michael Wagoner
Wygląda na to, że do czasu obsłużenia eventw module obsługi funkcja stopPropogation()nie jest dostępna. Musiałem to zrobić poprawnie w znacznikach: `(click) =" foo (); $ event.stopPropogation () "
inorganik
To nie działa, przynajmniej nie po umieszczeniu w elemencie kotwiczącym. Odpowiedź jest zła.
Shadow Wizard is Ear For You
143

Wywołanie stopPropagationzdarzenia zapobiega propagacji: 

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

Po preventDefaultprostu wróćfalse

(event)="doSomething($event); false"
Günter Zöchbauer
źródło
Sam tego nie próbowałem, ale github.com/angular/angular/issues/4782 i github.com/angular/angular/pull/5892/files wskazują, że powinien działać. Nie mają ;jednak końca. Zmienię to.
Günter Zöchbauer
1
Mówią o zapobieganiu domyślnej akcji, a nie o krokach poprzez elementy nadrzędne, o co chodzi w stopPropagation.
Rem
Och, to moje złe. Przepraszam.
Günter Zöchbauer
2
powrót false<3
Paweł Gorczyński
Niesamowite, jak błędne odpowiedzi otrzymują automatyczne aktualizacje. Kod po prostu nie działa.
Shadow Wizard is Ear For You
35

Dodanie do odpowiedzi z @AndroidUniversity. W jednym wierszu możesz to napisać tak:

<component (click)="$event.stopPropagation()"></component>
dinigo
źródło
Nie powinno tak bardzo zmieniać się z wersji na wersję, ponieważ starają się utrzymać standard szablonów HTML :)
dinigo
Doskonale działa również z kątową 5.
imans77
10

Jeśli używasz metody powiązanej ze zdarzeniem, po prostu zwróć false:

@Component({
  (...)
  template: `
    <a href="https://stackoverflow.com/test.html" (click)="doSomething()">Test</a>
  `
})
export class MyComp {
  doSomething() {
    (...)
    return false;
  }
}
Thierry Templier
źródło
1
To czyni pracę dla zdarzeń kliknięcia. Przynajmniej w najnowszej wersji Angular2.
Jon
6
Odbieranie falsepołączeń preventDefaultnie stopPropagation.
Günter Zöchbauer
Wywołanie wartości false powoduje zatrzymanie propagacji w DOM. Sprawdź swoje fakty @ GünterZöchbauer Jest wspomniany w książce ng.
moeabdol
3
@moeabdol link może przynajmniej wykazać to, co twierdzisz, ale tak naprawdę preventDefaultjest nazywany. github.com/angular/angular/blob/... , github.com/angular/angular/blob/...
Günter Zöchbauer
1
Poprawny! @ GünterZöchbauer Dziękujemy za wyjaśnienie tego. Chciałbym móc udostępnić link. Postępowałem zgodnie z radą Nate'a Murraya w jego książce „ng-book The Complete Book on Angular 4” o powrocie fałszu; na końcu funkcji zatrzymującej propagację zdarzeń w DOM. Opisuje to dokładnie tak, jak wspomniałeś. Przepraszam za nieporozumienie.
moeabdol
8

To działało dla mnie:

mycomponent.component.ts:

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

mycomponent.component.html:

<button mat-icon-button (click)="action($event);false">Click me !<button/>
Brahim JDIDOU
źródło
To rozwiązanie zadziałało dla mnie w kącie 5 .. Dziękuję.
inbha
5

Musiałem stopPropigationi preventDefaultaby przycisk nie rozszerzał elementu akordeonu, znajdował się nad nim.

Więc...

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

Nic nie działało dla IE (Internet Explorer). Moi testerzy byli w stanie złamać mój modal, klikając okno podręczne na przyciskach za nim. Słuchałem więc kliknięcia na moim modalnym ekranie div i wymusiłem ponowne ustawianie ostrości na przycisku wyskakującym.

<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
źródło
3

użyłem

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

w skrócie po prostu oddziel inne wywołania rzeczy / funkcji za pomocą ';' i dodaj $ event.stopPropagation ()

Ray Dragon
źródło
2

Właśnie sprawdziłem w aplikacji Angular 6, event.stopPropagation () działa na module obsługi zdarzeń, nawet nie przekazując $ event

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


doSomething(){
   // write any code here

   event.stopPropagation();
}
Dipendu Paul
źródło
1

Wyłącz link href za pomocą JavaScript

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

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

Jak powinno działać również w TypeScript z Angularem (Moja wersja: 4.1.2)

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

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

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

    return false;
}

Ale to nie wyłącza wykonywania routerLink!

Javan R.
źródło
0

Dodanie funkcji false po spowoduje zatrzymanie propagacji zdarzeń

<a (click)="foo(); false">click with stop propagation</a>
Fabian Rios
źródło
0

To rozwiązało mój problem, od zapobiegania, że ​​zdarzenie zostanie zwolnione przez dzieci:

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

JulianRot
źródło
0

Wypróbuj tę dyrektywę

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

Stosowanie

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

<input 
    type="text" 
    [stopPropagation]="['input', 'click']" />
David Alsh
źródło