摘要:一條正在繪制中的三次方貝塞爾曲線因為該曲線由四個點形成,我們將其稱為三次方貝塞爾曲線,而不是二次方曲線三個點或四次方曲線五個點。現在終于可以將貝塞爾曲線收入囊中了,也已經對這
作者:Nicolas(滬江前端開發工程師)
本文原創翻譯,轉載請注明作者及出處。
各位,趕緊綁住自己并緊緊抓牢了,因為當你掌握了特別有趣但又復雜的CSS時序函數之后,你將會真正體驗到豎起頭發般的興奮感受。
好吧,本文的主題可能還沒能讓你熱血沸騰。言歸正傳,時序函數對CSS動畫而言就像是一顆隱藏的寶石,你想得到多少驚喜取決于你如何使用它。
首先,讓我們定義下場景,并確保這些與時序函數相關的場景都是我們熟悉的。如上所述,當你在CSS動畫領域中工作時(其中包括CSS過渡和基于關鍵幀的動畫),該功能將變得可用。那么,它究竟是什么,它是做什么的呢?
什么是CSS時序函數它是一個不太顯眼的基于動畫的CSS屬性之一,而它的大多數的相鄰屬性都是相當自明的。然而,它的特別之處是它使你能夠控制和改變動畫的加速度 - 也就是說,它定義了動畫在指定的持續時間內加速和減速的方式。
雖然它不影響動畫的實際持續時間,但它可能會影響到用戶如何感知動畫的快或者慢。如果你還不知道它的實際意義,那么請在這里聽我娓娓道來,因為時序函數屬性比定義的更加有趣。
注意:事實上沒有確切的“時序函數”的屬性命名,當我提到這個“屬性”時,既是指transition-timing-function和animation-timing-function屬性。
在繼續之前,讓我們熟悉一下語法以及它適合在CSS中定義整個動畫過程的位置。為了淺顯易懂,讓我們使用CSS過渡做為例子。我們將從完整的過渡屬性數組開始:
div { transition-property: background; transition-duration: 1s; transition-delay: .5s; transition-timing-function: linear; } /* This could, of course, be shortened to: */ div { transition: background 1s .5s linear; }
對定義過渡的簡寫是相當寬松的,對于順序的唯一要求是延遲參數必須在持續時間值之后進行聲明(但不必立即跟在后面)。此外,對該功能來說transition-duration的值是唯一的必填項; 而且由于其他參數的默認值在大多數的時候都會適當填充,因此過渡很少需要超過以下的代碼片段:
div { transition: 1s; } /* This is the same as saying: */ div { transition: all 1s 0s ease; }
但這有點無趣。雖然默認值通常足以滿足頁面的標準懸停事件等,但如果你正在做一些更重要的東西,那么時序函數是微調動畫的一個重要技巧!
不管怎么樣,你現在已經有了對時序函數是干什么的基本了解。接下來讓我們來看看它是如何做到的。
揭開面紗
過去很多人可能不會在意時序函數屬性的可用的關鍵詞,它們有五個:ease(默認)ease-in,ease-out,ease-in-out和linear。然而,這些關鍵字僅僅是用于定義貝塞爾曲線的簡寫。
納尼?
你可能不了解這個術語,但是我敢打賭,如果你使用過圖形編輯軟件,然后你還創建過一條曲線,你實際上看到的是一條貝塞爾曲線!沒錯,當您使用筆或路徑工具來創建一個漂亮的平滑曲線,那么你正在繪制一條貝塞爾曲線!總之,貝塞爾曲線是時序函數背后的黑魔法 ; 它基本描述了在圖形上的加速模式。
這是關鍵字ease的貝塞爾曲線
如果你像我一樣第一次看到這樣的貝塞爾曲線,那么你可能想知道曲線是怎么從圖表上的四個點繪制而成的!我可能無法通過言語來告訴你,但幸運的是,我有一個特別精彩的GIF來幫助我解決這個問題,非常感謝維基百科。
一條正在繪制中的三次方貝塞爾曲線
因為該曲線由四個點形成,我們將其稱為“三次方”貝塞爾曲線,而不是“二次方”曲線(三個點)或“四次方”曲線(五個點)。
cubic-bezier()函數介紹那么現在,這才是真正令人感到興奮的地方了,因為我揭示了你實際上可以通過cubic-bezier()函數簡單的替換時序函數屬性值的關鍵字來訪問這個曲線。我非常理解你可能需要一些時間來控制你的興奮情緒...
你可以使用cubic-bezier()函數操縱你想要的貝塞爾曲線,從而為你的動畫創建出完全自定義的加速模式!所以,讓我們看看這個函數是如何工作的,以及它是如何使你能夠創建出屬于自己的貝塞爾曲線的。
首先,我們知道曲線由四個點形成,稱為點0,點1,點2和點3。另外一個需要注意的重要事情是,第一個點和最后一個點(0和3)已經在圖表上定義了,點0總是位于0,0(左下)和點3總是位于1,1(右上)。
這就使得你用cubic-bezier()函數只能在圖表上繪制點1和點2了。此函數傳入四個參數,前兩個是點1的x和y坐標,后兩個是點2的x和y坐標。
transition-timing-function: cubic-bezier(x, y, x, y);
為了舒適的理解語法,以及它是如何創建曲線和動畫的物理效果的,我將給你帶來5個和時序函數關鍵字相等的cubic-bezier()值以及動畫的最終效果。
EASE-IN-OUT讓我們先從ease-in-out關鍵字開始,因為這條曲線背后的邏輯以及它如何將其轉換為動畫的可能是最容易理解的。
/* The cubic-bezier() equivalent of the ease-in-out keyword */ transition-timing-function: cubic-bezier(.42, 0, .58, 1);
一個完全對稱的貝塞爾曲線,意味著動畫從慢速開始到全速,然后再減速。
你可以看到,點1位于沿著x軸的0.42處和在y軸上的0處,而點2位于x軸上的0.58和y軸上的1。這就是一條完全對稱的貝塞爾曲線,意味著動畫將低速移動至全速,然后以與起始處完全相同的速率移出。因此,這個關鍵字的名稱就是這樣來的。
如果你看一下下面的演示,你將會看到ease-in-out值的物理效果,以及它和其他關鍵字的值的不同之處。CodePen地址。
訪問CodePen上的演示效果
EASE關鍵字ease是CSS時序函數屬性的默認值,它實際上和前一個非常接近,雖然它以更快的速度移入,而以更平穩的速度移出。
/* The ease keyword and its cubic-bezier() equivalent */ transition-timing-function: cubic-bezier(.25, .1, .25, 1);
關鍵字ease的曲線以更快的速度移入,以更平穩的速度移出。
你可以看到在動畫中的這個時序函數直接轉換成的物理效果,在原點處更加陡峭,到結束點又被拉長了。在查看了這些示例后,記得參考之前的演示來對比下效果。
EASE-IN和EASE-OUT勿庸置疑,關鍵字ease-in和ease-out是正好相反的。前者是低速開始,而后者是低速結束,其他時間內都保持全速。我們之前看到的ease-in-out關鍵字如同邏輯所暗示的那樣,就是這2條貝塞爾曲線的完美組合。
/* The ease-in keyword and its cubic-bezier() equivalent */ transition-timing-function: cubic-bezier(.42, 0, 1, 1); /* The ease-out keyword and its cubic-bezier() equivalent */ transition-timing-function: cubic-bezier(0, 0, .58, 1);
ease-in貝塞爾曲線(左)| ease-out貝塞爾曲線(右)
LINEAR最后一個關鍵字就完全不是曲線了。正如其名稱所示,linear時序函數值在整個動畫過程中都保持相同的速度,這意味著所得到的貝塞爾曲線(或者根本不是)將只是一條直線。在曲線圖上表現為沒有變化的加速模式。
/* The linear keyword and its cubic-bezier() equivalent */ transition-timing-function: cubic-bezier(0, 0, 1, 1);
linear時序函數值在整個動畫期間保持相同速度。
假如你回到之前的演示,你可能會注意到,盡管所有的例子都有保持不變的持續時間值,但有一部分的動畫看起來會慢于其他動畫。這是為什么呢?就拿ease-in-out作為一個例子,我們知道,它在開始和結束時都比較慢,這意味著它所涉及動畫的中間部分需要以更快的速度執行。這就有效確保了我們感知的實際動畫會更快更短,而線性動畫看上去更長。
你也許會覺得,這篇文章寫的有點拖沓(看我都寫了些什么呀?),所以,現在是時候來寫點干貨了,看看如何使用cubic-bezier()函數來創建自定義的時序函數。
用cubic-bezier()函數創建自定義的加速模式現在我們已經看到了關鍵字是如何等同于相對應的貝塞爾曲線的,并且看到了它們在動畫上的效果,那么再來看看如何操作曲線來創建自定義加速模式。
現在你應該能夠利用cubic-bezier()函數在曲線圖上繪制點1和點2 ,并相當清楚這將會如何影響動畫。然而,考慮到你通常看不到的曲線圖上繪制點,顯然這可能會非常無趣。
幸好還存在Lea Verou這樣的牛人,他們似乎從不需要休息,直到讓CSS的開發可以變得更加簡單!Lea開發的Cubic Bézier工具,可以用來創建完整的自定義的貝塞爾曲線,并將執行的動作與預定義的關鍵字進行比較。這意味著,你可以使用這個平臺工具建立貝塞爾曲線直到得到你想要的效果,而不是在cubic-bezier()函數中無聊地編輯數字。你可以訪問Cubic Bezier然后把玩一下曲線,直到可以實現你想要的效果。這就方便多了不是嗎。
LEA Verou開發的極其有用的Cubic Bézier(查看大圖)
簡寫的關鍵字為你提供了在開始使用時序函數時有了很好的選擇,但是它們之間的差異通常較小。只有當你開始創建自定義貝塞爾曲線時,你才會意識到時序函數在動畫上會給你帶來驚人的效果。
請看下面的示例,看一下各個動畫在相同持續時間內的極端差異。CodePen地址。
讓我們仔細看一下第一個例子,試著去搞明白為什么它會產生這樣一個完全不同的效果。
/* cubic-bezier() values for first example from preceding demo page */ transition-timing-function: cubic-bezier(.1, .9, .9, .1);
自定義貝塞爾曲線的示例
這個時序函數和默認關鍵字之間的主要區別是這個陡峭的貝塞爾曲線靠近了“進度”標尺(y軸)。這意味著動畫會突然前進,在中間(即曲線接近水平時)有一段較長的幾乎暫停的低速。這種模式與我們習慣于使用時序函數關鍵字的方式形成了鮮明對比,它采用相反的方向,緩動時段出現在動畫的開始和結束,并不是在中間。
現在終于可以將貝塞爾曲線收入囊中了,也已經對這個cubic-bezier()函數的功能屬性做了徹底的探討,對嗎?也許你是這么想的,但這個狡猾的家伙還有更多的套路可以玩!
用貝塞爾曲線獲得創意沒錯:貝塞爾曲線還可以更有趣!誰會想到,只有時間標尺(x軸)被限制在曲線圖上的0-1的范圍內,而進度標尺(y軸)可以繼續延伸甚至超出0-1的范圍。
進度標尺恰如你所想象的那樣,底端(0)標記動畫的開始,頂端(1)標記動畫的結束。通常,三次的貝塞爾曲線總是以不同強度在這個進度標尺里向北方向運行,直到到達動畫的終點。然而,在0—1范圍之外繪制點1和點2的可能性將使得曲線蜿蜒回退到進度標尺內,這實際上會導致在動畫中出現反向運動!和之前一樣,理解這一點的最好方法是通過視圖:
用標準0-1范圍之外的值的自定義貝塞爾曲線
你可以看到點2在-0.5的位置,被繪制在標準0-1范圍之外,,曲線反向下拉。如果你看下面的演示,你會看到,這會在動畫的中段產生一個彈跳效果。CodePen地址。
反之,你可以把反向運動放置于動畫的起始處,并故意超出原來終點。它就像是后退了幾步又回到了起點; 然后,在終點處,你的運動慣性使你超過了目的地,導致你走了幾步后,又保證你回到預期的目的地。請看下面的示例,以徹底理解我們在這里說的什么。另外,產生這種效果的貝塞爾曲線也可以在下面看到。CodePen地址。
使用標準0-1范圍之外的值的自定義貝塞爾曲線
你現在應該對cubic-bezier()函數的值在標準的0-1范圍以外如何影響到動畫播放有一個較好的理解。當然我們可以整天看移動箱子的例子,但還是讓我們用一個有創意的時序函數逼真的演示一個示例來完成這一部分的內容。CodePen地址。
沒錯:這是一個漂浮氣球的動畫!你不總是想用CSS來做到這樣的動畫嗎?
這個動畫的要點是,當你點擊“添加氦氣”氣球飄到了“天花板”, 就像自然世界中的那樣,在碰到頂部之前會輕微回彈。使用cubic-bezier()函數的值在0-1范圍之外可以讓我們創造出彈跳,最終有助于產生一個逼真的效果。下面的代碼片段展示了在cubic-bezier()函數中使用的坐標,而最終的貝塞爾曲線的表現在下方可以看到。
/* The cubic-bezier() values for the bouncing balloon */ transition-timing-function: cubic-bezier(.65, 1.95, .03, .32);
模擬彈跳的氣球的自定義貝塞爾曲線
這個例子非常好地解釋了曲線是如何轉換為最終的動畫的,因為它表現的幾乎完美。首先,可以看到的是,曲線從進度標尺開始一直到結束都是一條直線,表示氣球以恒定的速度從動畫開始移動到結束。然后,和氣球非常相似的是,曲線從標尺的頂端向下反彈,然后再緩緩地回到頂部。相當簡單!
一旦你掌握了曲線并用它來操縱你想要的藝術品,你就成功了。
時序函數和基于關鍵幀的CSS動畫要注意的最后一點是,當應用于CSS關鍵幀動畫時時序函數是如何表現的。這些概念與我們迄今為止使用的過渡示例中的概念完全相同。但需要注意有一個重要的例外:當你應用一個時序函數設置關鍵幀時,它會在每一個關鍵幀都會被執行,而不是應用于動畫的整個部分。
為了證明這一點,假如我們有四個關鍵幀,把一個箱子在一個矩形的四個角內移動,然后你應用了“彈跳”時序函數,也就是我們在前面的氣球示例中使用的“反彈”的時序函數,那么四個關鍵幀中每一個動作都會經歷反彈,而不是整個動畫。讓我們看看這個效果和代碼。CodePen地址。
@keyframes square { 25% { top:200px; left:0; } 50% { top:200px; left:400px; } 75% { top:0; left:400px; } } div { animation: square 8s infinite cubic-bezier(.65, 1.95, .03, .32); top: 0; left: 0; /* Other styles */ }
注意,如果100%的關鍵幀沒有定義,那么元素將簡單的返回到它起點的樣式,這在這個案例中是本來想要的結果,所以就沒必要定義了。從演示中可以很明顯的看到,時序函數應用于四個關鍵幀中的每一個,因為它們每個都表現為從容器壁反彈。
如果你需要某些關鍵幀來呈現有別于其他的時序函數,可以直接使用一個多帶帶的時序函數值給到關鍵幀,比如下面的代碼片段。
@keyframes square { 50% { top: 200px; left: 400px; animation-timing-function: ease-in-out; } }step()時序函數介紹
如果你認為這就是時序函數的全部了,那么我告訴你,CSS時序函數要比預定義的緩動函數還要更多!
在這一節中,當我們通過steps()時序函數探索“分步函數”的概念時,我們可以把我們的曲線轉換成直線。
steps()函數是一個很小眾的工具,但在工具箱中仍然是有用的。它使您能夠將動畫分成多個步驟,而不是我們習慣的常規補間動畫。例如,如果我們想要將一個正方形在4秒內分四步向右移動400個像素,那么正方形將每秒向右跳100個像素,而不是連續運動。讓我們來看看在這個特殊案例中所需要的語法,既然我們已經理解了錯綜復雜的cubic-bezier()函數,這個就應該非常簡單了。CodePen地址。
div { transition: 4s steps(4); } div:target { left: 400px; }
如你所見,將動畫分割成多個步驟是如此的簡單。但要記住,這個數字必須是一個正整數,所以不能是負數或者小數。然而,第二個可選參數為我們提供了更多的控制,可能的值有start和end,后者是默認的值。
transition-timing-function: steps(4, start); transition-timing-function: steps(4, end);
Start會在每個步驟的起始位置運行動畫,而end是在每個步驟的結束處運行動畫。使用之前的“移動箱子”示例,下圖對兩者之間的差異做了很好的解釋。
start和end值在steps()函數中的差異。
可以看到,start值,只要動畫被觸發,它就會立即開始,而end值,它開始于第一個步驟的結尾處(在這個案例中,將會在一秒鐘之后被觸發)。
為了確保這個概述的足夠全面,steps()函數還可以用兩個預定義的關鍵字:step-start和step-end代替。前者相當于steps(1, start),而后者是相當于steps(1, end)。
Steps()函數的創意案例好吧,你可能沒有太多的需求來動畫一個移動的箱子,但steps()函數也有很多很酷的用途。例如,如果你有一套基礎的卡通的所有圖片精靈(sprites),那么你可以使用這種技術來逐幀播放,只需要使用幾個CSS屬性!讓我們來看一個演示和制作它功能的代碼。CodePen地址。
div { width: 125px; height: 150px; background: url(images/sprite.jpg) left; transition: 2s steps(16); /* The number of steps = the number of frames in the cartoon */ } div:target { background-position: -2000px 0; }
首先,我們有一個小的矩形框(125像素寬),它有一個背景圖像(2000像素寬),并排包含16幀。這個背景圖像最初與框的左邊緣對齊; 所以,我們現在需要做的是將背景圖像一直向左移動,以便所有的16幀都通過小矩形窗口。正常動畫下,當背景圖像向左移動時,幀將僅僅在視圖中滑動; 然而,用steps()函數,背景圖像可以移動16步到左側,確保每一個16幀的圖像可以像你希望的那樣進出視圖。就像這樣,你僅僅使用CSS過渡就可以播放一個基本的卡通!
這個GIF演示了背景圖分步通過“窗口”的概念
我還發現另一個使用steps()函數的創意來源于LEA Verou,她想出了一個特別巧妙的打字動畫。CodePen地址。
首先,你需要一些文本,但不幸的是,你還需要確切的知道你正在使用的字符數,因為你需要在CSS中使用這個數字。另一個要求是字體必須是等寬的,以便所有字符的寬度完全相同。
smashingmag
.text { width: 6.6em; width: 11ch; /* Number of characters */ border-right: .1em solid; font: 5em monospace; }
我們正在處理的文本有11個字符。在CSS單位ch的幫助下,我們實際上可以使用這個數字來定義該段的寬度,盡管我們應該指定回退寬度針對那些并不支持這個單位的瀏覽器。然后,該段落在右側顯示一個黑色實心框,這將成為光標。現在一切就緒; 我們只需要簡單的使它動起來。
這需要兩個多帶帶的動畫:一個用于光標,一個用于打字。要實現前者,我們所需要做的就是使黑色邊框閃爍,這沒有更簡單的了。
@keyframes cursor { 50% { border-color: transparent; } } .text { /* existing styles */ animation: cursor 1s step-end infinite; }
按照原先的設定,黑色邊框只會在黑色和透明之間切換,然后連續循環。這是steps()至關重要的地方,因為如果沒有它,光標也只是淡入淡出,而不會閃爍。
最后,打字動畫也很簡單。我們需要做的是在11個步驟(字符數)中將其寬度重新設置為全部寬度之前,將段落的寬度變為零。
@keyframes typing { from { width: 0; } } .text { /* existing styles */ animation: typing 8s steps(11), cursor 1s step-end infinite; }
在這里有一個關鍵幀,文本會在8秒內每次顯示一個字母,而黑色右邊框(光標)會連續閃爍。該技術非常簡單,但卻很有效。
只要加上這個由LEA Verou創造的steps()函數的極佳用法,就將完全改變效果,或許使文字看上去被刪除也不在話下。要做到這一點,只需改變下關鍵幀的關鍵字,以便它從to讀取而不是from,然后添加一個forwards的animation-fill-mode參數到一組動畫規則中。這將確保一旦文本“刪除”(即當動畫完成時),文本仍然保留被刪除狀態。看一下下面的演示。CodePen地址。
但本節中的兩個示例的缺點是,必須事先知道幀或字符的數量,以指定正確的步數,如果此數字變更了,那么您將需要同時更改代碼。盡管如此,steps()函數在此已經展現了它的價值,而且是CSS時序函數的另一個神奇功能。
瀏覽器支持情況我們已經制定的,除非瀏覽器支持基于CSS的動畫,即CSS過渡和CSS動畫(基于關鍵幀的)模塊,否則不能使用CSS時序函數。幸運的是,現在瀏覽器的支持性越來越好了。
CSS過渡的支持再次強調,對于關鍵幀動畫,只需要包含-webkit-前綴和沒有前綴的代碼。
顯然,基于CSS動畫的瀏覽器支持性是非常好的,但當涉及到時序函數時,支持性會變得略有不同。請看下表更詳細地說明。
時序函數的支持再次再次強調,雖然某些瀏覽器還需要更長一段時間才能支持時序函數的完整功能,但可以看到目前的瀏覽器版本對此功能的支持較為普遍。(譯者注:目前主流瀏覽器都已經很好的支持)
總結讓我們回顧一下,我們學到了CSS時序函數的什么?。
它們定義了動畫加速和減速的位置。
他們不僅僅是預定義的關鍵字。
您可以通過用cubic-bezier()函數在0-1范圍以外的值來創建反彈效果。
您可以將動畫分成任意數量的步驟,而不是補間動畫。
瀏覽器的支持非常好,而且在不斷改進中。
最后,這不是一篇關于CSS3技術的文章,雖然這些技術現在已經得到全面的支持,但還是需要做漸進增強。我們總是要從下到上的處理; 也就是說,漸進增強可以在不能很好支持這些功能的設備和瀏覽器上為瀏覽器優化處理,確保你的作品的可接受性和可訪問性。
除此之外,祝你在用曲線和分步的時序函數調試動畫時玩的愉快!哈~
其他參考資料
“Cubic Bézier”,Lea Verou
一個制作和對比貝塞爾曲線的平臺
“Timing Functions”,Mozilla 開發者網絡
貝塞爾曲線的更多概述
“Bézier Curves”,維基百科
了解貝塞爾曲線的更多信息
iKcamp原創新書《移動Web前端高效開發實戰》已在亞馬遜、京東、當當開售。
>> 滬江Web前端上海團隊招聘【Web前端架構師】,有意者簡歷至:zhouyao@hujiang.com <<
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/112539.html
摘要:好吧,本文的主題可能還深入剖析的深復制前端掘金一年前我曾寫過一篇中的一種深復制實現,當時寫這篇文章的時候還比較稚嫩,有很多地方沒有考慮仔細。 翻譯 | 深入理解 CSS 時序函數 - 前端 - 掘金作者:Nicolas(滬江前端開發工程師) 本文原創,轉載請注明作者及出處。 各位,趕緊綁住自己并緊緊抓牢了,因為當你掌握了特別有趣但又復雜的CSS時序函數之后,你將會真正體驗到豎起頭發般的...
摘要:前端日報精選的作用鳥瞰前端再論性能優化翻譯給創始人和們的許可協議解惑如何工作引擎深入探究優化代碼的個技巧譯文第期還是,讓我來解決你的困惑中文基礎為什么比快二分查找法你真的寫對了嗎個人文章推薦機不可失直播技術盛宴,深圳騰訊開發者大 2017-09-21 前端日報 精選 setTimeout(fn, 0) 的作用鳥瞰前端 , 再論性能優化翻譯:給創始人和 CTO 們的 React 許可協議...
摘要:模塊化是隨著前端技術的發展,前端代碼爆炸式增長后,工程化所采取的必然措施。目前模塊化的思想分為和。特別指出,事件不等同于異步,回調也不等同于異步。將會討論安全的類型檢測惰性載入函數凍結對象定時器等話題。 Vue.js 前后端同構方案之準備篇——代碼優化 目前 Vue.js 的火爆不亞于當初的 React,本人對寫代碼有潔癖,代碼也是藝術。此篇是準備篇,工欲善其事,必先利其器。我們先在代...
摘要:對于域,編譯器和處理器要遵守兩個重排序規則在構造函數內對一個域的寫入,與隨后把這個被構造對象的引用賦值給一個引用變量,這兩個操作之間不能重排序。這個屏障禁止處理器把域的寫重排序到構造函數之外。下一篇深入理解內存模型七總結 與前面介紹的鎖和volatile相比較,對final域的讀和寫更像是普通的變量訪問。對于final域,編譯器和處理器要遵守兩個重排序規則: 在構造函數內對一個fi...
摘要:前端日報精選如何優雅的編寫代碼深入理解內部機制專題之函數組合年月個有趣的和庫最經典的前端面試題之一,你能答出什么幺蛾子中文翻譯深入理解響應式原理掘金譯與和交互掘金箭頭函數使用禁忌技術棧耕耘助力美團點評前端進階之路前端模塊 2017-09-01 前端日報 精選 如何優雅的編寫 JavaScript 代碼深入理解 Node.js Stream 內部機制JavaScript專題之函數組合20...
閱讀 1628·2021-10-12 10:11
閱讀 3746·2021-09-03 10:35
閱讀 1438·2019-08-30 15:55
閱讀 2122·2019-08-30 15:54
閱讀 991·2019-08-30 13:07
閱讀 1003·2019-08-30 11:09
閱讀 568·2019-08-29 13:21
閱讀 2644·2019-08-29 11:32