Зупиніть розповсюдження подій миші


239

Який найпростіший спосіб зупинити поширення подій миші в куті 2? Чи повинен я пройти спеціальний $eventоб’єкт і подзвонити stopPropagation()собі, або є якийсь інший шлях. Наприклад, в Meteor я можу просто повернутися falseз обробника подій.

Відповіді:


235

Якщо ви хочете мати можливість додавати це до будь-яких елементів без необхідності копіювати / вставляти один і той же код знову і знову, ви можете зробити директиву для цього. Це так само просто, як нижче:

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

9
не працює для мене, якщо у мене є інший клік ... <кнопка натискання-зупинка-розповсюдження (click) = "тест ($ подія)"> тест </button>
Біббі Чун

Працювали для мене. Використовуючи Angular 5.2.9
yarz-tech

1
Можливо, вам доведеться прослухати іншу подію миші (наприклад, mousedown, mouseup).
йохосуф

1
@yohosuff робить хороший момент. Додайте цей метод до директиви: @HostListener("mousedown", ["$event"]) public onMousedown(event: any): void { event.stopPropagation(); }
andreisrob

253

Найпростіший - викликати розповсюдження зупинки на обробці подій. $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(); };
Саїд Неаматі

4
Спробуйте також повернути помилкове
Джошуа Майкл Вагонер

видається, що до моменту обробки eventфункції обробника stopPropogation()недоступна. Мені довелося це зробити прямо у розмітці: `(click) =" foo (); $ event.stopPropogation () "
inorganik

Це не спрацьовує, принаймні не тоді, коли розміщується в анкерному елементі. Відповідь неправильна.
Shadow Wizard - це вухо для вас

143

Дзвінки stopPropagationна подію запобігають поширенню: 

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

Для preventDefaultпросто поверненняfalse

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

Я сам не пробував цього, але github.com/angular/angular/isissue/4782 та github.com/angular/angular/pull/5892/files вказують, що це має працювати. ;Однак вони не мають кінця. Я це зміню.
Günter Zöchbauer

1
Вони говорять про запобігання дії за замовчуванням, а не про перехід події через батьківські елементи, про що йде мова.
Рем

О, це моє погано. Вибачте.
Günter Zöchbauer

2
повернення false<3
Pawel Gorczynski

Дивно, як неправильні відповіді отримують автоматичні оновлення. Код просто не працює.
Shadow Wizard - це вухо для вас,

35

Додавання відповіді від @AndroidUniversity. В одному рядку ви можете записати його так:

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

Це не повинно так сильно змінюватися від версії до версії, оскільки вони намагаються дотримати стандарт HTML-
шаблону

Чудово працює і з кутовим 5.
imans77

10

Якщо ви використовуєте метод, пов'язаний з подією, просто поверніть false:

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

1
Це робить роботу для подій клацання. Принаймні, в останній версії Angular2.
Джон

6
Повернення falseдзвінків preventDefaultнемає stopPropagation.
Günter Zöchbauer

Виклик return false не припиняє розповсюдження в DOM. Перевірте свої факти @ GünterZöchbauer Про це йдеться у книзі ng.
moeabdol

3
@moeabdol посилання може хоча б демонструвати те, про що ви заявляєте, але насправді preventDefaultназивається. github.com/angular/angular/blob/… , github.com/angular/angular/blob/…
Günter Zöchbauer

1
Правильно! @ GünterZöchbauer Дякую за роз’яснення цього. Я б хотів, щоб я міг поділитися посиланням. Я дотримувався поради Нейта Мюррея в його книзі "НГ-книга Повна книга про кутовий 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 () працює на обробці подій, навіть не передаючи $ події

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


doSomething(){
   // write any code here

   event.stopPropagation();
}

1

Вимкнути посилання href з JavaScript

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

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

Як це також має працювати в TypeScript з Angular (Моя версія: 4.1.2)

Шаблон
<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;
}

Але це не відключає виконання routerLink!


0

Додавання помилки після функції зупинить поширення події

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

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']" />
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.