Xem xét việc đánh dấu trình xử lý sự kiện là 'thụ động' để làm cho trang phản hồi nhanh hơn


217

Tôi đang sử dụng búa để kéo và nó đang bị giật khi tải các thứ khác, vì thông báo cảnh báo này đang nói với tôi.

Việc xử lý sự kiện đầu vào 'touchstart' đã bị trì hoãn trong X ms do luồng chính đang bận. Xem xét việc đánh dấu trình xử lý sự kiện là 'thụ động' để làm cho trang phản hồi nhanh hơn.

Vì vậy, tôi đã cố gắng thêm 'thụ động' cho người nghe như vậy

Hammer(element[0]).on("touchstart", function(ev) {
  // stuff
}, {
  passive: true
});

nhưng tôi vẫn nhận được cảnh báo này.

Câu trả lời:


264

Đối với những người nhận được cảnh báo này lần đầu tiên, đó là do một tính năng vượt trội có tên là Trình nghe sự kiện thụ động đã được triển khai trong các trình duyệt khá gần đây (mùa hè 2016). Từ https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md :

Trình lắng nghe sự kiện thụ động là một tính năng mới trong thông số DOM cho phép nhà phát triển chọn tham gia để có hiệu suất cuộn tốt hơn bằng cách loại bỏ nhu cầu cuộn để chặn người nghe sự kiện cảm ứng và bánh xe. Các nhà phát triển có thể chú thích người nghe cảm ứng và bánh xe với {passive: true} để cho biết rằng họ sẽ không bao giờ gọi ngăn chặn Default. Tính năng này được vận chuyển trong Chrome 51, Firefox 49 và hạ cánh trên WebKit. Đối với lời giải thích chính thức đầy đủ đọc thêm ở đây.

Xem thêm: Người nghe sự kiện thụ động là gì?

Bạn có thể phải đợi thư viện .js của mình triển khai hỗ trợ.

Nếu bạn đang xử lý các sự kiện một cách gián tiếp thông qua thư viện JavaScript, bạn có thể sẵn sàng hỗ trợ tính năng của thư viện cụ thể đó. Kể từ tháng 12 năm 2019, có vẻ như không có bất kỳ thư viện lớn nào đã triển khai hỗ trợ. Vài ví dụ:


16
Thư viện ion thì sao?
abhit

10
Tôi đang gọi preventDefault()- Có thể chặn cảnh báo này không?
maja


12
API Google Maps phiên bản 3 cũng tạo ra những cảnh báo này. Vấn đề đang được theo dõi tạisuetracker.google.com/issues/63211698 . (Kiểu mỉa mai, khi xem xét rằng Google Chrome đang cảnh báo về các vi phạm mà API JavaScript của Google Maps tạo ra.)
Joool Schulenklopper

6
để loại bỏ cảnh báo này, bạn có thể `addEventListener ('touchstart', this.callPassedFuntion, {passive: false})`
Shlomi Schwartz

8

Điều này ẩn thông điệp cảnh báo:

jQuery.event.special.touchstart = 
{
  setup: function( _, ns, handle )
  {
    if ( ns.includes("noPreventDefault") ) 
    {
      this.addEventListener("touchstart", handle, { passive: false });
    } 
    else 
    {
      this.addEventListener("touchstart", handle, { passive: true });
    }
  }
};

5
Mục tiêu sẽ là dừng sự kiện thực tế? Tôi sẽ không muốn ẩn tin nhắn cho đến khi tôi xử lý vấn đề.
yardpenalty.com

1
Tôi nghĩ đó là một vấn đề thư viện jquery. Tôi nghĩ các nhà phát triển sẽ phải sửa nó. Nhưng nếu bạn sẽ nhận được nó, hãy cho tôi biết làm thế nào để làm điều đó xin vui lòng. Cảm ơn bạn rất nhiều.
Iván Rodríguez

Chắc chắn là Ivan! Vâng, đúng vậy. Này, bây giờ tôi tò mò ... Tôi đang sử dụng plugin d3 và tôi đang nhận được 2300 vi phạm. Có thể mã của bạn sẽ giúp! Tôi sẽ giữ cho bạn được đăng!
yardpenalty.com

@ yardpenalty.com, không, dừng sự kiện không phải là mục tiêu! Các trạng thái cảnh báo bạn đã đặt trình nghe của mình mà không chỉ định liệu nó có thể hoặc không thể ngăn chặn hành vi mặc định đối với sự kiện. Nếu bạn có trường hợp bạn muốn gọi preventDefault(), bạn nên chỉ định passive: false. Nếu không, chỉ định passive: true. Bạn chỉ nhận được cảnh báo nếu bạn không chỉ định. Nếu bạn chỉ định passive: truepreventDefault()được gọi, nó sẽ dẫn đến lỗi và mặc định không được ngăn chặn. Chỉ định passivekhông phải là một hack ở đây. Đó là giải pháp . Đó là những gì cảnh báo yêu cầu!
tao

@tao cảm ơn đã bình luận. Đã vài năm nhưng tôi chắc chắn sẽ nhớ giải pháp trong tương lai!
yardpenalty.com

1

Cũng gặp phải điều này trong plugin thả xuống select2 trong Laravel. Thay đổi giá trị theo đề xuất của Alfred Wallace từ

this.element.addEventListener(t, e, !1)

đến

this.element.addEventListener(t, e, { passive: true} )

giải quyết vấn đề Tại sao anh ta bỏ phiếu xuống, tôi không biết nhưng nó hiệu quả với tôi.


0

Đối với những người mắc kẹt với các vấn đề cũ, hãy tìm dòng ném lỗi và thêm {passive: true}- ví dụ:

this.element.addEventListener(t, e, !1)

trở thành

this.element.addEventListener(t, e, { passive: true} )

-1

Tôi đã tìm thấy một giải pháp hoạt động trên jQuery 3.4.1 slim

Sau khi hủy bỏ, hãy thêm {passive: true}vào hàm addEventListener trên dòng 1567 như sau:

t.addEventListener(p, a, {passive: true}))

Không có gì phá vỡ và kiểm toán ngọn hải đăng không phàn nàn về người nghe.


1
không bao giờ thay đổi mã nguồn của thư viện; thay vào đó bạn nên ghi đè lên nó.
Raptor
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.