提交按钮一定要加 loading,防止用户狂点击,重复提交,频繁触发提交事件

css实现提交按钮重复提交

CSS 实现了类似 函数节流 throttle 的功能,相比 JS 实现而言,使用更简单,没有框架限制
保存按钮,为了避免重复提交或者服务器考虑,往往需要对点击行为做一定的限制,比如只允许每 1000ms提交一次

animation 动画控制

原理:对 CSS 动画的控制
有一个动画控制按钮从 禁用->可点击的变化,每次点击时让这个动画重新执行一遍,
在执行的过程中,一直处于禁用状态,是不是就达到了“节流

实现功能需要用到 pointer-eventsanimation以及 :active,

  • 禁用事件,pointer-events
  • animation 时间以及状态恢复,每次点击后需要自动禁用300ms,时间过后重新恢复
  • 触发时机,这里是点击行为,和伪类 :active有关联

好处:禁用的逻辑是完全和业务逻辑是解耦,不受框架和环境影响
局限性:仅限于点击行为

  • 3s 限制时间
  • 缓动函数设置成了阶梯曲线,step-end,很方便的控制 pointer-events 的变化时间点 ```less // 动画绑定在按钮上 .btn-throttle { animation: throttle 3s step-end forwards; }

.btn-throttle:active { animation: none; }

/**

  • 从禁用到可点击的变化
  • pointer-events 在0~2秒内的值都是none,一旦到达2秒,就立刻变成了all
  • forwards,会一直保持all的状态
  • 在点击时重新执行一遍动画,只需要在按下时设置动画为 none */ @keyframes throttle { from { pointer-events: none; } to { pointer-events: all; } } ```

lodash实现函数节流

  1. btn.addEventListener('click', _.throttle(onSubmit, 1000))

css 监听事件

通过 :active去触发 transition变化,然后通过监听 transition 回调,去动态设置按钮的禁用状态

  1. // 定义一个无关紧要的过渡属性,目的是方便监听 transitionstart & end事件
  2. button{
  3. opacity: .99;
  4. transition: opacity 2s;
  5. }
  6. button:not(:disabled):active{
  7. opacity: 1;
  8. transition: 0s;
  9. }
  10. // 监听transition的起始回调
  11. // 过渡开始
  12. document.addEventListener('transitionstart', function(ev){
  13. ev.target.disabled = true
  14. })
  15. // 过渡结束
  16. document.addEventListener('transitionend', function(ev){
  17. ev.target.disabled = false
  18. })

Button 位置规范参考

https://ant-design.antgroup.com/docs/spec/buttons-cn
https://zhuanlan.zhihu.com/p/109644406