load預載入簡單實現
阿新 • • 發佈:2019-02-05
很久沒寫部落格了 昨天在寫頁面的時候 突然想起一個頁面預載入的東西 試試,剛好有朋友經常接觸微信活動頁面 就聊了一下思路。
頁面資源載入就是三個 圖片 CSS JS
現在最方便的就是判斷圖片載入完畢來計算進度(JS也可以計算CSS 和JS 檔案是否載入完畢了,考慮loading頁面等待時間不能太長,所以忽略了CSS和JS,只判斷load頁面的下一個頁面所需要的圖片載入完畢來計算進度)
imgae的onload方法就是代表image載入成功了所執行的方法。這樣我們就好辦了。每次載入一張 我們就 定義一個變數 add++,然後問題來了,我們實現的邏輯最好寫在頭部,用window.onload的話必須等待所有資源和DOM載入完畢執行,jquery的$(function(){//})很好的避免了這個問題,只加載DOM完畢就執行,還好HTML5給了高階瀏覽器一個福利:
DOMContentLoaded
DOM載入之後資源載入之前執行。這樣方法很好的解決了我們loading頁面需要操作一些DOM而undnfined的錯誤。
下面看image進行邏輯計算進度條程式碼
/* * @Author: Mark * @Date: 2015-10-22 10:39:35 * @Last Modified by: Mark * @Last Modified time: 2015-10-22 11:07:11 * @param 可選 obj 如果存在就設定DOM class和ID需要加上字首,如果不存在就填寫null * @param 必填 imgs 一組圖片的陣列地址 * @param 必填 callBack 是圖片載入完畢執行的回撥函式 */ var lyloadimg=(function(){ function lyimg(obj,imgs,callBack){ this.opt_num=null; this.opt_gress=null; this.opt_aver=Math.floor(100/imgs.length); this.opt_imgs=imgs; this.opt_dom=Object.prototype.toString.call(obj).slice(8,-1)=="String"?document.querySelector(obj):null; this.callBack=callBack; this.imgEach(); } lyimg.prototype={ constructor:"lyimg", setText:function(ct){ this.opt_dom?(this.opt_dom.innerText=ct):false; }, imgEach:function(){ var that=this; this.setText(0); for (var i = 0; i < this.opt_imgs.length; i++) { var imgr=new Image(); imgr.src=this.opt_imgs[i]; imgr.onload=function(){ that.opt_num++; that.comter(this,that.opt_num); } }; }, comter:function(imgpt,numlg){ var that=this,_this=imgpt; _this.timer=setInterval(function(){ that.opt_gress++; that.setText(that.opt_gress); if(that.opt_gress>=(that.opt_aver*numlg)){ clearInterval(_this.timer); if(numlg==that.opt_imgs.length){ that.ovload(that.opt_gress); } } },1000/60) }, ovload:function(Count){ if(Count<=100){ Count=100; this.setText(Count);; } this.callBack(); } } return lyimg; })()
使用在Head裡面:
document.addEventListener('DOMContentLoaded',function(){
new lyloadimg(".s",imgArray,function(){
console.log("img loading OK");
});
},false);
然後我看了一下網上有seajs處理判斷CSS檔案是否載入完畢的程式碼,利用了判斷link節點上的
sheet
屬性來知道CSS檔案是否載入完畢,程式碼如下: function loadCss(src,fn){
var node=document.createElement('link');
node.rel='stylesheet';
node.href=src;
document.head.insertBefore(node,document.head.firstChild);
if(node.attachEvent){
node.attachEvent('onload', function(){fn(null,node)});
}else{
setTimeout(function() {
poll(node, fn);
}, 0); // for cache
}
function poll(node,callback){
var isLoaded = false;
if(/webkit/i.test(navigator.userAgent)) {//webkit
if (node['sheet']) {
isLoaded = true;
}
}else if(node['sheet']){// for Firefox
try{
if (node['sheet'].cssRules) {
isLoaded = true;
}
}catch(ex){
// NS_ERROR_DOM_SECURITY_ERR
if (ex.code === 1000) {
isLoaded = true;
}
}
}
if(isLoaded){
setTimeout(function(){
callback(null,node);
},1);
}else{
setTimeout(function(){
poll(node,callback);
},10);
}
}
node.onLoad=function(){
fn(null,node);
}
}
關於司徒正美 他的 JS時候載入完畢的邏輯判斷是根據onload或者onreadystatechange來處理的,邏輯和上面兩個的差不多,程式碼如下: function loadScript(src,fn){
var node = document.createElement("script");
node.setAttribute('async','async');
var timeID
var supportLoad = "onload" in node
var onEvent = supportLoad ? "onload" : "onreadystatechange"
node[onEvent] = function onLoad() {
if (!supportLoad && !timeID && /complete|loaded/.test(node.readyState)) {
timeID = setTimeout(onLoad)
return
}
if (supportLoad || timeID) {
clearTimeout(timeID)
fn(null,node);
}
}
document.head.insertBefore(node, document.head.firstChild);
node.src=src;
node.onerror=function(e){
fn(e);
}
}
今日分享完畢,最近實在沒有怎麼樣鑽研動畫之類的庫,在瞭解gulp前端處理的工具,感覺頹廢了,所以部落格很久才更新一次。希望儘快恢復臉皮厚的鑽研動畫的狀態。