Dừng truyền sự kiện chuột


238

Cách dễ nhất để ngăn chặn sự lan truyền sự kiện chuột trong Angular 2 là gì? Tôi có nên vượt qua $eventđối tượng đặc biệt và gọi cho stopPropagation()mình hoặc có một số cách khác. Ví dụ, trong Meteor tôi chỉ có thể trở về falsetừ bộ xử lý sự kiện.

Câu trả lời:


234

Nếu bạn muốn có thể thêm phần này vào bất kỳ phần tử nào mà không phải sao chép / dán cùng một mã nhiều lần, bạn có thể tạo một lệnh để làm điều này. Nó đơn giản như dưới đây:

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

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

Sau đó, chỉ cần thêm nó vào phần tử bạn muốn:

<div click-stop-propagation>Stop Propagation</div>

5
Nó không làm việc cho tôi. Sự kiện nhấp không dừng lại :(
Diallo

9
không hoạt động với tôi, nếu tôi có nhấp chuột khác ... <nút click-stop-tuyên truyền (nhấp) = "test ($ event)"> test </ button>
Bibby Chung

Đã làm cho tôi. Sử dụng Angular 5.2.9
yarz-tech

1
Bạn có thể cần lắng nghe một sự kiện chuột khác nhau (ví dụ: mousedown, mouseup).
yohosuff

1
@yohosuff làm cho một điểm tốt. Thêm phương thức này vào chỉ thị: @HostListener("mousedown", ["$event"]) public onMousedown(event: any): void { event.stopPropagation(); }
andreisrob

252

Đơn giản nhất là gọi lan truyền dừng trên một trình xử lý sự kiện. $eventhoạt động tương tự trong Angular 2 và chứa sự kiện đang diễn ra (bằng cách nhấp chuột, sự kiện chuột, v.v.):

(click)="onEvent($event)"

trên bộ xử lý sự kiện, chúng ta có thể dừng việc truyền bá:

onEvent(event) {
   event.stopPropagation();
}

2
Trong chỉ thị tùy chỉnh của tôi, nó không hoạt động. <button confirmMessage="are you sure?" (click)="delete()">Delete</button>và trong chỉ thị của tôi : (click)="confirmAction($event), sau đó confirmAction(event) { event.stopPropagation(); };
Saeed Neamati

4
Hãy thử trả lại sai
Joshua Michael Wagoner

dường như vào thời điểm bạn xử eventlý chức năng xử lý stopPropogation()không khả dụng. Tôi phải làm điều đó đúng trong đánh dấu: `(nhấp chuột) = "foo (); $ event.stopPropogation ()"
inorganik

Điều này không hoạt động, ít nhất là không khi được đặt trong phần tử neo. Trả lời là sai.
Shadow Wizard là Ear For You

143

Kêu gọi stopPropagationsự kiện này ngăn cản sự lan truyền: 

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

Để preventDefaulttrở vềfalse

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

Tôi đã không tự mình thử nhưng github.com/angular/angular/issues/4782github.com/angular/angular/pull/5892/files cho thấy nó sẽ hoạt động. Họ không có ;cuối cùng mặc dù. Tôi sẽ thay đổi điều đó.
Günter Zöchbauer 8/2/2016

1
Họ đang nói về việc ngăn chặn hành động mặc định, không phải là bước sự kiện thông qua các phần tử cha, stopPropagation là gì.
Rem

Ồ, đó là xấu của tôi. Lấy làm tiếc.
Günter Zöchbauer 8/2/2016

2
trở lại false<3
Pawel Gorczynski

Tuyệt vời làm thế nào câu trả lời sai có được upvotes tự động. Mã đơn giản là không hoạt động.
Shadow Wizard là Ear For You

35

Thêm vào câu trả lời từ @AndroidUniversity. Trong một dòng duy nhất bạn có thể viết nó như vậy:

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

Không nên thay đổi quá nhiều từ phiên bản này sang phiên bản khác vì họ cố gắng giữ tiêu chuẩn tạo khuôn mẫu html :)
dinigo

Hoạt động hoàn hảo với 5 góc là tốt.
imans77

10

Nếu bạn đang ở trong một phương thức bị ràng buộc với một sự kiện, chỉ cần trả về false:

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

1
không hoạt động cho các sự kiện nhấp chuột. Ít nhất là trong phiên bản mới nhất của Angular2.
Jon

6
falseGọi lại preventDefaultkhông được stopPropagation.
Günter Zöchbauer

Gọi return false không dừng việc truyền bá trong DOM. Kiểm tra sự thật của bạn @ GünterZöchbauer Nó được đề cập trong cuốn sách ng.
moeabdol

3
@moeabdol một liên kết ít nhất có thể chứng minh những gì bạn yêu cầu, nhưng thực sự preventDefaultđược gọi. github.com/angular/angular/blob/ cường , github.com/angular/angular/blob/
mẹo

1
Chính xác! @ GünterZöchbauer Cảm ơn bạn đã làm rõ điều này. Tôi ước tôi có thể chia sẻ một liên kết. Tôi đã làm theo lời khuyên của Nate Murray trong cuốn sách "ng-book The Complete Book on Angular 4" của anh ấy về việc trả lại sai; ở cuối hàm để dừng lan truyền sự kiện trong DOM. Ông mô tả nó chính xác theo cách bạn đề cập. Xin lỗi vì sự hiểu lầm.
moeabdol

8

Điều này làm việc cho tôi:

mycomponent.component.ts:

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

mycomponent.component.html:

<button mat-icon-button (click)="action($event);false">Click me !<button/>

Giải pháp này đã làm việc cho tôi trong góc 5 .. Cảm ơn bạn.
inbha

5

Tôi đã phải stopPropigationpreventDefaultđể ngăn một nút mở rộng một vật phẩm accordion mà nó ngồi phía trên.

Vì thế...

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

3

Không có gì hoạt động cho IE (Internet Explorer). Những người thử nghiệm của tôi đã có thể phá vỡ phương thức của tôi bằng cách nhấp vào cửa sổ bật lên trên các nút phía sau nó. Vì vậy, tôi đã nghe một nhấp chuột vào div màn hình phương thức của mình và buộc phải tập trung vào một nút bật lên.

<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

Tôi đã sử dụng

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

trong ngắn hạn, chỉ tách biệt các cuộc gọi / chức năng khác với ';' và thêm $ event.stopPropagation ()


2

Tôi vừa kiểm tra trong một ứng dụng Angular 6, event.stopPropagation () hoạt động trên một trình xử lý sự kiện mà không vượt qua $ event

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


doSomething(){
   // write any code here

   event.stopPropagation();
}

1

Vô hiệu hóa liên kết với JavaScript

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

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

Cách thức hoạt động trong TypeScript với Angular (Phiên bản của tôi: 4.1.2)

Bản mẫu
<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;
}

Nhưng nó không vô hiệu hóa việc thực thi bộ định tuyến!


0

Thêm false sau chức năng sẽ dừng lan truyền sự kiện

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

0

Điều này đã giải quyết vấn đề của tôi, từ việc ngăn chặn rằng một sự kiện bị trẻ em sa thải:

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


0

Hãy thử chỉ thị này

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

Sử dụng

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

<input 
    type="text" 
    [stopPropagation]="['input', 'click']" />
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.