大概思路:
1. 取得當前的滾輪位置
2. 滾動事件強制滾動到該位置(所以就不會往下滾了)
https://www.geeksforgeeks.org/how-to-disable-scrolling-temporarily-using-javascript/
可以防止使用 `body: { overflow: hidden; }` 時因為滾輪消失而造成 UI 抖動的樣子
## 為什麼不能直接新增 `onScroll` 事件並且取消呢?
本來想說就直接取消 `scroll` 事件就行了,結果發現行不通:
```javascript!
window.addEventListener('scroll', (event) => event.preventDefault())
```
上網查到才發現 `scroll` 事件是不能被取消的:
> The scroll event cannot be canceled. *[ref.](https://stackoverflow.com/questions/4770025/how-to-disable-scrolling-temporarily)*
所以必須用其他事件組合,這些事件都可以達到「往下滾動的行為」:
```javascript!
// [ref. How to disable scrolling temporarily?](https://stackoverflow.com/questions/4770025/how-to-disable-scrolling-temporarily)
// left: 37, up: 38, right: 39, down: 40,
// spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
/** 觸發往下滾動的按鍵 keys */
var keys = {37: 1, 38: 1, 39: 1, 40: 1};
function preventDefault(e) {
e.preventDefault();
}
function preventDefaultForScrollKeys(e) {
if (keys[e.keyCode]) {
preventDefault(e);
return false;
}
}
// modern Chrome requires { passive: false } when adding event
var supportsPassive = false;
try {
window.addEventListener("test", null, Object.defineProperty({}, 'passive', {
get: function () { supportsPassive = true; }
}));
} catch(e) {}
var wheelOpt = supportsPassive ? { passive: false } : false;
/** 直接建立一個 div 後再透過判斷取得當前瀏覽器支援的 event type */
var wheelEvent = 'onwheel' in document.createElement('div') ? 'wheel' : 'mousewheel';
// call this to Disable
function disableScroll() {
window.addEventListener('DOMMouseScroll', preventDefault, false); // older FF
/** wheel / mouseWheel 是滑鼠滾輪滾動後會觸發的事件 */
window.addEventListener(wheelEvent, preventDefault, wheelOpt); // modern desktop
window.addEventListener('touchmove', preventDefault, wheelOpt); // mobile
window.addEventListener('keydown', preventDefaultForScrollKeys, false);
}
// call this to Enable
function enableScroll() {
window.removeEventListener('DOMMouseScroll', preventDefault, false);
window.removeEventListener(wheelEvent, preventDefault, wheelOpt);
window.removeEventListener('touchmove', preventDefault, wheelOpt);
window.removeEventListener('keydown', preventDefaultForScrollKeys, false);
}
```
### `scroll` 跟 `wheel` 是不同的事件喔
> onwheel specifically fires when the mouse wheel is spun. onscroll fires for any kind of scrolling, including keyboard buttons like the arrow keys, Home, End, Page Up, Page Down, space bar, tabbing etc.
> `wheel` 是只有滑鼠滾輪滾動才會觸發,而 `scroll` 是當頁面滾動(不管任何方式,滾動或者透過鍵盤達到頁面滾動等)都會觸發。
## 參考資料
- [What's the difference between "onwheel" and "onscroll" events?](https://stackoverflow.com/questions/32719495/whats-the-difference-between-onwheel-and-onscroll-events)
- [How to disable scrolling temporarily?](https://stackoverflow.com/questions/4770025/how-to-disable-scrolling-temporarily)