纯js实现流程进度显示——学习篇

5 篇文章 0 订阅
5 篇文章 0 订阅
本文介绍了一个用于展示流程进度的JavaScript组件`Progress`,包括效果展示、代码实现、示例及总结。组件支持自定义节点名称、描述、状态等属性,并能计算节点耗时,提供不同状态的样式展示。示例中展示了两种不同的数据格式使用方式,适用于展示多级流程节点的状态和时间信息。
摘要由CSDN通过智能技术生成

目录

一、效果展示

二、上代码

1、Progress对象

2、样式加载

3、render输出流程

4、生成节点 

5、 计算耗时时间

三、Example

四、总结经验


一、效果展示

二、上代码

1、Progress对象

if (typeof Progress != 'undefined') {
        delete Progress;
    }
    var Progress = function ({
                                 eleId, 
                                 data, // 数组
                                 fieldMap = { // 映射到data数组中的字段名称
                                     nodeName: '', // 节点名称 
                                     nodeDesc: '', // 节点描述
                                     nodeStatus: '', // 节点状态
                                 }, 
                                 nodeStatusSuccess = 1, // 成功节点状态值
                                 nodeStatusNext = 2, // 下一个节点状态值
                                 nodeStatusFail = 3, // 失败节点状态值
                                 nodeStatusFunc = null, // 判断节点状态,返回状态值:nodeStatusSuccess、nodeStatusNext、nodeStatusFail
                             }) {
        this._data = data;
        console.log(this._data)
        this._liPool = [];
        this._prevTime = 0;
        this._fieldMap = fieldMap;
        this._nodeStatusSuccess = nodeStatusSuccess;
        this._nodeStatusNext = nodeStatusNext;
        this._nodeStatusFail = nodeStatusFail;
        this._nodeStatusFunc = nodeStatusFunc;
        this._rootElement = document.getElementById(eleId);
        this._ul = document.createElement('ul');
        this._ul.classList.value = 'out-line';
        this._rootElement.append(this._ul);
        this.initStyle();
        this.render();
        return this;
    }

2、样式加载

Progress.prototype.initStyle = function () {
        this._style = document.createElement('style');
        this._rootElement.append(this._style);
        this._style.innerHTML = `
    .out-line {
        position: relative;
        border-left: 1px solid red;
        border-right: 0px;
        border-top: 0px;
        border-bottom: 0px;
        /*width: 0px;*/
        padding: 0px;
    }
    .out-line li {
        list-style: none;
        margin: 0px;
        -webkit-transform: translateX(-50%);
        -moz-transform: translateX(-50%);
        -ms-transform: translateX(-50%);
        -o-transform: translateX(-50%);
        transform: translateX(-50%);
        /*border: 1px solid;*/
    }
    .first-node, .second-node, .third-node {
        margin: 30px 0px !important;
        position: relative;
    }
    .first-node {
        padding: 20px 50px;
        background: #eeeeee;
        font-size: 21px;
        font-weight: bold;
    }
    .second-node {
        width: 40px;
        height: 40px;
        -webkit-border-radius: 40px;
        -moz-border-radius: 40px;
        border-radius: 40px;
    }
    .third-node {
        width: 30px;
        height: 30px;
        -webkit-border-radius: 30px;
        -moz-border-radius: 30px;
        border-radius: 30px;
    }
    .start-node, .end-node {
        -webkit-border-radius: 10px;
        -moz-border-radius: 10px;
        border-radius: 10px;
    }
    .start-node {
        margin-top: 0px !important;
    }
    .end-node {
        margin-bottom: 0px !important;
    }
    .is-pass {
        background: green;
    }
    .is-next {
        background: orange;
    }
    .is-future {
        background: #eeeeee;
        border: 1px solid rgba(0, 0, 0, 0.4);
    }
    .is-fail{
        background: red;
        color: white;
    }
    .node-left, .node-right {
        position: absolute;
        left: 0px;
        top: 0px;
        width: 500px;
    }
    .node-left {
        -webkit-transform: translateX(-100%);
        -moz-transform: translateX(-100%);
        -ms-transform: translateX(-100%);
        -o-transform: translateX(-100%);
        transform: translateX(-100%);
        left: -30px;
        top: -25px;
        text-align: right;
        color: rgba(0, 0, 0, 0.5);
    }
    .node-right {
        left: 70px;
        text-align: left;
        display: flex;
        align-items: center;
    }
    .node-right * {
        text-align: left;
    }
    .node-content {
        color: rgba(0, 0, 0, 0.8);
        width: 200px;
    }
    .node-name {
        font-size: 20px;
        font-weight: bold;
    }
    .node-time {
        margin-left: 20px;
        color: rgba(0, 0, 0, 0.5);
    }
    .node-text {
        width: 100%;
        height: 100%;
        display: flex;
        justify-content: center;
        align-items: center;
        -webkit-border-radius: 100%;
        -moz-border-radius: 100%;
        border-radius: 100%;
    }
    .is-pass .node-text,.is-next .node-text, .is-fail .node-text {
        color: white;
    }
    .is-future .node-text {
        color: #000;
    }
    .second-node .node-text {
        font-size: 24px;
    }
    .third-node .node-text {
        font-size: 14px;
    }
    .is-next .node-name, .is-fail .node-name{
        color: orange;
    }
    `
        return this;
    }

3、render输出流程

Progress.prototype.render = function () {
        let lastNode = Object.keys(this._data).length - 1;
        Object.values(this._data).forEach((item, index) => {
            let li = document.createElement('li'),
                nodeName = this._fieldMap.nodeName ? (typeof item[this._fieldMap.nodeName] == 'undefined' ? '' : item[this._fieldMap.nodeName]) : (typeof item.nodeName == 'undefined' ? '' : item.nodeName);
            li.classList.value = 'first-node ' + (index == 0 ? 'start-node' : (index == lastNode ? 'end-node' : ''));
            li.innerHTML = nodeName;
            this._liPool.push(li);
            this._ul.append(li);
            if (item.node) {
                this.secondNode(item.node);
            }
        })
        return this;
    };

4、生成节点 


Progress.prototype.secondNode = function (data) {
        Object.values(data).forEach((vo, i) => {
            this.createNode(vo, 'second-node');
            if (vo.photo_log) {
                this.thirdNode(vo.photo_log);
            }
        })
    }


Progress.prototype.thirdNode = function (data) {
        Object.values(data).forEach((v, j) => {
            this.createNode(v, 'third-node');
        })
    }



Progress.prototype.createNode = function (data, className = 'second-node') {
        let li = document.createElement('li'), consuming = '', nodeText = '·', 
            nodeTime = this._fieldMap.nodeTime ? (typeof data[this._fieldMap.nodeTime] == 'undefined' ? '' : data[this._fieldMap.nodeTime]) : (typeof data.nodeTime == 'undefined' ? '' : data.nodeTime),
            nodeName = this._fieldMap.nodeName ? (typeof data[this._fieldMap.nodeName] == 'undefined' ? '' : data[this._fieldMap.nodeName]) : (typeof data.nodeName == 'undefined' ? '' : data.nodeName),
            nodeDesc = this._fieldMap.nodeDesc ? (typeof data[this._fieldMap.nodeDesc] == 'undefined' ? '' : data[this._fieldMap.nodeDesc]) : (typeof data.nodeDesc == 'undefined' ? '' : data.nodeDesc),
            nodeStatus = this._fieldMap.nodeStatus ? (typeof data[this._fieldMap.nodeStatus] == 'undefined' ? '' : data[this._fieldMap.nodeStatus]) : (typeof data.nodeStatus == 'undefined' ? '' : data.nodeStatus);
        if (nodeTime) {
            consuming = this.consumingTime(nodeTime);
        }
        if ((this._nodeStatusFunc && this._nodeStatusFunc.call(this, data) == this._nodeStatusFail) || nodeStatus == this._nodeStatusFail) {
            className += ' is-fail';
            nodeText = '×';
        } else if ((this._nodeStatusFunc && this._nodeStatusFunc.call(this, data) == this._nodeStatusSuccess) || nodeStatus == this._nodeStatusSuccess) {
            nodeText = '√'
            className += ' is-pass';
        } else if ((this._nodeStatusFunc && this._nodeStatusFunc.call(this, data) == this._nodeStatusNext) || nodeStatus == this._nodeStatusNext) {
            nodeText = '···';
            className += ' is-next';
        } else {
            className += ' is-future';
        }
        li.classList.value = className;
        li.innerHTML = `<div class="node-text">${nodeText}</div>
                                <div class="node-left">${consuming}</div>
                                <div class="node-right">
                                    <div class="node-content">
                                        <div class="node-name">${nodeName}</div>
                                        <div class="node-person">${nodeDesc}</div>
                                    </div>
                                    <div class="node-time">${nodeTime}</div>
                                </div>`;
        this._liPool.push(li);
        this._ul.append(li);
    }

5、 计算耗时时间

Progress.prototype.consumingTime = function (dateTime) {
        let date = new Date(dateTime), consuming = '';
        // console.log('prevTime=' + this._prevTime)
        if (this._prevTime) {
            let time = date.getTime() / 1000, timeDiff = time - this._prevTime;
            if (timeDiff > 0) {
                let h = Math.floor(timeDiff / 3600), m = Math.floor((timeDiff % 3600) / 60),
                    s = (timeDiff % 3600) % 60, d = '';
                if (h > 24) {
                    d = Math.floor(h / 24) + '天 ';
                    h = h % 24;
                }
                consuming = `节点耗时:${d}${h}:${m}:${s}`;
                this._prevTime = time;
            } else {
                consuming = `节点耗时:0:0:0`;
            }
        } else {
            this._prevTime = date.getTime() / 1000;
        }
        return consuming;
    }

三、Example

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>客户贷款进度查询</title>
    <script src="https://cdn.bootcss.com/html2canvas/0.5.0-beta4/html2canvas.min.js"></script>
    <script src="/js/jq2.0.js"></script>

    <style>
        body {
            background: #ffffff !important;
        }

        .section-box {
            display: flex;
        }

        .out-box {
            text-align: center;
            display: flex;
            justify-content: center;
            width: 70%;
        }

       
    </style>
</head>
<body>
<section class="section-box">
    <div class="out-box" id="out-box"></div> 
</section>
</body>
</html>

使用方式1:

<script>
        $(function () {
        new Progress({
            eleId: 'out-box',
            data: [
                {
                    nodeName: '开始',
                    node: [
                        {
                            nodeName: '第一步',
                            nodeDesc: '小米',
                            nodeStatus: 1,
                            nodeTime: '2020-10-30 10:21:32',
                        }, {
                            nodeName: '第二步',
                            nodeDesc: '小华',
                            nodeStatus: 1,
                            nodeTime: '2020-10-30 10:39:32',
                        }, {
                            nodeName: '第三步',
                            nodeDesc: '小马',
                            nodeStatus: 1,
                            nodeTime: '2020-10-30 10:50:32',
                        }
                    ]
                }, {
                    nodeName: '分包',
                    node: [
                        {
                            nodeName: '分类',
                            nodeDesc: '小红',
                            nodeStatus: 2,
                            nodeTime: '2020-10-30 11:19:30',
                        }, {
                            nodeName: '分配',
                            nodeDesc: '小刘',
                            nodeStatus: '',
                            nodeTime: '',
                        }
                    ]
                }, {
                    nodeName: '结束',
                }
            ]
        })
    })
    </script>   

使用方式2:

<script>
        $(function () {
        new Progress({
            eleId: 'out-box',
            fieldMap:{
                nodeName: 'name',
                nodeDesc: 'action_name',
                nodeTime: 'time',
            },
            nodeStatusFunc: (data)=>{
                if (data.audit_status == 3 || data.audit_status == 4) {
                    return 3;
                } else {
                    return data.is_audit == 3 ? 4 : data.is_audit;
                }
            },
            data: [
                {
                    name: '开始',
                    node: [
                        {
                            name: '第一步',
                            action_name: '小米',
                            is_audit: 1,
                            audit_status:1,
                            time: '2020-10-30 10:21:32',
                        }, {
                            name: '第二步',
                            action_name: '小华',
                            is_audit: 1,
                            audit_status:1,
                            time: '2020-10-30 10:39:32',
                        }, {
                            name: '第三步',
                            action_name: '小马',
                            is_audit: 1,
                            time: '2020-10-30 10:50:32',
                        }
                    ]
                }, {
                    name: '分包',
                    node: [
                        {
                            name: '分类',
                            action_name: '小红',
                            is_audit: 2,
                            audit_status:1,
                            time: '2020-10-30 11:19:30',
                        }, {
                            name: '分配',
                            nodeDesc: '小刘',
                            is_audit: 3,
                            audit_status:1,
                            time: '',
                        }
                    ]
                }, {
                    name: '结束',
                }
            ]
        })
    })
    </script>   

四、总结经验

以上为本文所有内容,希望能够帮助到有需要的博友们!!!!

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值