函數(shù)節(jié)流,CSS也能輕松實現(xiàn):CSS防止按鈕重復(fù)點擊
眾所周知,函數(shù)節(jié)流(throttle)是 JS 中一個非常常見的優(yōu)化手段,可以有效的避免函數(shù)過于頻繁的執(zhí)行。
舉個例子:一個保存按鈕,為了避免重復(fù)提交或者服務(wù)器考慮,往往需要對點擊行為做一定的限制,比如只允許每300ms提交一次,這時候我想大部分同學(xué)都會到網(wǎng)上直接拷貝一段throttle函數(shù),或者直接引用lodash工具庫。
其實除了 JS 方式, CSS 也可以非常輕易的實現(xiàn)這樣一個功能,無需任何框架庫,一起看看吧
一、CSS 實現(xiàn)思路分析
CSS 實現(xiàn)和 JS 的思維不同,需要從另一個角度去看待這個問題。
比如這里的需要對點擊事件進行限制,也就是禁用點擊事件,想想有什么方式可以禁用事件,沒錯,就是pointer-events;
然后是時間的限制,每次點擊后需要自動禁用300ms,時間過后重新恢復(fù),那么,有什么特性和時間以及狀態(tài)恢復(fù)有關(guān)呢?沒錯,就是animation;
除此之外,還需要有觸發(fā)時機,這里是點擊行為,所以必然和偽類:active有關(guān)聯(lián)。
因此,綜合分析,實現(xiàn)這樣一個功能需要用到pointer-events、animation以及:active,那么如何將這些思路串聯(lián)起來呢?
思考3秒...
你想到了嗎?
其實這種場景可以理解成是對 CSS 動畫的控制,比如有一個動畫控制按鈕從禁用->可點擊的變化,每次點擊時讓這個動畫重新執(zhí)行一遍,在執(zhí)行的過程中,一直處于禁用狀態(tài),是不是就達到了“節(jié)流”的效果了?
接下來看看具體實現(xiàn)
二、CSS 動畫的精準控制
假設(shè)有一個按鈕,綁定了一個點擊事件
這時的按鈕連續(xù)點擊就會不斷地觸發(fā),效果如下:
下面定義一個關(guān)于pointer-events的動畫,就叫做 throttle 吧
很簡單吧,就是從禁用到可點擊的變化。
接下來,將這個動畫綁定在按鈕上,這里為了方便測試,將動畫設(shè)置成了2s
注意,這里動畫的緩動函數(shù)設(shè)置成了階梯曲線,step-end,它可以很方便的控制pointer-events的變化時間點。
如下示意,pointer-events在0~2秒內(nèi)的值都是none,一旦到達2秒,就立刻變成了all,由于是forwards,會一直保持all的狀態(tài)
最后,在點擊時重新執(zhí)行一遍動畫,只需要在按下時設(shè)置動畫為none就行了
實現(xiàn)如下:
為了演示方便,我們暫時把顏色變化也加在動畫里
現(xiàn)在如果文字是red,表示是禁用態(tài),只有是green,才表示可以被點擊,非常清晰明了,如下:
下面是最終點擊對比效果,很好地限制了點擊頻率。
完整代碼如下,就這么幾行,如果需要改限制時間,直接改動畫時間就行了。
三、CSS 實現(xiàn)的其他思路
為了更好的體驗,可以用上真正的按鈕禁用
具體思路是這樣的,通過:active去觸發(fā)transition變化,然后通過監(jiān)聽transition回調(diào)去動態(tài)設(shè)置按鈕的禁用狀態(tài),實現(xiàn)如下
定義一個無關(guān)緊要的過渡屬性,比如opacity
然后監(jiān)聽transition的起始回調(diào)
這樣做的最大好處是,這部分禁用的邏輯是完全和業(yè)務(wù)邏輯是解耦的,可以在任意時候,任意場合下無縫接入,也不受框架和環(huán)境影響,效果如下:
四、總結(jié)一下
以上通過 CSS 的思路實現(xiàn)了類似“節(jié)流”的功能,相比 JS 實現(xiàn)而言,實現(xiàn)更精簡、使用更簡單,沒有框架限制,下面一起總結(jié)一下實現(xiàn)要點:
- 函數(shù)節(jié)流是一個非常常見的優(yōu)化方式,可以有效避免函數(shù)過于頻繁的執(zhí)行
- CSS 的實現(xiàn)思路和 JS 不同,重點在于在于找到和該場景相關(guān)聯(lián)的屬性
- CSS 實現(xiàn)“節(jié)流”其實就是控制一個動畫的精準控制,假設(shè)有一個動畫控制按鈕從禁用->可點擊的變化,每次點擊時讓這個動畫重新執(zhí)行一遍,在執(zhí)行的過程中,一直處于禁用狀態(tài),這樣就達到了“節(jié)流”的效果
- 還可以通過 transition 的回調(diào)函數(shù)動態(tài)設(shè)置按鈕禁用態(tài)
- 這種實現(xiàn)的好處在于禁用邏輯和業(yè)務(wù)邏輯是完全解耦的
不過,這種實現(xiàn)方式還是比較有局限的,僅限于點擊行為,像很多時候,節(jié)流可能會用在滾動事件或者鍵盤事件上,像這些場景就用傳統(tǒng)方式實現(xiàn)就行了。