Unable to preventDefault inside passive event listener due to target being treated as passive

一.需求: tab導航要求滾動效果

在這裏插入圖片描述

二.問題: iscroll左右滾動不流暢,

網上找了一通,大致有以下三種解決方法

方法一: 爲滾動區域外層div添加下列css樣式
  ```css
  #wrapper {
      touch-action: none;
  }
方法二: 添加disablePointer參數
new IScroll('#wrapper', {
    disablePointer: true
});
方法三: 爲document對象的touchmove事件添加{passive: false}
document.addEventListener('touchmove', function (event) {
    event.preventDefault();
}, {
    passive: false
});

結果不盡人意, 要麼是滑動不順暢問題沒結局,要麼是向下滑動加載內容時彈出以下報錯

Unable to preventDefault inside passive event listener due to target being treated as passive....
https://www.chromestatus.com/features/5093566007214080

根據錯誤提示中的鏈接找到下列解釋

AddEventListenerOptions defaults passive to false. With this change touchstart and touchmove listeners added to the document will default to passive:true (so that calls to preventDefault will be ignored)… If the value is explicitly provided in the AddEventListenerOptions it will continue having the value specified by the page. This is behind a flag starting in Chrome 54, and enabled by default in Chrome 56. See https://developers.google.com/web/updates/2017/01/scrolling-intervention

要了解上面的問題,我們先來看看addEventListener方法,實際上該方法是可接受第三個參數的,分別是capture, once, passive, 因此,下列寫法是等價的

target.addEventListener(type, listener);
target.addEventListener(type, listener, false);
target.addEventListener(type, listener, {useCapture: false});

那passive參數是幹嘛的呢?

passive: Boolean,表示 listener 永遠不會調用 preventDefault()。如果 listener 仍然調用了這個函數,客戶端將會忽略它並拋出一個控制檯警告。

三. 最終解決方案, 在外面的wrapper上面使用e.preventDefault

 document.getElementById('scroller').addEventListener('touchmove',  function (e) { e.preventDefault(); }, { passive: false });

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章