1. 程式人生 > >頁面載入時,新增進度條,提高使用者體驗

頁面載入時,新增進度條,提高使用者體驗

這幾個月做了個專案,在此對一些問題做一個記錄。

專案是前後端分離的,前端用的 npm+webpack。

問題:由於系統某頁面資料量過大或網路較差等原因,導致頁面還未完全加載出來,但按鈕已被載入時(js還未就緒),點選按鈕會報錯。

根據系統情況,解決方案:每個頁面載入的時候,在header上方加一個動態的進度條,同時通過css樣式在頁面上覆蓋一個透明的背景,使頁面在載入完成前不可點選。頁面完全載入後,進度條到100%,然後消失。

方案實施:

1. 在專案的系統公用檔案裡建一個loading.js檔案,內容如下:

module.exports = function() {

    class Process {

        constructor(prop) {

            this.timer = null;

            this.id = `_${(new Date().getTime() + parseInt(Math.random() *1000)).toString(32)}_loading`;

            this.maskId = `_${(new Date().getTime() + parseInt(Math.random() *1000)).toString(32)}_mask`;



            this.loading();

        }

        loading() {

            var html = [

            `<div id="${this.maskId}" class="loading-mask js-loading-mask"></div>`,

            `<div id="${this.id}" class="loading-line-wrap js-loading-line-wrap"><p class="loading-line"></p></div>`

            ], dis = [80, 90], speed = [1, 3], _dis = this.random(dis), _speed =this.random(speed);

            $('body').append(html.join(''));

            this.play(_dis, _speed, 0);

        }

        random(option) {

            var times = option[1] - option[0],

            offset = option[0];

            return Math.random() * times + offset;

        }

        play(dis, speed, num) {

            if(num + speed >= dis) {

                this.timer && clearTimeout(this.timer);

            }else {

                num = num + speed;

            }

            $(`#${this.id}`).css({width: `${num}%`});

            this.timer = setTimeout(()=>{

                this.play(dis, speed, num);
            }, 50);

        }



        completeLoading() {

            this.timer && clearTimeout(this.timer);

            $(`#${this.id}`).stop().animate({width: '100%'}, ()=> {

                $(`#${this.id}`).remove();

                $(`#${this.maskId}`).remove();

            })

        }

    }

    return new Process();

}

2. 在系統公用的樣式檔案common.scss里加上透明背景及進度條樣式,內容如下:

.loading-mask{

    position: fixed;

    top: 0;

    left: 0;

    width: 100%;

    height: 100%;

    background: #000;

    opacity: 0;

    filter:alpha(opacity=0);

}

.loading-line-wrap{

    position: fixed;

    top: 0;

    left: 0;

    width: 0;

    height: 2px;

    background: #2aa7ff;

    z-index: 100000;

}

3. 在系統的 main.js檔案(系統的入口檔案)引入 loading.js並做處理。下面省略了一些不相關的程式碼。有//*********的為此次新增程式碼。

import loading from './common-component/loading/loading.js';//*********


/**此處省略部分程式碼**/



let ajaxObj = {}, ajaxSend = {};//*********

$.ajaxSetup({//*********

    cache: false,//*********

    beforeSend: function(a, b, c, d){//*********

        if(ajaxObj[`_${decodeURIComponent(this.url)}`]) {//*********

            delete ajaxObj[`_${decodeURIComponent(this.url)}`];//*********

        }//*********

        ajaxObj[`_${decodeURIComponent(this.url)}`] = loading();//*********

    }//*********

});//*********



const router = new Router(routes).configure({

    notfound: () => {

        alert('錯誤連結!');

    },

    before: () => {

        $("div[id^=easytip-div-main],div.flatpickr-calendar").remove();

        let token = Util.getCookie('token');

        // 每個路徑初始化商品分類

        window.goodsClassify = null;

        ajaxObj = {};//*********

        $('.js-loading-line-wrap,.js-loading-mask').remove();//*********

        $(".classify-dialog").remove();

        if(!token && location.hash.indexOf('/login') < 0){

            window.location.href = '/login.html'

            return false;

        }

        chageText();

        checkCurrentManager(function () {

            detailFun();

        });

    },

    after:() =>{

        sessionStorage.removeItem('funcBtn');

        Object.keys(ajaxSend).map(key=>{//*********

            ajaxSend[key].abort();//*********

        });//*********

        ajaxSend = {};//*********

    }

});

router.init();



//初始化預設路由

if(!Util.getRouter()){

    Util.linkTo('/');

}



// header文字切換

function chageText() {

    let hashCode = window.location.hash,

    $pageTitle = $("#js-page-title"),

    $text = $pageTitle.find('.js-header-title'),

    text = '點選收起選單';



    if(hashCode == '#/home-page') {

        text = 'Hi,歡迎登入xx系統,xxxxxxxx!';

    }else {

        if($('body').hasClass('hide-menu')) {

            text = '點選展開選單';

        }

    }

    $text.text(text);

}



function clearLoading(key) {//*********

    if(ajaxObj[`_${decodeURIComponent(st.url)}`]) {//*********

        ajaxObj[`_${decodeURIComponent(st.url)}`].completeLoading();//*********

        delete ajaxObj[`_${st.url}`];//*********

    }//*********

}//*********



/**

* Desc: 使用者未登入統一攔截模組.

*/

$(document).ajaxComplete(function(e,xhr,st){

    var status = xhr.status;

    if(ajaxObj[`_${decodeURIComponent(st.url)}`]) {//*********

        ajaxObj[`_${decodeURIComponent(st.url)}`].completeLoading();//*********

        delete ajaxObj[`_${st.url}`];//*********

    }//*********



    if(ajaxSend[`_${decodeURIComponent(st.url)}`]) {//*********

        delete ajaxSend[`_${decodeURIComponent(st.url)}`];//*********

    }//*********

    if(status == 401 ){//使用者未登入 則刪除token跳轉登入

        Util.deleteCookie("token",document.domain);

        sessionStorage.clear();

        window.location.href = '/login.html';

    }

}).ajaxSend(function(e,xhr,st){//*********

    ajaxSend[`_${decodeURIComponent(st.url)}`] = xhr;//*********

});



function checkCurrentManager(callback) {//檢查當前操作員密碼狀態

    $.ajax({

        type:'post',

        url:API.checkCurrentManager,

        // async:false,

        success:function(msg){

            if(msg.success){

                callback ? callback() : null;

                let name = ((msg.result || {}).status || {}).name;

                if((msg.result || {}).firstTimeLoginFlag) {//首次登入,強制修改密碼

                    window.location.href = '/#/modify-pwd?flag=1';

                }else {

                    if(name == 'NORMAL'){//正常

                    }else if(name == 'PASSWORD_INVALIDATE'){//密碼失效

                        $(".passwordTi").addClass('hide');

                        $(".passwordDesc,.passwordStatus").removeClass('hide');

                        Util.linkTo('/modify-pwd');

                    }else if(name == 'NEED_MODIFY_PASSWORD'){//需要修改密碼

                        $(".passwordDesc,.passwordStatus").addClass('hide');

                        $(".passwordTi").removeClass('hide');

                    }

                }

            }else{

                Util.alertMessage(msg.error);

            }

        }

    });

}



function detailFun() {

    let hashCode = window.location.href;

    if(hashCode.indexOf('detail') > -1){

    $("#js-toggle-menu").html('Hi,歡迎登入xx系統,xxxxxxxx!')

    $("#js-page-title,.js-container-left,.content").css({marginLeft:0});

    $("#js-menu,.header-logo").css({display:'none'});
    
}

}

相關推薦

頁面入時新增進度提高使用者體驗

這幾個月做了個專案,在此對一些問題做一個記錄。 專案是前後端分離的,前端用的 npm+webpack。 問題:由於系統某頁面資料量過大或網路較差等原因,導致頁面還未完全加載出來,但按鈕已被載入時(js還未就緒),點選按鈕會報錯。 根據系統情況,解決方案:每個頁面載入的時

三種方式實現自定義圓形頁面載入中效果的進度包含一個好看的Android UI

效果圖如下:下載地址 樣式一、通過動畫實現定義res/drawable/loading.xml如下: <?xml version="1.0" encoding="UTF-8"?> ​ <animation-list android:oneshot=

總結:ajax多檔案上傳進度前端篇

前言: 之前寫過一個檔案上傳的模組,但是是多個input上傳的,而且使用的是jQuery.form打包上傳的,這樣子就覺得還是有點不太方便。 1.提交的時候需要將整個form提交上去,換句話說就是需要將要提交的內容使用form

Android與js互動進度的載入H5頁面

private void initWebView() { WebSettings settings = wvResumeDetail.getSettings(); //支援JavaScript指令碼語言 settings

jsp頁面入時div中迴圈輸出ulspan標籤接收引數並呼叫js方法

<html lang="en"> <head> <script src="relation.js"></script> </head> <body> <div id="aaa"> <

JS實例之進度制作實現進度效果

back class meta border top set inpu adding 效果 1 <head> 2 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /

Python實現下載界面(帶進度斷點續傳多線程多任務下載等)

Python 下載界面 tkinter 斷點續傳 進度條 開發環境: Windows 7 64位,Python 3.6.2 實現功能: 進度條,下載速度和下載進度的顯示,斷點續傳(暫停繼續下載功能),取消下載等功能下載界面,如圖所示點擊‘新建任務‘,彈出輸入下載鏈接的窗口,如圖所示點擊‘開

原生JS編寫了個簡易進度還請各位前輩指教~

classname 學習 UNC TP .com 開始學習 com get 能說 剛開始學習JS不久,以及第一次來到博客園,第一次進行分享博文。。。 噢,不對,不能說是分享,而是學習請教,請前輩多多指教,各個方面都可以~ 感謝您的路過~ <!DOC

#Python繪制 文本進度帶刷新、時間暫緩的

截取 字符串 alt 自動換行 分享 進行 style 進度 文本 #Python繪制 文本進度條,帶刷新、時間暫緩的 #文本進度條 import time as T st=T.perf_counter() print(‘-‘*6,‘執行開始‘,‘-‘*6)

用 Python 給程序加個進度讓你的看起來更炫酷?

image 進度條 hub 一行 ref 當前 標準輸出 alt 操作 對於開發或者運維來說,使用 Python 去完成一些跑批任務,或者做一些監控事件是非常正常的情況。那麽如何有效地監控任務的進度?除了在任務中加上 Log 外,還能不能有另一種方式來了解任務進展到哪一步了

Android 對話方塊總結(確定取消單選多選進度具體的進度

/** * 彈出確定取消對話方塊 * * @param view */ public void click01(View view) { // 工廠設計模式,得到建立對話方塊的工廠 AlertDialog

C#自定義進度可用於音樂播放器進度調整音量調整等功能

平時在做c#專案時偶爾會碰到要使用進度條的情況,但c#自帶的進度條外觀往往不合我們心意,這就需要我們自己動手來只做一款自己的進度條。先上圖:        外觀雖然簡單,但感覺比c#自帶的好看多了。 繪製這樣一個進度條需要兩個基本控制元件,兩個La

在Linux下使用makefile寫一個進度以及對\r 和\n緩衝區的簡單瞭解

1.’\r’和‘\n’的區別 \r:表示回車:它只會回到這一行的最前邊 \n:表示回車換行。它會回到這一行的最前邊,然後跳到下一行  。 2.緩衝區 c函式如printf(),在輸出時,shell預設將資料輸出到標準輸出如顯示器,而printf()在

處理流程已辦完選擇一個節點新增待辦

---找到流程例項id--- select * from ACT_HI_PROCINST t where t.proc_inst_id_ in (select distinct t.proc_inst_id_ from ACT_HI_VARINST t where t.text_='402880e864

(shell練習2)zenity圖形介面之進度滑動塊輸入、警告、錯誤、顯示對話方塊

1,程式執行進度條(這個比較好玩,有時候需要檢視某個操作的進度,可以使用這種方法) #!/bin/bash #1,自建進度條 #進度條內上要顯示的內容 ( echo "50"; sleep 1 tar -zcvf aaa.tar.gz practice/*; sleep 1 echo "1

Android 常用效果(各種進度酷炫loading動畫火箭升空撒花以及趨勢圖)

最近時間比較充裕一些,總結了下幾個專案用到的ui效果,在這邊共享給大家,也給自己做個記錄(後面會有demo貼出). 主要是以下幾種ui效果: 進度條多種展示 開源loading動畫 火箭升空 撒花

Android studio 一直在檢索目錄底部進度顯示 Indexing...

今天使用Android Studio 的時候,也不知道怎麼操作的,出現了一個問題:每當開啟 Layout 檔案的時候,底部一直在重複顯示Indexing, 重新整理速度很快, 不到一秒就重新整理一次。嘗

android自定義圓形進度實現動態畫圓效果

自定義圓形進度條效果圖如下:應用場景如動態顯示分數等。 view的自定義屬性如下attr.xml <?xml version="1.0" encoding="UTF-8"?> <resources> <declare-style

HTML5 jQuery+FormData 非同步上傳檔案進度

利用jQuery和html5的FormData非同步上傳檔案的好處是: 實現很簡單很方便地支援進度條很方便地進行擴充套件和美化 先看看效果圖: 圖片上傳後的結果: 實現步驟如下: 第二步:上傳頁面的html程式碼: [html] view plain

Android使用okhttp封裝多檔案批量下載 (帶進度取消下載)

在網上搜索了很多關於okhttp封裝的網路框架,唯獨沒找到完美實現了多個檔案批量下載的案例,當前使用的最多的也就是okhttp了,所以,我學習了各位大神的封裝後,自己也試著封裝了一個關於okhttp的網路請求框架,方便專案中的使用。 實現的功能基本如下: