众所周知,函数节流(throttle)是JS中非常常见的一种优化方式,可以有效防止函数执行过于频繁。比如:一个保存按钮,为了避免重复提交或者服务器的考虑,往往需要对点击行为进行一定的限制,比如每300ms只允许提交一次。这个时候我想大部分同学都会直接在网上复制一个油门函数。或者直接引用lodash工具库。btn.addEventListener('click',_.throttle(save,300))其实除了JS方法,CSS也可以很方便的实现这样的功能,不需要任何框架库。一起来看看吧。一、CSS实现思路分析CSS实现不同于JS思维,我们需要换个角度来看这个问题。比如这里需要限制点击事件,也就是禁用点击事件。考虑如何禁用该事件。是的,它是指针事件;然后有时间限制。每次点击后需要自动关闭300ms。时间经过恢复之后,那么,与时间和状态恢复相关的特性有哪些呢?没错,就是动画;另外,还需要有一个触发时机,这里是点击行为,所以肯定和伪类:active有关。所以综合分析,实现这样的功能需要pointer-events、animation和:active,那么这些思路怎么串联起来呢?想三秒钟……你想出来了吗?其实这种场景可以理解为CSS动画的控制。比如有一个动画控制按钮,从disabled->clickable变化,每次点击都重新执行动画。在执行过程中,它始终处于禁用状态,是否达到了“节流”的效果?接下来看具体实现2.CSS动画的精准控制假设有一个按钮,它绑定了一个点击事件Save处这次连续点击按钮,就会连续触发,效果如下:我们定义一个关于pointer-events的动画,暂且命名为throttle@keyframesthrottle{from{pointer-events:none;}到{指针事件:全部;}}很简单,就是disabled到clickable的变化。接下来,将此动画绑定到按钮。这里为了测试方便,动画设置为2sbutton{animation:throttle2sstep-endforwards;}注意动画的easing函数设置为stepcurve,step-end,可以方便的控制变化指针事件的时间点。如下图,0~2秒内pointer-events的值为none。一旦达到2秒,就会立刻变成全部。既然是前锋,就会一直保持在所有人的状态。最后,点击时重新执行动画。按下时只需要将动画设置为无即可。实现如下:button:active{animation:none;}为了演示方便,我们暂时将颜色变化添加到动画@keyframesthrottle{from{color:red;指针事件:无;}至{颜色:绿色;指针事件:全部;}}现在,如果文本是红色的,表示它被禁用,只有绿色表示它可以被点击。很清楚了,如下:下面是最后的点击对比效果,很好的限制了点击的频率。完整代码如下,就几行,如果需要改变限制时间,直接改变动画时间即可。button{animation:throttle2sstep-endforwards;}button:active{animation:none;}@keyframesthrottle{from{pointer-events:none;}到{指针事件:全部;}}3.其他通过CSSIdea实现为了更好的体验,可以使用realbutton来禁用btn.disabled=true。具体思路是这样的。使用:active触发transition变化,然后通过监听transition回调动态设置按钮的disabled状态。定义一个按钮如下无意义的过渡属性,例如opacitybutton{opacity:.99;过渡:不透明度2s;}按钮:不(:禁用):活动{不透明度:1;transition:0s;}然后监听transition的初始回调//transitionstartsdocument.addEventListener('transitionstart',function(ev){ev.target.disabled=true})//transitionenddocument.addEventListener('transitionend',function(ev){ev.target.disabled=false})这样做最大的好处就是这部分disabled逻辑和业务逻辑完全解耦,可以随时随地无缝访问,并且不受框架和环境的影响。效果如下:4.总结上面这段话CSS的思想实现了一个类似于“节流”的功能。与JS实现相比,实现更精简,更易上手,无框架限制。下面一起来总结一下实现要点:函数节流是一种很常见的优化方式。可以有效防止函数执行过于频繁。CSS的实现思路和JS是不一样的。关键是找到与场景关联的属性。CSS中“节流”的实现,其实就是控制一个动画的精确控制。假设有一个动画控制按钮从Disabled->Clickable改变,让这个动画在每次被点击时重新执行。在执行过程中,始终处于禁用状态,从而达到“节流”的效果。也可以通过transition的回调函数激活这种实现的好处是禁用逻辑和业务逻辑完全解耦。不过这种实现方式还是比较局限,仅限于点击行为。像许多次一样,节流可能用于滚动事件。或者在键盘事件上,直接用传统的方式实现这些场景。