常見的loading圖標,大概的樣子是這樣:(錄製的gif,比較卡)
看到大牛的面試中被問到這個問題,我就想自己動手實現一下。我們來用20行代碼實現一下。
代碼如下:
<!DOCTYPE html>
<html>
<head>
<title>加載效果</title>
<style type="text/css">
.loading{
width: 30px;
height: 30px;
border-radius: 50%;
border: 5px solid #BEBEBE;
border-left: 5px solid #498aca;
animation: load 1s linear infinite;
-moz-animation:load 1s linear infinite;
-webkit-animation: load 1s linear infinite;
-o-animation:load 1s linear infinite;
}
@-webkit-keyframes load
{
from{-webkit-transform:rotate(0deg);}
to{-webkit-transform:rotate(360deg);}
}
@-moz-keyframes load
{
from{-moz-transform:rotate(0deg);}
to{-moz-transform:rotate(360deg);}
}
@-o-keyframes load
{
from{-o-transform:rotate(0deg);}
to{-o-transform:rotate(360deg);}
}
</style>
</head>
<body>
<div class="loading"></div>
</body>
</html>
如果只考慮chrome瀏覽器的話,代碼少於20行。
基本思路是利用border-radius把div變成圓圈,然後border-left改變部分border顏色,最後使用動畫完成。
animation: load 1s linear infinite;
原來animation的循環時間屬性有一個infinite值,表示無限循環,今天之前我居然不知道,慚愧。
後續-2017/9/03
繼續寫了兩個常見的加載樣式,並分析常用的方法以及相關知識。
效果如下gif :
代碼如下:
<style type="text/css">
html,body{
background-color:#080915;
}
.loading1{
position: absolute;
left:10px;
top:10px;
width: 50px;
height: 50px;
background-color: #ed5565;
}
.loading{
width:10px;
height: 10px;
display: inline-block;
margin: 0;
border-radius: 50%;
position: absolute;
background-color: #fff;
-webkit-animation: load 0.5s cubic-bezier(0.77, 0.47, 0.64, 0.28) alternate infinite;
animation: load 0.5s cubic-bezier(0.77, 0.47, 0.64, 0.28) alternate infinite;
}
.b1{animation-delay:-0.5s;left:5px;}
.b2{animation-delay:-0.2s;left:20px;}
.b3{animation-delay: 0s;left:35px;}
@keyframes load{
from {top:10px;}
to {top:20px;}
}
@-webkit-keyframes load{
from {top:10px;}
to {top:20px;}
}
.loading2{
position: absolute;
top:10px;
left:80px;
background-color: #ed5565;
width: 60px;
height:40px;
padding-top:10px;
}
.loading2 div{
width: 4px;
height: 10px;
background-color: #fff;
display: inline-block;
margin-left:2px;
animation:load2 0.5s cubic-bezier(0.77, 0.47, 0.64, 0.28) alternate infinite;
-webkit-animation:load2 0.5s cubic-bezier(0.77, 0.47, 0.64, 0.28) alternate infinite;
}
.loading2 div:nth-child(1){
animation-delay: -0.5s;
}
.loading2 div:nth-child(2){
animation-delay: -0.4s;
}
.loading2 div:nth-child(3){
animation-delay: -0.3s;
}
.loading2 div:nth-child(4){
animation-delay: -0.2s;
}
.loading2 div:nth-child(5){
animation-delay: -0.1s;
}
@keyframes load2{
from{transform:scaleY(1);}
to{transform:scaleY(3);}
}
@-webkit-keyframes load2{
from{transform:scaleY(1);}
to{transform:scaleY(3);}
}
</style>
</head>
<body>
<div class="loading1">
<div class="loading b1"></div>
<div class="loading b2"></div>
<div class="loading b3"></div>
</div>
<div class="loading2">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</body>
上面兩個加載的css3效果,一樣是css3的動畫,關鍵思路是使用animation-delay達到延遲效果,利用transform:sacle()來達到縮放效果。還有一些效果需要使用css3的線性漸變來做。
1.animation屬性總結:
*animation 所有動畫屬性的簡寫屬性,除了 animation-play-state 屬性;
animation-name 規定 @keyframes 動畫的名稱。
animation-duration 規定動畫完成一個週期所花費的秒或毫秒。默認是 0。
animation-timing-function 規定動畫的速度曲線。默認是 “ease”。
animation-delay 規定動畫何時開始。默認是 0。
animation-iteration-count 規定動畫被播放的次數。默認是 1。
animation-direction 規定動畫是否在下一週期逆向地播放。默認是 “normal”。
animation-play-state 規定動畫是否正在運行或暫停。默認是 “running”。
animation-fill-mode 規定對象動畫時間之外的狀態。*
其中timing-function速度曲線常用linear,cubic-bezier(n,n,n,n)貝塞爾曲線;animation-delay屬性在做這個加載效果時很有用;animation-iteration-count有一個infinite值,表示無限循環;animation-direction屬性常用值:alternate表示逆向播放;
2.關於nth-child()的使用
<div class='ss'>
<div></div>
<div></div>
<div></div>
</div>
.ss div:nth-child(1){
color:#fff;
}
總結: nth:child()
僞元素本身是寫在子類上的,然後對子類寫樣式;而不是寫在父類的;參數接受數字/名稱或者公式;
1表示第一個子類;2n表示偶數;2n+1表示奇數;odd表示奇數,even表示偶數;4n+3表示每隔四個數的第三個
3.網頁的加載事件:
document.addEventListener(‘DOMContentLoaded’, function () { });
DOMContentLoaded顧名思義,就是dom內容加載完畢。從頁面空白到展示出頁面內容,會觸發DOMContentLoaded事件。而這段時間就是HTML文檔被加載和解析完成。當我們在瀏覽器地址輸入URL時,瀏覽器會發送請求到服務器,服務器將請求的HTML文檔發送回瀏覽器,瀏覽器將文檔下載下來後,便開始從上到下解析,解析完成之後,會生成DOM。如果頁面中有css,會根據css的內容形成CSSOM,然後DOM和CSSOM會生成一個渲染樹,最後瀏覽器會根據渲染樹的內容計算出各個節點在頁面中的確切大小和位置,並將其繪製在瀏覽器上。javascript會阻塞dom的解析。當解析過程中遇到<script>
標籤的時候,便會停止解析過程,轉而去處理腳本,處理完腳本之後,瀏覽器便繼續解析HTML文檔。頁面上所有的資源(圖片,音頻,視頻等)被加載以後纔會觸發load事件,簡單來說,頁面的load事件會DOMContentLoaded被觸發之後才觸發。
Jquery中的ready與load:
在 jQuery 中經常使用的 $(document).ready(function() { // ...代碼... });
其實監聽的就是 DOMContentLoaded 事件,而 $(document).load(function() { // ...代碼... });
監聽的是 load 事件(onload事件)。在用jquery的時候,我們一般都會將函數調用寫在ready方法內,就是頁面被解析後,我們就可以訪問整個頁面的所有dom元素,可以縮短頁面的可交互時間,提高整個頁面的體驗。
4.爲什麼將css放在頭部,將js文件放在尾部會優化性能。
瀏覽器生成Dom樹的時候是一行一行讀HTML代碼的,script標籤放在最後面就不會影響前面的頁面的渲染。瀏覽器爲了更好的用戶體驗,渲染引擎將嘗試儘快在屏幕上顯示的內容。它不會等到所有HTML解析之前開始構建和佈局渲染樹。部分的內容將被解析並顯示。也就是說瀏覽器能夠渲染不完整的dom樹和cssom,儘快的減少白屏的時間。假如我們將js放在header,js將阻塞解析dom,dom的內容會影響到First Paint,導致First Paint延後。所以說我們會將js放在後面,以減少First Paint的時間,但是不會減少DOMContentLoaded被觸發的時間。