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

2023-05-16

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

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

}

 

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

页面加载时,添加进度条,提高用户体验 的相关文章

  • 多目录工程的CmakeLists.txt编写(自动添加多目录下的文件)

    实现类似于vs中工程的CMakeLists txt的编写 功能为main cpp调用hello cpp 的hello 函数 xff0c world cpp的world 函数 使用自动添加多目录下的文件 xff0c 用add library方
  • 最容易理解的对卷积(convolution)的解释

    项目github地址 xff1a bitcarmanlee easy algorithm interview and practice 经常有同学私信或留言询问相关问题 xff0c V号bitcarmanlee github上star的同学
  • 使用STM32F103做CAN的收发通信

    下面也是搭建嵌入式系统所必须的一个部分 参考网站 xff1a https www cnblogs com craigtao p 3645148 html https blog csdn net qq 29413829 article det
  • 解决matlab遇到的“错误使用 mex未找到支持的编译器或 SDK。”

    解决matlab遇到的 错误使用 mex未找到支持的编译器或 SDK 因为coco数据集转pascal数据集需要用到matlab的以下代码 xff1a span class token function mex span span clas
  • STM32开发 数据包环形队列

    目录 前言一 构建环形队列结构体二 队列初始化三 读写数据1 队列满判断2 队列空判断3 队列写入数据4 队列读取数据 四 实际使用 前言 环形队列的理论知识网上有很多文章 xff0c 这里我就仅通过代码分享一下使用经验 xff0c 在我的
  • 静态链接库lib和动态链接库ddl的区别和联系

    静态链接库lib和动态链接库ddl的区别 联系 xff1a 都是在链接阶段使用的 区别 xff1a 不同的是静态链接库中的代码会直接放到exe中 xff0c 而动态链接库在使用时才会被加载到这个exe执行的内存空间 xff0c 所以使用静态
  • 单片机与上位机的串行通信

    写在前面 这篇博客主要记录下单片机是如何通过TXD RXD与上位机进行数据交换的 先介绍下51单片机中与串口通信有关的各种寄存器 首先 xff0c 上位机如果要发送数据给单片机 xff0c 单片机接收到数据之后 xff0c 会存入到SBUF
  • 【C++知识】关于迭代器失效的几种情况

    前言 关于面试时有被问到过这类问题 xff0c 当时由于只一知半解 xff0c 回答的不是特别好 xff0c 所以今天自己特意来实验一下 希望能帮助大家有同样疑惑的人解答疑惑 xff01 目录 关于迭代器失效的几种情况 1 序列式容器迭代器
  • Yolov3+C+++opencv+VS2015成功检测

    nbsp 前言 nbsp nbsp nbsp 最近在用yolov3进行目标检测 也有一个多星期了 想把最近做出的一些成果记录下来 供大家参考下 我的运行环境是C opencv VS2015 yolov3 下面将简单介绍下yolo的一些思想
  • simulink之S函数

    s函数是system Function的简称 xff0c 用它来写自己的simulink模块 xff08 够简单吧 xff0c xff0c 详细的概念介绍大伙看帮助吧 xff09 可以用matlab C C 43 43 Fortran Ad
  • win10解决未安装任何音频输出设备

    最近刚刚更新了一下win10系统 xff0c 开始啥问题没有 xff0c 晚上睡觉关机后 xff0c 第二天开机 xff0c 小喇叭处有一个红叉 xff0c 显示未安装任何音频输出设备 查看了微软的官网以及百度了很多解决方法 xff0c 电
  • Quadcopter控制

    1 问题描述 四旋翼飞行器对角线上的两个电机旋转方向相同 xff0c 另一对与之旋转方向相反 这是使推力 xff0c 滚转 xff0c 俯仰 xff0c 偏航相互独立控制的必要条件 这可以使我们命令其中的一个动作而不影响其他动作 实际上 x
  • 入门级都能看懂的softmax详解

    项目github地址 xff1a bitcarmanlee easy algorithm interview and practice 经常有同学私信或留言询问相关问题 xff0c V号bitcarmanlee github上star的同学
  • LQR制导

    LQR制导 引言 在ardupilot中固定翼飞机横航向位置控制 xff08 制导律 xff09 采用L1制导律 xff0c 最近想将一些其他的控制理论用于ardupilot代码中 xff0c 通过ardupilot论坛 xff0c 看到已
  • 2022年度总结

    年度总结 参加工作的第一年很快就过去了 xff0c 从四月份离校到公司 xff0c 直到农历腊月27回家 xff0c 工作了9个月的时间 xff0c 总的来说工作和学习的差别还是很大的 xff0c 从学生到社畜的转换还是花了一段时间的 接下
  • HTTP基本认证

    在HTTP中 xff0c 基本认证 xff08 英语 xff1a Basic access authentication xff09 是允许http用户代理 xff08 如 xff1a 网页浏览器 xff09 在请求时 xff0c 提供 用
  • c# 设置代理服务器发送http请求

    span class token keyword using span span class token namespace System span span class token punctuation span span class
  • Blaze:高性能C++数学库

    Blaze xff1a 高性能C 43 43 数学库 本文译自 xff1a Blaze A high performance C 43 43 math library Blaze是一个用于密集和稀疏算法的开源 高性能 C 43 43 数学库
  • c/c++编译:使用CMAKE进行跨平台开发

    前言 本文介绍跨平台cmake的编写 xff0c 主要是linux和windows用cmake对项目的编译 这是一个通用模板 xff0c 能够应用到更加复杂的项目中 xff0c 项目例子用https blog csdn net qq 364
  • 对于应用层HTTP协议的学习

    lt start gt 在TCP IP协议栈中 xff0c HTTP协议处于应用层 xff0c 它在最顶层进行数据报转发给应用进程 xff0c 它是最靠近用户的那一层 它的默认端口号为80 HTTP协议是基于请求响应的协议 xff0c 那么

随机推荐

  • 编程开发环境搭建

    全部目录 下载 amp 安装官方下载Vs2019其它历史 版本下载 开始使用安装C 43 43 的工作负载 xff08 环境 xff09 打开vs后有这些模板创建出一个控制台应用程序更多参考文档 使用手册c 43 43 参考手册Visual
  • c++创建第一个控制台程序

    目录 创建控制台应用程序打印出Hello World 空项目创建vs自带打印的创建桌面向导 自定义创建 了解代码 抛转引玉减少为什么 什么是 include 它是预处理指令什么是iostream 它是c 43 43 标准库头件 编写前的了解
  • python3-操作SQLite、创建表、添加数据、查询数据

    SQLlte数据类型 SQLite能保存什么样的数据类型 可以保存空值 整数 浮点数 字符串和blob 什么是blob xff1f xff1f 是二进制大对象 例如图片 音乐 zip文件 什么是游标 游标是在数据库中用来移动和执行查询的对象
  • 初学者都能看懂的95%置信区间

    项目github地址 xff1a bitcarmanlee easy algorithm interview and practice 经常有同学私信或留言询问相关问题 xff0c V号bitcarmanlee github上star的同学
  • c# WindowForm练习项目主窗体设计

    窗体分割器 SpliContainer分割器 在项目主窗体分割成左右俩部分 设置边框线属性 MonthCalendar月历控件 添加程序所需要的按钮 退出 修改密码 添加会员 按钮 固定好左边的容器 组件 ImageList 按钮太多添加图
  • C#-WinForm班级下拉框数据绑定

    前台展示 后台方法 span class hljs keyword using span System span class hljs keyword using span System Collections Generic span c
  • C#--WinForm项目主窗体设计

    主窗体基本设置 大小 颜色 去边框 出现的位置 Panel控件 背景图 颜色 布局 xff1a Label标签 文本 字体 背景颜色 布局 按钮 布局 文本 字体颜色 背景色 底部panel 绑定控件边框 颜色 用label标签导入图标 S
  • C# -- 实现WinForm程序的密码修改

    修改窗体程序密码的示例 实现分析 前台弹出修改窗体 编写后台方法 xff0c 调用通用数据访问类Update方法 数据验证 xff0c 判断原密码是否与旧密码符合 xff0c 俩次输入的新密码是否一致 更新程序全局变量 前台弹出修改窗体 编
  • C#--WinForm--表格数据控件DataGridView--绑定模式

    官方文档 DataGridView控件提供了一种强大而灵活的以表格形式显示数据的方式 用户可以使用DataGridView控件来显示少量数据的只读视图 xff0c 也可以对其进行缩放以显示特大数据集的可编辑视图 扩展DataGridView
  • ASP.NET--网站配置、发布与部署

    网站发布前的配置信息 配置文件下载 网站发布的基本步骤 写好的项目 在本机上发布 打开目录查看 xff1a 部署网站 安装IIs 打开控制面板 程序和功能 启用或关闭Windows功能 安装后 返回控制面板 管理工具 双击打开 xff1a
  • c/c++ hash表 (哈希表、字典表)

    表 1 表 存储数据 key gt value 2 表存储数据结构的困难 怎么查找 一个一个key去比较去查找 xff1f 61 61 效率不高 3 Hash算法加快查找 将字符串的key 转成整数 使用整数找到对应的value Hash算
  • c/c++ UDP通讯

    UDP通讯 1 无连接的 不需要反复的确认和握手等待 根本不关心对方是否存在 2 不可靠 可能有丢包 和先发后到 3 UDP通讯快速 占用系统资源少 4 UDP提供作为传输层协议的最基本功能 将其他的交给用户自己来管理 UDP服务端 1 创
  • c#程序流程控制与调试技术

    If选择结构 为什么要使用关系运算符 简单If 选择结构1 逻辑运算符
  • 特征融合之基于贝叶斯理论的特征融合算法

    参考文献 xff1a 1 刘渭滨 邹智元 邢薇薇 模式分类中的特征融合方法 J 北京邮电大学学报 2017 04 5 12 2 Ma A J Yuen P C Lai J H Linear Dependency Modeling for C
  • 初学者都能看懂的蒙特卡洛方法以及python实现

    项目github地址 xff1a bitcarmanlee easy algorithm interview and practice 经常有同学私信或留言询问相关问题 xff0c V号bitcarmanlee github上star的同学
  • postman安装包

    postman34位和64位安装包 xff0c 访问API 下载地址 xff1a 链接 xff1a https pan baidu com s 1p 830DPPKumXiwMPVtKYsw 提取码 xff1a 8p6k
  • STM32入门:STM32F401CDU6库函数工程文件搭建

    STM32F401CDU6库函数工程文件搭建 根据下图的结构进行复制粘贴操作 xff0c 代码部分在本文末有贴出来 xff0c STM32F4xx DSP StdPeriph Lib V1 8 0文件下载 xff08 使用part1即可 x
  • 减小vscode-cpptools的内存占用

    在VScode菜单栏文件 gt 首选项 gt 设置 搜索C Cpp intelliSenseCacheSize 修改默认的5120为512
  • Ubuntu20.04 安装tcp调试工具mNetAssist步骤

    概述 在Ubuntu20 04上安装一个比较好用的网络调试助手mNetAssist 下载链接 mNetAssist链接 提取码 vrsm 安装 进入文件 mNetAssist release amd64 deb的所在文件夹 xff0c 然后
  • 页面加载时,添加进度条,提高用户体验

    这几个月做了个项目 xff0c 在此对一些问题做一个记录 项目是前后端分离的 xff0c 前端用的 npm 43 webpack 问题 xff1a 由于系统某页面数据量过大或网络较差等原因 xff0c 导致页面还未完全加载出来 xff0c