錯誤資訊:Unable to preventDefault inside passive event listener due to target being treated as passive.
是時候 google 了。
在 chrome 56 版本的更新日志中又這樣一段話。
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
又看到 google 曾發過這樣幾篇部落格。(需要翻牆)
passive-event-listeners
scrolling-intervention
經過一番折騰,大概知道了為什麼。(看部落格下的評論,程式員們對這一改動一片“叫好“,呵呵~)
google 這一改動是為了移動端滾動更加流暢,在 chrome 56 版本之後,對 touchstart 和 touchmove 事件處理函數,會預設設為 passive: true。是以預設也會忽略 preventDefault() 的調用。
也就是這樣:
window.addEventListener('touchmove', func)
window.addEventListener('touchmove', func, { passive: true }) // 預設為 true,等同上句
那麼知道導緻問題的原因,怎麼解決呢?
1、方案一:
2、方案二:
body {
touch-action: none
}
通過這個可以防止觸發預設事件,同時touch相關事件還能保持有效。
3、方案三:
document.body.addEventListener('touchmove', function(e) {
// 判斷預設事件是否可以禁止
if (e.canelable) {
e.preventDefault();
}
})
第三種方案,pc端和移動端表現不一緻,剛好可以避免pc端報這個錯誤。不過測試過程中,還有其他不确定問題,不建議用。