首頁
學習紀錄
遊戲心得影視Life書單案件檔案
Side Projects委託作品與二創互動實驗場
Kurau
百百 BLOG
首頁
學習紀錄
遊戲心得影視Life書單案件檔案
Side Projects委託作品與二創互動實驗場
Kurau

Kurau Blog

「隨心而寫,真真假假,都是我」

一個記錄生活、輸出興趣的個人空間。
遊戲、影視、閱讀、學習……每一段體驗都值得留下文字。

頁面導覽

  • 學習紀錄
  • 遊戲心得
  • 影視Life
  • 書單
  • 委託作品與二創
  • Kurau
  • 合作邀請

找到我

歡迎來 Discord 找我聊天!

“曾經發生的事不可能忘記,只是暫時想不起來而已。”-《神隱少女》

© 2026 Kurau All rights reserved

前端基礎

滑鼠滾輪事件 (WheelEvent)

By Kurau·2023-03-07·Updated 2026-05-09·3 分鐘閱讀

滑鼠滾輪事件(WheelEvent)

TL;DR
用 Math.sign(e.deltaY) 取得方向(+1 下 / -1 上)。需要阻止頁面捲動時必須 { passive: false },否則 preventDefault() 會被忽略。

取方向最簡寫法

const delta = Math.sign(e.deltaY);
// e.deltaY > 0  → +1(向下/向後滾)
// e.deltaY < 0  → -1(向上/向前滾)
// e.deltaY = 0  →  0
typescript
為什麼用 Math.sign 不直接用 e.deltaY?
不同裝置(滑鼠、觸控板、Magic Mouse)的 deltaY 數值大小差很多(可能 1、3、100),只有方向是穩定的。要做「滾一格 = 縮放一級」這種離散行為,只看方向比較可靠。

WheelEvent 屬性

屬性說明
deltaX水平滾動量(觸控板左右滑)
deltaY垂直滾動量(最常用)
deltaZZ 軸滾動量(極少用)
deltaMode0=像素 / 1=行 / 2=頁(跨瀏覽器差異主要來自這)

實用範例:縮放功能

let scale = 1;

element.addEventListener('wheel', (e) => {
  e.preventDefault();              // 阻止頁面捲動
  const direction = Math.sign(e.deltaY);
  if (direction > 0) {
    scale *= 0.9;                  // 往下滾:縮小
  } else if (direction < 0) {
    scale *= 1.1;                  // 往上滾:放大
  }
  element.style.transform = `scale(${scale})`;
}, { passive: false });            // ⚠️ 必須 false 才能 preventDefault
javascript
passive 陷阱
使用 e.preventDefault() 時必須將 passive 設為 false,否則無法阻止預設行為,console 會出現: Unable to preventDefault inside passive event listener invocation.

詳見 監聽 passive 屬性。


跨裝置 / 跨瀏覽器差異

deltaMode 差異

element.addEventListener('wheel', (e) => {
  let pixels = e.deltaY;
  // 正規化:不同 deltaMode 統一成 pixel
  if (e.deltaMode === 1) pixels *= 16;       // 行 → 16px
  else if (e.deltaMode === 2) pixels *= window.innerHeight; // 頁 → 視窗高
  // 接著用 pixels 做運算
});
javascript

Mac 觸控板的慣性滾動

Mac 觸控板會在你停止滑動後繼續發送 wheel 事件(慣性),deltaY 會逐漸變小。如果做縮放,可以加 throttle 或 debounce 避免縮放過快:

import { throttle } from 'lodash';

const handleZoom = throttle((delta) => {
  scale *= delta > 0 ? 0.9 : 1.1;
}, 50);

element.addEventListener('wheel', (e) => {
  e.preventDefault();
  handleZoom(Math.sign(e.deltaY));
}, { passive: false });
javascript

常見使用場景

場景做法
滾動進度追蹤(分析、scroll-driven 動畫)passive: true,只讀不擋
自訂縮放(地圖、圖片預覽)passive: false + preventDefault
水平滾動(把垂直滾動轉成水平)passive: false + 改 scrollLeft
無限滾動觸發passive: true(用 IntersectionObserver 更好)

目錄

    ◆ 相關文章

    • 拖曳事件 (DragEvent)

      2026-05-09
    • 監聽 passive 屬性

      2026-05-09
    • iframe 嵌入

      2026-05-09
    • SCSS 編譯 前綴問題

      2026-05-09
    ← 上一篇會try{}catch{}嗎下一篇 →物件

    ◆ 關於作者

    Kurau

    個人寫作 / 創作的 SoT,記錄遊戲、影視、學習與生活。

    更多 Kurau 的文章