小分享:移动端的点击事件和基于 :active 实现的按钮点击态

1,170 阅读2分钟
原文链接: zhuanlan.zhihu.com

Banner 图来自 ant.design

在封装按钮组件时候,我们一般喜欢通过 :active 实现按钮的点击态。然而有个容易被忽略的细节是:在移动设备中按下然后在该元素上移动一定的距离后点击态会消失

如果你这个组件是专门为移动端设计的,你还可能会使用各种 touch 事件的组合来模拟按钮的点击。这时候就会带来一个问题,基于上一段的设定,很可能当用户松开手指之前按钮的点击态已经消失了,点击态消失给用户的暗示就是不会触发点击事件了。

可是基于 touch 事件模拟的点击是开发者行为,而移动设备上按钮 :active 状态的变化是浏览器行为,这二者很难保持一致(我没有找到可以直接监听到按钮 :active 状态变化的办法)。因此该用户在松开手指的时候大概率还是会触发事件,这是一个不太符合预期的行为:

解决办法是可以基于 mouse 事件或者直接基于 click 来搞,这两个事件和 :active 行为是一致的。如果担心不用 touch 带来的延时问题,可以尝试其他移动设备点击延迟的解决方案。经测试,解决了延迟问题后,移动端的 click 和 mouseup 事件几乎是等效的,可以概括为在某元素上按下,未发生过一定的移动且未移开过该元素,那么松开的时候会触发。唯一的区别是如果按下了一定的时间后再松开,click 不会触发,mouseup 会(这么来看微信小程序的 tap 事件很大可能就是基于 mouseup 实现的)。

ps:录制 Gif 图的过程很痛苦...chrome 移动端调试时候长按时候一不小心会呼出菜单或选中文字,呼出菜单的问题可以通过 JS:window.oncontextmenu = () => false 来解决;选中可以通过 CSS:user-select: none 来解决。