# JavaScript 怎么判断鼠标现在还按着？用 MouseEvent.buttons

**URL:** <https://www.shiqidu.com/t/topic/1756>\
**Category:** 开发调优\
**Tags:** 前端开发, JavaScript\
**Created:** [2026 年8 月 10 日 10:54 UTC](https://www.shiqidu.com/t/topic/1756 "2026-08-10T10:54:55Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

作者： ![caijizhushou](https://www.shiqidu.com/user_avatar/www.shiqidu.com/caijizhushou/32/528_2.png) [@caijizhushou](https://www.shiqidu.com/u/caijizhushou)\
发布日期： [2026 年8 月 10 日 10:54 UTC](https://www.shiqidu.com/t/topic/1756/1 "2026-08-10T10:54:55Z")

</div>

`mousedown` 只能说明按键刚刚被按下。拖拽、绘图这类连续交互更关心的是另一件事：执行到某个 `mousemove` 时，主键到底还按没按着。

早期常见的办法是自己维护变量，在 `mousedown` 时加一，在 `mouseup` 时减一。问题是鼠标可能在浏览器里按下、移到窗口外再松开，这次 `mouseup` 不一定会被页面收到，变量便会一直停在“按下”状态。

## 从事件对象读取当前状态

现代浏览器的 `MouseEvent.buttons` 会告诉你事件发生时哪些按键正处于按下状态。主键对应最低位，可以这样检查：

```javascript
let primaryButtonDown = false;

function isPrimaryButtonDown(event) {
  const pressedButtons = event.buttons !== undefined
    ? event.buttons
    : event.which;

  return Boolean(pressedButtons & 1);
}

function refreshButtonState(event) {
  primaryButtonDown = isPrimaryButtonDown(event);
}

["mousedown", "mousemove", "mouseup"].forEach((eventName) => {
  document.addEventListener(eventName, refreshButtonState);
});

```

代码里仍然有一个状态变量，但它不是靠 `mousedown`、`mouseup` 次数做加减，而是每次都从事件对象重新读取。监听放在 `document` 上，而不是某个局部元素上。鼠标在窗口外松开后，只要重新移回页面，新的 `mousemove` 就会带回当前按键状态，代码也会随之修正 `primaryButtonDown`。

## 老 Safari 需要回退

这段代码保留 `event.which`，是为了兼容较老的 Safari。`buttons` 在 macOS Safari 11.1 及以上、iOS Safari 11.3 及以上可用；更早的版本里可能是 `undefined`。

这里只判断主键，所以 `(flags & 1) === 1` 足够。如果还要区分右键、中键或多个按键同时按下，不能直接照搬这一条判断，因为 `which` 与 `buttons` 对右键和中键使用的数字并不相同，需要分别处理。
