我有兩個專案:
Bootstrap和jQuerymaterialize-css和Vanilla JS
在對兩個專案進行 Lighthouse 審計時,我曾經materialize-css在一個專案和jQuery另一個專案上收到此警告:

我說“曾經得到”,因為我確實設法修復它jQuery只是為了應用這個解決方法:
const opts = (ns) => ... // some code deciding if browser supports passive
$.event.special.touchmove = { setup: function(_, ns, handle) { this.addEventListener('touchmove', handle, opts(ns)) } }
$.event.special.touchstart = { setup: function(_, ns, handle) { this.addEventListener('touchstart', handle, opts(ns)) } }
$.event.special.touchend = { setup: function(_, ns, handle) { this.addEventListener('touchend', handle, opts(ns)) } }
這似乎解決了這個問題jQuery,我不再收到這樣的警告,一切似乎都作業正常。
現在,materialize-css我發現這個包default-passive-events(來自檔案):
每次你宣告一個新的事件監聽器時,它基本上會自動設定 {passive: true }。
不幸的是,這個庫確實使物化組件因觸摸事件而中斷,因為e.preventDefault()...
有沒有一種類似于jQuery上述解決方法的方法來修復所有materialize-css添加的事件偵聽器?PS它不使用jQuery
uj5u.com熱心網友回復:
首先,這只是一個警告,而不是錯誤。
有沒有辦法,類似于上面的 jQuery 解決方法,來修復所有添加的 materialize-css 事件偵聽器?PS它不使用jQuery
是的,實際上有三種方式:
- 在不提高性能的情況下閱讀警告
只需將{ passive: false }第三個引數添加到所有沒有物件作為第三個引數的偵聽器。這將告訴瀏覽器.preventDefault()可能會在這些事件上被呼叫。但是,尤其是在scroll,touchmove和touchstart事件上,當瀏覽器知道不會阻止某個事件的默認行為時,性能提升是相當可觀的。當標記為被動時,滾動將更加流暢,感知性能將顯著提高。
- 通過可能破壞功能來提高性能
{ passive: true }作為第三個引數添加到所有沒有物件作為第三個引數的偵聽器。這將告訴瀏覽器.preventDefault()永遠不會在這些事件上被呼叫。您會看到性能提升,但依賴于阻止這些事件的代碼將會中斷。
注意:這是 jQuery 修復程式和default-passive-events包所做的,順便說一句。
- 正確的方法
正確的方法是進入您正在修復的任何庫的源代碼,找出可能會阻止哪些事件并{ passive: false }為這些事件添加,同時{ passive: true }為其他所有內容添加。
我認為找到所有在庫中阻止事件的地方并不是一項艱巨的任務。
您可以在 fork 中執行此操作,理想情況下將其 PR-ing 回 lib 的 repo,讓其他人受益,就像您從 lib 本身中受益一樣。
這是解決方案1。
function patchScrollBlockingListeners() {
let supportsPassive = false;
const x = document.createElement("x");
x.addEventListener("cut", () => 1, {
get passive() { supportsPassive = true; return !!1 }
});
x.remove();
if (supportsPassive) {
const originalFn = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function(...args) {
if (
['scroll', 'touchmove', 'touchstart'].includes(args[0]) &&
(typeof args[2] !== 'object' || args[2].passive === undefined)
) {
args[2] = {
...(typeof args[2] === 'object' ? args[2] : {}),
passive: false
};
}
originalFn.call(this, ...args);
}
}
}
patchScrollBlockingListeners();
上面的代碼唯一的“補丁” scroll,touchmove和touchstart事件(通過宣告它們的非無源)。這使得警告消失,而無需觸及第三方代碼。
注意:為了使其作業,必須在加載任何引發警告的庫之前運行該函式。上面的代碼只修補運行后添加的事件,它不會修補已經系結的偵聽器。
注意:解決方案 2 是相同的代碼,但passive覆寫設定為true.
另一個相當重要的注意事項:雖然我不能保證它對每個人都有效,但將以下內容傳遞passive給我在很多專案中“修補”了很多庫:
passive: typeof args[2] === "boolean" ? args[2] : true
它尊重之前的addEventListener語法(其中 3-rd argpassive本身就是 as boolean)并將其設定為true根本沒有指定時。但是,這將破壞passive未指定的事件,并且在某些情況下事件被取消,這就是我沒有在上面包含它的原因。
uj5u.com熱心網友回復:
我創建了一個遵循 @tao 的“正確方法”的 npm 包,不僅可以洗掉警告,還可以提高性能。請參閱被動事件支持
它確實消除了MaterializeCSS和jQuery對我造成的警告。如果您想使用它,請務必閱讀自定義部分以僅將修復應用于您需要的事件:
import { passiveSupport } from 'passive-events-support/src/utils'
passiveSupport(['touchstart', 'touchmove'])
如果您不使用模塊,請閱讀檔案以了解將其匯入專案的其他方法。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/405810.html
標籤:
