2017-06-13 25 views
5

Tôi dường như không thể chụp sự kiện cuộn cửa sổ. Mở nhiều trang web mà tôi tìm thấy mã tương tự như sau:Làm cách nào để xử lý sự kiện cuộn cửa sổ trong Angular 4?

@HostListener("window:scroll", []) 
onWindowScroll() { 
    console.log("Scrolling!"); 
} 

Các đoạn thường xuất phát từ phiên bản 2. Đây dường như không làm việc (? Nữa) ở góc 4.2.2. Nếu tôi thay thế "window: scroll" bằng "window: touchmove" chẳng hạn, thì sự kiện touchmove được xử lý tốt.

Có ai biết tôi đang thiếu gì không? Cảm ơn nhiều!

Trả lời

14

Có thể document của bạn không cuộn, nhưng div ở trong đó. Sự kiện cuộn chỉ bong bóng lên đến số window nếu được gọi từ document. Ngoài ra, nếu bạn chụp sự kiện từ document và gọi một số nội dung như stopPropagation, bạn sẽ không nhận được sự kiện trong số window.

Nếu bạn muốn chụp tất cả các sự kiện cuộn bên trong ứng dụng, cũng sẽ từ các vùng chứa có thể cuộn nhỏ, bạn phải sử dụng phương thức mặc định addEventListener với useCapture đặt thành true.

Điều này sẽ kích hoạt sự kiện khi nó rơi xuống DOM, thay vì giai đoạn bong bóng. Thật không may, và khá thẳng thắn bỏ lỡ lớn, góc cạnh không cung cấp một tùy chọn để vượt qua trong các tùy chọn sự kiện người nghe, vì vậy bạn phải sử dụng addEventListener:

export class WindowScrollDirective { 

    ngOnInit() { 
     window.addEventListener('scroll', this.scroll, true); //third parameter 
    } 

    ngOnDestroy() { 
     window.removeEventListener('scroll', this.scroll, true); 
    } 

    scroll =(): void => { 
     //handle your scroll here 
     //notice the 'odd' function assignment to a class field 
     //this is used to be able to remove the event listener 
    }; 

} 

Bây giờ đây không phải là tất cả để có nó, bởi vì tất cả các trình duyệt chính (ngoại trừ IE và Edge, rõ ràng) đã triển khai thông số addEventListener mới, giúp bạn có thể vượt qua đối tượng là third parameter.

Với đối tượng này, bạn có thể đánh dấu trình xử lý sự kiện là passive. Đây là một điều được khuyến nghị để thực hiện trên một sự kiện gây cháy nhiều thời gian, điều này có thể ảnh hưởng đến hiệu suất giao diện người dùng, như sự kiện cuộn. Để thực hiện điều này, trước tiên bạn nên kiểm tra xem trình duyệt hiện tại có hỗ trợ tính năng này hay không. Trên mozilla.org họ đã đăng một phương thức passiveSupported, mà bạn có thể kiểm tra hỗ trợ trình duyệt. Bạn chỉ có thể sử dụng điều này, khi bạn chắc chắn bạn sẽ không sử dụng event.preventDefault()

Trước khi tôi chỉ cho bạn cách thực hiện điều đó, có một tính năng hiệu suất khác mà bạn có thể nghĩ đến. Để ngăn phát hiện thay đổi đang chạy (số DoCheck được gọi mỗi khi có sự cố không đồng bộ xảy ra trong vùng. Giống như một sự kiện kích hoạt), bạn nên chạy trình xử lý sự kiện bên ngoài vùng và chỉ nhập nó khi cần thiết. Soo, hãy kết hợp tất cả những điều sau:

export class WindowScrollDirective { 

    private eventOptions: boolean|{capture?: boolean, passive?: boolean}; 

    constructor(private ngZone: NgZone) {} 

    ngOnInit() {    
     if (passiveSupported()) { //use the implementation on mozilla 
      this._eventOptions = { 
       capture: true, 
       passive: true 
      }; 
     } else { 
      this.eventOptions = true; 
     } 
     this.ngZone.runOutsideAngular(() => { 
      window.addEventListener('scroll', this.scroll, <any>this.eventOptions); 
     }); 
    } 

    ngOnDestroy() { 
     window.removeEventListener('scroll', this.scroll, <any>this.eventOptions); 
     //unfortunately the compiler doesn't know yet about this object, so cast to any 
    } 

    scroll =(): void => { 
     if (somethingMajorHasHappenedTimeToTellAngular) { 
      this.ngZone.run(() => { 
       this.tellAngular(); 
      }); 
     } 
    }; 
} 
+0

Cảm ơn bạn rất nhiều, điều này dường như hoạt động như mong đợi! Tôi nghĩ rằng vấn đề thực sự là bản thân tài liệu không cuộn trong tình huống của tôi. – Robert

+1

@Robert Tôi đã cập nhật câu trả lời của mình thêm một chút với thông tin bổ sung :) – PierreDuc

+0

Nội dung bên trong trình nghe trong khối mã thứ hai có tương quan với việc chặn các sự kiện không? Hơn nữa, làm thế nào để iche hướng của cuộn? –

Các vấn đề liên quan