E1.07.2non-overlapping hit targets设计研究
相邻按钮的命中区不得重叠
别名: 热区重叠 · 点错邻居 · overlapping hit slop
概念解释
每个按钮都可以把自己的命中区外扩,但两枚相邻按钮的命中区不能抢同一块像素。重叠之后,那一块像素的归属由 z 序、事件冒泡或「谁后挂监听」随便决定,用户无法预测。视觉上两枚键隔着 8 像素空隙,热区若在空隙中央交叠,点在「空白」上仍会激活其中一枚——而且常常是错的那一枚。
机制
外扩是对单枚按钮的优化;相邻时,两枚的外扩带在中线相撞。命中测试是点查询:一个坐标只能交给一个控件。实现若取最上层、或取后注册者,重叠带就变成一台随机机。更糟的是视觉空隙给人「点这里什么都不会发生」的模型,实际却会触发,于是取消手势(滑出按钮再抬起)也可能在空隙里点到邻居。触点还有面积,质心落在空隙、接触圆却压住两枚热区时,驱动栈的仲裁规则用户看不见。重叠不是「更易点」,是把菲茨的目标边界拆掉,让两个目标重新粘成一块含糊地带。
怎么研究
在固定视觉间距下增大双方外扩,直到热区相交,记录点在中线附近时激活了哪一枚。再比较「相交时取上层」和「相交时都不激活」两种仲裁。
自变量:视觉间距、双方外扩量、触点半径模拟、仲裁规则。 因变量:点空隙却激活的比例、激活了非意图按钮的比例、取消手势被邻居吃掉的次数。
用鼠标点精确像素会低估,因为鼠标没有接触圆。触屏或用圆形触点模拟才能看到重叠带的真实宽度。
边界
按钮组把若干动作画成一块分段控件,内部用分隔线而不是空隙,命中区在分隔线上必须有明确归属(通常各吃一半),这是刻意的邻接而不是疏忽重叠。绝对定位的关闭叉叠在卡片角落,本来就与卡片命中争夺,需要单独规定「叉优先」。指针事件为 none 的装饰层不算按钮,穿过它点到下层不叫重叠。
怎么落地
- 外扩时从中线向两侧退,保证两枚按钮的命中矩形之间留出至少一条不属任何人的缝,或把缝明确划给其中一枚并在调试层画出来。
- 工具栏图标按钮用固定槽宽(槽 ≥ 最小触达),视觉图标居中,而不是每枚各自向外扩到撞上邻居。
- 调试模式着色命中区,任何出现混色的像素都是重叠。
- 验证:沿两枚按钮之间的空隙扫一条点击。若激活左右不定,或点「空白」却触发了按钮,命中区已重叠。