页面加载时,添加进度条,提高用户体验

这几个月做了个项目,在此对一些问题做一个记录。

项目是前后端分离的,前端用的 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'});
    
}

}

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值