使用原生JS添加進場和退場動畫詳解
前言
總所周知啊,身為一個合格的前端搬磚工,會編寫并且添加一些基礎的動畫效果可謂是比較基礎且輕車熟路的技能了。但是據我所見,大部分的前端程序員其實只會添加進場動畫,而不知道如何添加退場動畫。使用方式,也是簡單粗暴的添加一個css類。
比如下面這種情況,增加一個下拉選項的展開動畫。我們會先準備好keyframe
關鍵幀和animation
屬性的值。
.expand { transform-origin: top; animation: expand 0.3s ease both; } .fold { transform-origin: top; animation: fold 0.3s ease both; } /* 展開 */ @keyframes expand { from { transform: scaleY(0); } to { transform: scaleY(1); } } /* 折疊 */ @keyframes fold { from { transform: scaleY(1); } to { transform: scaleY(0); } }
使用的時候,就直接把這個類添加到目標元素上面,呈現出來的效果就像這樣:
誠然,這樣已經基本上能夠滿足目前的絕大部分業(yè)務需求了,而且,絕大部分的客戶也不會注意到這個退場有沒有動畫。但是,我作為一個比較喜歡鉆牛角尖的人,就特別想知道退場動畫到底是怎么實現。不過,由于我入行沒有多久,就趕上了vue普及開來了的潮流,讓我一下子喪失了找尋這個問題答案的興趣。
vue中的transition標簽
自從工作中開始使用了vue這個框架之后,媽媽再也不用擔心我不會添加退場動畫了。在vue中,添加進場和退場動畫都變得非常的容易,只需要像下面這樣就行:
<transition enter-active-class="expand" leave-active-class="fold" appear> <ul class="options-ul" v-show="isShow"> <li class="option">霧切之回光</li> <li class="option">飛雷之弦振</li> <li class="option">薙草之稻光</li> <li class="option">波亂月白經津</li> </ul> </transition>
再后來,等我可以比較熟練的應對項目上的問題的時候,我終于有閑情逸致可以探究一下究竟是怎么回事了。點開DevTools,我發(fā)現在入場動畫剛開始執(zhí)行的時候,目標元素上面會被添加上expand
類,但是等到執(zhí)行完畢的時候,expand
就被移除了。而執(zhí)行退場動畫的時候,fold
類會被添加到目標元素上,等到退場動畫結束的時候,fold
類被移除,然后元素消失。
為此,我去了解了一下vue的transition
標簽的一些內部原理。具體內容參見我這篇文章——關于transition過渡動畫的收獲;
簡單說,就是我們要利用一個比較冷門的監(jiān)聽事件animationend
來監(jiān)聽動畫是何時執(zhí)行完畢的,然后再做下一步的處理。
小DEMO
根據這個思路,我們便可以寫出一個小DEMO。代碼如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>全原生樣式的下拉框</title> </head> <style> html, body { margin: 0; } html{ --arrowSize: 8px; } div, ul { box-sizing: border-box; } html, body { width: 100%; height: 100%; background-color: #0B2550; overflow: hidden; } #app { width: 1000px; height: 500px; box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.1); box-sizing: border-box; border: 1px solid white; position: relative; margin: 100px auto; background-color: #0B2550; } .selection-wrapper{ position: relative; width: 250px; height: 50px; color: white; margin: 20px auto; font-size: 30px; font-family: 華文楷體; /*border: 1px solid #799cdc;*/ border-radius: 10px; } .displayText-box{ width: 100%; height: 100%; text-align: center; line-height: 50px; cursor: pointer; } .displayText{ user-select: none; } .arrow-icon{ position: absolute; top: 22px; right: 10px; width: 16px; height: 8px; line-height: initial; font-size: 0; transition: transform 0.3s ease; } .options-ul{ display: none; width: 100%; padding: 0; margin: 0; position: absolute; top: 60px; left: 0; border: 2px solid #BDF0FF; } .option{ list-style: none; text-align: center; line-height: 40px; cursor: default; } .expand { transform-origin: top; animation: expand 0.3s ease both; } .fold { transform-origin: top; animation: fold 0.3s ease both; } /* 展開 */ @keyframes expand { from { transform: scaleY(0); } to { transform: scaleY(1); } } /* 折疊 */ @keyframes fold { from { transform: scaleY(1); } to { transform: scaleY(0); } } </style> <body> <div id="app"> <h1 style="text-align: center;color: white;font-family: 華文楷體">選擇你想要的五星武器</h1> <div class="selection-wrapper"> <div class="displayText-box"> <div class="displayText">請選擇</div> <div class="arrow-icon"> <svg viewBox="0,0,16,8"> <path d="M 0,0 L 16,0 L 8,8 Z" fill="#31A1EF"></path> </svg> </div> </div> <ul class="options-ul expand"> <li class="option">霧切之回光</li> <li class="option">飛雷之弦振</li> <li class="option">薙草之稻光</li> <li class="option">波亂月白經津</li> </ul> </div> </div> </body> <script> const selection = document.querySelector('.displayText-box'); const ul = document.querySelector('.options-ul'); const arrow = document.querySelector('.arrow-icon'); selection.addEventListener('click',function (e){ let isExpand = ul.style.display === 'block'; if(isExpand){ // 折疊 ul.classList.add('fold'); arrow.style.transform = 'rotate(0deg)' ul.onanimationend = function (){ ul.classList.remove('fold'); ul.style.display = 'none'; } } else { // 展開 ul.style.display = 'block'; ul.classList.add('expand'); arrow.style.transform = 'rotate(180deg)' ul.onanimationend = function (){ ul.classList.remove('expand'); } } }) </script> </html>
效果如下:
結語
這個DEMO就是一個最簡單的退場動畫的實現方式,即在animationend事件中使目標元素消失。當我們清楚原生的js是怎么寫的,那么在非vue環(huán)境中,我們也可以自由自在的添加各種各樣的退場動畫了。不過,有能力的小伙伴可能就直接去看vue的transition
的源碼去了,而我這篇文章就是獻給像我一樣不想去看源碼但是還想知道一些旁門左道的知識的小伙伴。
到此這篇關于使用原生JS添加進場和退場動畫詳解的文章就介紹到這了,更多相關JS進場 退場動畫內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
解決js頁面滾動效果scrollTop在FireFox與Chrome瀏覽器間的兼容問題的方法
這篇文章為大家分享了解決js頁面滾動效果scrollTop在FireFox與Chrome瀏覽器間的兼容問題的方法,感興趣或者是遇到這種問題的朋友可以參考這篇文章2015-12-12