停止与发送原地互换要加点击守卫
机制
click 在 mousedown/mouseup 都完成才派发,而按钮的身份在 mousedown 与 mouseup 之间已经改变 → 用户按下的是停止,触发的是发送。这是同一坐标承载两种语义动作的固有竞态,不是偶发 bug。
修法取舍
- 加时间窗守卫最简单,代价是「停止后极短时间内无法点击发送」(Enter 不受影响)。
- 更彻底的做法是让两个动作不共享同一命中区(位置分离,或保持元素身份只换内容)。
- 一般化:任何「同一控件原地切换语义」的交互(播放/暂停、开始/停止、展开/收起)都要考虑这个竞态。
相关
- 隐藏态按钮要保留命中区 —— 同属「按钮命中区与状态切换」类问题
- 过期响应不能覆盖当前编辑内容
- 条件return前必须调用所有hooks