提交按钮一定要加 loading,防止用户狂点击,重复提交,频繁触发提交事件
css实现提交按钮重复提交
CSS 实现了类似 函数节流 throttle 的功能,相比 JS 实现而言,使用更简单,没有框架限制
保存按钮,为了避免重复提交或者服务器考虑,往往需要对点击行为做一定的限制,比如只允许每 1000ms提交一次
animation 动画控制
原理:对 CSS 动画的控制
有一个动画控制按钮从 禁用->可点击的变化,每次点击时让这个动画重新执行一遍,
在执行的过程中,一直处于禁用状态,是不是就达到了“节流
实现功能需要用到 pointer-events、animation以及 :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实现函数节流
btn.addEventListener('click', _.throttle(onSubmit, 1000))
css 监听事件
通过 :active去触发 transition变化,然后通过监听 transition 回调,去动态设置按钮的禁用状态
// 定义一个无关紧要的过渡属性,目的是方便监听 transitionstart & end事件
button{
opacity: .99;
transition: opacity 2s;
}
button:not(:disabled):active{
opacity: 1;
transition: 0s;
}
// 监听transition的起始回调
// 过渡开始
document.addEventListener('transitionstart', function(ev){
ev.target.disabled = true
})
// 过渡结束
document.addEventListener('transitionend', function(ev){
ev.target.disabled = false
})
Button 位置规范参考
https://ant-design.antgroup.com/docs/spec/buttons-cn
https://zhuanlan.zhihu.com/p/109644406