Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
次源碼時(shí)代H5學(xué)科老師跟大家一起來(lái)總結(jié)下在web應(yīng)用中常見(jiàn)的加載進(jìn)度條實(shí)現(xiàn)方案。
隨著html5的普及,各種css3動(dòng)畫(huà)及js特效在網(wǎng)頁(yè)中也是層出不窮,PC端加載數(shù)據(jù)的速度還是比較快的,但是對(duì)于移動(dòng)端設(shè)備而言則相對(duì)要慢不少,如果圖片或者腳本沒(méi)有加載完,用戶(hù)在操作中就可能發(fā)生各種問(wèn)題,因此我們需要對(duì)數(shù)據(jù)加載進(jìn)行偵測(cè),以更加人性化的方法將網(wǎng)頁(yè)程序內(nèi)容展現(xiàn)給用戶(hù),實(shí)現(xiàn)更佳的用戶(hù)體驗(yàn)。
先說(shuō)一下整體的實(shí)現(xiàn)思路吧,常見(jiàn)的效果是將進(jìn)度條的dom結(jié)構(gòu)顯示在頁(yè)面最“前”(使用fixed定位 + 高z-index,提高優(yōu)先級(jí)),主體內(nèi)容相當(dāng)于是被“隱藏”(實(shí)際是被遮蓋)了,所以進(jìn)度條一打開(kāi)網(wǎng)頁(yè)就有了,當(dāng)網(wǎng)頁(yè)內(nèi)容全部加載完成后,觸發(fā)js相關(guān)事件,執(zhí)行回調(diào)函數(shù):隱藏進(jìn)度條的同時(shí)顯示頁(yè)面主體內(nèi)容。
【1. 定時(shí)器模擬制作進(jìn)度條】
很多同學(xué)會(huì)使用定時(shí)器的方式實(shí)現(xiàn)網(wǎng)頁(yè)進(jìn)度條,通常可以設(shè)置延遲3到5秒鐘的時(shí)間后來(lái)顯示網(wǎng)頁(yè)內(nèi)容,這樣的確可以模擬出進(jìn)度條的加載效果,不過(guò)這種方式會(huì)有一些問(wèn)題,比如當(dāng)前頁(yè)面已經(jīng)打開(kāi)過(guò)了,瀏覽器中會(huì)有緩存數(shù)據(jù),再次開(kāi)啟頁(yè)面定時(shí)器依然會(huì)執(zhí)行,反而會(huì)影響加載性能,原本可以“瞬間”完成的內(nèi)容加載,現(xiàn)在由于定時(shí)器的原因也需要等待。還有一個(gè)就是在網(wǎng)絡(luò)情況比較糟糕的情況下,很有可能3到5秒鐘的時(shí)間也未必能夠加載完成網(wǎng)頁(yè)內(nèi)容,這個(gè)時(shí)候定時(shí)器加載又顯得比較雞肋了。
示例代碼參考:load1.html
樣式:
<font size="3"><style type="text/css">
*{
margin: 0;
padding: 0;
}
#Loading{
position: fixed;
width: 100%;
height: 100%;
background-color: orange;
color: #fff;
font-size: 40px;
text-align: center;
line-height: 10;
}
</style></font>
復(fù)制代碼
結(jié)構(gòu):
<font size="3"><!--加載頁(yè)面-->
<div id="Loading">loading...</div>
<!--內(nèi)容主體-->
<div id="Cont">Hello world</div></font>
復(fù)制代碼
交互:
<font size="3"><script>
var load_page = document.querySelector("#Loading");
setTimeout(function(){
load_page.style.display = "none";
}, 3000)
</script></font>
復(fù)制代碼
小結(jié):
1. 定時(shí)器模擬制作進(jìn)度條只能是視覺(jué)表現(xiàn)上的實(shí)現(xiàn),而非真正意義上的解決方案。
【2. 通過(guò)加載狀態(tài)事件制作進(jìn)度條】
javascrip提供了相關(guān)事件機(jī)制可以監(jiān)控頁(yè)面的加載情況,我們可以通過(guò)加載狀態(tài)事件實(shí)現(xiàn)進(jìn)度條的制作,可以使用window.onload事件,等到頁(yè)面中全部?jī)?nèi)容包括圖片加載完成后才會(huì)被觸發(fā),或者使用document.onReadyStateChange事件,在ReadyStateChange事件中可通過(guò)自變量事件參數(shù)獲取到頁(yè)面加載的當(dāng)前狀態(tài),分為5項(xiàng)內(nèi)容:
Uninitialized:未初始化
Loading:載入
Loaded:載入完成
Interactive:交互
Completed:完成
而js通過(guò)ReadyStateChange事件可以獲取到的僅為后2項(xiàng)狀態(tài),不過(guò)對(duì)于我們的代碼實(shí)現(xiàn)而言?xún)H僅只需要最后一個(gè)完成狀態(tài)即可。
示例代碼參考:load2.html(樣式代碼同load1.html)
結(jié)構(gòu):
<font size="3"><!--加載頁(yè)面-->
<div id="Loading">
loading...
</div>
<!--內(nèi)容主體-->
<div id="Cont">
<p>Hello world</p>
<img src="http://img.hb.aicdn.com/0b452ed716f0530575eff4b4e253009af7112a19bbec-Cg9NH6"/>
<img src="http://img.hb.aicdn.com/80701a6a3be8f6ce71a312385d672963f155b7627542e-qfEGEw"/>
<img src="http://img.hb.aicdn.com/8cfc2f27f9832043e3dcb87512ce6c56a8e54fed5a905-skDixu"/>
</div></font>
復(fù)制代碼
交互:
<font size="3"><script>
var load_page = document.querySelector("#Loading");
document.onreadystatechange = function(e){
if(e.target.readyState === "complete"){
load_page.style.display = "none";
}
}
</script></font>
復(fù)制代碼
小結(jié):
1. 通過(guò)加載狀態(tài)事件(window.onload或document.onreadystatechange)制作進(jìn)度條,可真正意義上實(shí)現(xiàn)頁(yè)面加載效果。
【3. 實(shí)時(shí)獲取加載數(shù)據(jù)制作進(jìn)度條】
通過(guò)加載狀態(tài)事件制作進(jìn)度條,可真正意義上實(shí)現(xiàn)頁(yè)面加載效果,但是無(wú)法顯示當(dāng)前加載進(jìn)度,當(dāng)內(nèi)容加載完成后直接就顯示出了落地頁(yè),過(guò)程中缺少了加載進(jìn)度提示,實(shí)際上對(duì)于網(wǎng)頁(yè)而言加載圖片之類(lèi)的二進(jìn)制資源文件是最大的加載開(kāi)銷(xiāo),所以通常來(lái)講圖片資源往往是最后加載完成的,其加載行為本身又是異步的,所以我們可以通過(guò)圖片自身的load事件判定其是否加載完成,執(zhí)行回調(diào)函數(shù)實(shí)時(shí)計(jì)算加載進(jìn)度,模擬實(shí)時(shí)獲取加載數(shù)據(jù)進(jìn)度條效果。
示例代碼參考:load3.html(樣式代碼同load1.html)
結(jié)構(gòu):
<font size="3"><!--加載頁(yè)面-->
<div id="Loading">
<p>loading...</p>
<h2>0%</h2>
</div>
<!--內(nèi)容主體-->
<div id="Cont">
<p>Hello world</p>
<img src="http://img.hb.aicdn.com/0b452ed716f0530575eff4b4e253009af7112a19bbec-Cg9NH6"/>
<img src="http://img.hb.aicdn.com/80701a6a3be8f6ce71a312385d672963f155b7627542e-qfEGEw"/>
<img src="http://img.hb.aicdn.com/8cfc2f27f9832043e3dcb87512ce6c56a8e54fed5a905-skDixu"/>
<img src="http://img.hb.aicdn.com/c6572538c319c2096425485d27333153ab6a4237882c4-vb7X0I"/>
<img src="http://img.hb.aicdn.com/6d43fa49d2bdfa8379150ccb28991b4377a77a394f483-5iZuD5"/>
<img src="http://img.hb.aicdn.com/14b5365bb3462895b936d08afef904e7aa665cfa2a616-eHgU0g"/>
<img src="http://img.hb.aicdn.com/29922a9799e1c29f8a5ab92b79724bd558f9d4f548ea3-xXw31P"/>
<img src="http://img.hb.aicdn.com/b4c55ba8355ac8778752029cc853a6a41e0057e16d2e0-OGreNB"/>
<img src="http://img.hb.aicdn.com/d7075bfa3490f842ca2d7f28df14ca31973052a93fd7ea-nvZYmh"/>
<img src="http://img.hb.aicdn.com/69dea0ffbc98b8a8238d611a931bf10f1b12ba6b65743-dR6cTv"/>
</div></font>
復(fù)制代碼
交互:
<font size="3"><script>
var load_page = document.querySelector("#Loading"),
h2 = document.querySelector("h2"),
imgs = document.querySelectorAll("img"),
imgs_len = imgs.length,
loaded = 0,
load_callback = function(){
loaded++;
h2.innerHTML = parseInt(loaded/imgs_len*100) + "%";
if(loaded === imgs_len) load_page.style.display = "none";
};
for(var i=0; i<imgs_len; i++){
if(imgs[i].complete == true){//圖片已加載完成
load_callback();
}else{
imgs[i].onload = function(){//圖片動(dòng)態(tài)加載完成觸發(fā)
load_callback();
}
}
}
</script></font>
復(fù)制代碼
網(wǎng)站資源擴(kuò)展:
1. 動(dòng)畫(huà)圖標(biāo)資源:www.loading.io
2. GIF預(yù)加載圖標(biāo)資源:www.preloaders.net
感謝源碼時(shí)代H5學(xué)科講師提供此文章!
本文為原創(chuàng)文章,轉(zhuǎn)載請(qǐng)注明出處(http://www.itsource.cn)!
覽器加載一個(gè)js腳本,會(huì)在devtools中留下各種痕跡,elements中的script元素,console中的日志,source中的代碼,network中的網(wǎng)絡(luò)請(qǐng)求等
這個(gè)比較簡(jiǎn)單,插入js的時(shí)候設(shè)置好id,在js中刪掉自身就好了
<script id="xxx">
// todo
document.getElementById("xxx").remove();
</script>
對(duì)于引用js
<script id="xxx" src="a.js"></script>
// a.js
document.getElementById("xxx").remove()
對(duì)于動(dòng)態(tài)加載的js也是一樣的
<script>
let e=document.createElement("script");
e.id="xxx";
e.src="a.js";
document.head.appendChild(e);
</script>
// a.js
document.getElementById("xxx").remove()
或者也可以這樣
<script>
let e=document.createElement("script");
e.src="a.js";
document.head.appendChild(e);
e.remove();
</script>
雖然看起來(lái)很奇怪,但a.js確實(shí)能執(zhí)行,似乎是加載a.js時(shí)阻塞了腳本執(zhí)行,執(zhí)行完a.js之后再remove
clear就好了
console.clear()
直接引用和動(dòng)態(tài)加載都會(huì)在source中出現(xiàn)
<script src="a.js"></script>
<script>
let e=document.createElement("script");
e.src="a.js";
document.head.appendChild(e);
</script>
這樣都是不行的,經(jīng)過(guò)測(cè)試發(fā)現(xiàn)動(dòng)態(tài)插入js代碼時(shí)不會(huì)被記錄在source中
<script>
fetch("a.js").then(resp => {
return resp.text()
}).then(text => {
let e = document.createElement("script");
e.innerHTML = text;
document.head.appendChild(e);
})
</script>
這樣a.js就不會(huì)出現(xiàn)在source里了
常規(guī)HTTP/WebSocket都會(huì)被記錄,無(wú)法繞過(guò),但是WebRTC不會(huì),WebRTC可以基于UDP/TCP傳輸,WebRTC提供createDataChannel API,可以用于傳輸文本,那么就可以實(shí)現(xiàn)network隱藏加載
考慮WebRTC需要傳遞offer和icecandidate,還是得通過(guò)HTTP/WebSocket傳輸,而且復(fù)雜網(wǎng)絡(luò)環(huán)境下還需要使用或部署STUN/TURN服務(wù)器,穩(wěn)定性有待考慮
WebRTC技術(shù)可以參考學(xué)習(xí)我最近看的幾篇文章透明日?qǐng)?bào)20200801期
其他的方法我還沒(méi)有找到,技術(shù)不行就社會(huì)工程
一個(gè)思路是可以偽裝成其他流量混過(guò)去,比如png
<script>
fetch("a.png").then(resp => {
return resp.text()
}).then(text => {
let e = document.createElement("script");
e.innerHTML = text;
document.head.appendChild(e);
})
</script>
然后在delvtools里也看不出來(lái)
另外一個(gè)思路是devtools目前只在打開(kāi)的時(shí)候記錄network數(shù)據(jù),那么只要在devtools關(guān)閉的時(shí)候加載資源,打開(kāi)就不加載,這樣就不會(huì)出現(xiàn)在network里了
新的問(wèn)題又出現(xiàn)了,如何檢測(cè)devtools的狀態(tài),網(wǎng)上已經(jīng)有不少公開(kāi)技巧了
https://github.com/sindresorhus/devtools-detect
https://github.com/AEPKILL/devtools-detector
還可以在哪里找到加載和執(zhí)行痕跡呢
還有什么方法可以隱藏這些痕跡呢
如果你現(xiàn)在也想學(xué)習(xí)前端開(kāi)發(fā)技術(shù),在學(xué)習(xí)前端的過(guò)程當(dāng)中有遇見(jiàn)任何關(guān)于學(xué)習(xí)方法,學(xué)習(xí)路線,學(xué)習(xí)效率等方面的問(wèn)題,你都可以申請(qǐng)加入我的Q群:前114中6649后671還有大牛整理的一套高效率學(xué)習(xí)路線和教程與您免費(fèi)分享,還有許多大廠面試真題。希望能夠?qū)δ銈冇兴鶐椭?/p>
下代碼來(lái)源 https://tobiasahlin.com/spinkit/
為了怕源文件刪除,我抄錄了幾個(gè).....
//html
<div class="spinner"></div>
//css
.spinner {
width: 40px;
height: 40px;
background-color: #333;
margin: 100px auto;
-webkit-animation: sk-rotateplane 1.2s infinite ease-in-out;
animation: sk-rotateplane 1.2s infinite ease-in-out;
}
@-webkit-keyframes sk-rotateplane {
0% { -webkit-transform: perspective(120px) }
50% { -webkit-transform: perspective(120px) rotateY(180deg) }
100% { -webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg) }
}
@keyframes sk-rotateplane {
0% {
transform: perspective(120px) rotateX(0deg) rotateY(0deg);
-webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg)
} 50% {
transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
-webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg)
} 100% {
transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
-webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
}
}
//html
<div class="sk-chase">
<div class="sk-chase-dot"></div>
<div class="sk-chase-dot"></div>
<div class="sk-chase-dot"></div>
<div class="sk-chase-dot"></div>
<div class="sk-chase-dot"></div>
<div class="sk-chase-dot"></div>
</div>
//css
.sk-chase {
width: 40px;
height: 40px;
position: relative;
animation: sk-chase 2.5s infinite linear both;
}
.sk-chase-dot {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
animation: sk-chase-dot 2.0s infinite ease-in-out both;
}
.sk-chase-dot:before {
content: '';
display: block;
width: 25%;
height: 25%;
background-color: #fff;
border-radius: 100%;
animation: sk-chase-dot-before 2.0s infinite ease-in-out both;
}
.sk-chase-dot:nth-child(1) { animation-delay: -1.1s; }
.sk-chase-dot:nth-child(2) { animation-delay: -1.0s; }
.sk-chase-dot:nth-child(3) { animation-delay: -0.9s; }
.sk-chase-dot:nth-child(4) { animation-delay: -0.8s; }
.sk-chase-dot:nth-child(5) { animation-delay: -0.7s; }
.sk-chase-dot:nth-child(6) { animation-delay: -0.6s; }
.sk-chase-dot:nth-child(1):before { animation-delay: -1.1s; }
.sk-chase-dot:nth-child(2):before { animation-delay: -1.0s; }
.sk-chase-dot:nth-child(3):before { animation-delay: -0.9s; }
.sk-chase-dot:nth-child(4):before { animation-delay: -0.8s; }
.sk-chase-dot:nth-child(5):before { animation-delay: -0.7s; }
.sk-chase-dot:nth-child(6):before { animation-delay: -0.6s; }
@keyframes sk-chase {
100% { transform: rotate(360deg); }
}
@keyframes sk-chase-dot {
80%, 100% { transform: rotate(360deg); }
}
@keyframes sk-chase-dot-before {
50% {
transform: scale(0.4);
} 100%, 0% {
transform: scale(1.0);
}
}
*請(qǐng)認(rèn)真填寫(xiě)需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。