自定义步骤条分享

最近做的项目技术栈用的是jquery+requirejs+handlebar+公司内部的一套ui库。ui库中关于步骤条的只有简单的样式,如果设置下一步的时候需要一个节点一个节点的去设置样式,所以封装了一个步骤条的构造,现分享一下。

封装的步骤条可以实现的效果如下:

一、横向-从左开始

二、横向-从右开始

三、纵向-从上开始

四、纵向-从下开始

五、以上四种是封装的步骤条实现的效果。业务中用到的是第一种和第四种。

六、构造js代码

define([], function() {
    'use strict';
    
    /**
     * 创建步骤条
     * @param id - 容器id
     * @param mode - left, right, top, bottom
     * @param source - 步骤条数据 [{ label:"", value:"" }]
     * @param defaultKey - 默认显示的步骤的key
     * @param key - 步骤条唯一的key,默认为value
     * @param showKey - 步骤条显示的key,默认为label
     * 
     * @function setStepKey - 设置当前步骤条的位置(根据key值)
     * @function setStepIndex - 设置当前步骤条的位置(根据index值)
     * @function getCurrent - 获取当前步骤的信息 { key, index, item }
     * @function setStepColor - 设置某一步的颜色值,该方法建议只是静态显示的时候使用
     */
    function MyStep(option){
        if(!option){
            throw new Error('options is missing');
        }
        if(!option.id){
            throw new Error('box id is missing');
        }
        this.id = option.id;
        this.source = option.source || [];
        if(this.source.length <= 1){
            throw new Error('source length should > 1');
        }
        this.mode = option.mode || 'left';
        this.key = option.key || 'value';
        this.showKey = option.showKey || 'label';
        this.box = document.getElementById(this.id);
        this.init();
        if(!option.defaultKey){
            this.setStepIndex(0);
        }else{
            this.setStepKey(option.defaultKey);
        }
    }

    MyStep.prototype.init = function(){
        this.render();
    }

    MyStep.prototype.render = function(){
        var that = this;
        var str = '';
        if(that.mode == "left" || that.mode == "right"){
            str = '<div class="yby-steps-box left">';
            var source = that.mode == "left" ? this.source : this.source.reverse();
            source.forEach(function(item, index){
                str += '<div class="step ' + (index == 0 ? "first" : index == that.source.length - 1 ? "last" : "") + '" style="flex-basis: ' + (100 / that.source.length) + '%;" data-key="' + item[that.key] + '">'
    
                    + '<div class="circle-box">'
                    + '<div class="circle-icon-box"><span class="circle"></span></div>'
                    + '<div class="step-line"></div>'
                    + '</div>'
    
                    + '<div class="tips-box">'
                    + '<span class="title">' + item[that.showKey] + '</span>'
                    + '</div>'
    
                    + '</div>';
            })
            str += '</div>';
        }
        else if(that.mode == "bottom" || that.mode == "top"){
            str = '<div class="yby-steps-box bottom">';
            var source = that.mode == "top" ? this.source : this.source.reverse();
            source.forEach(function(item, index){
                str += '<div class="step ' + (index == 0 ? "first" : index == that.source.length - 1 ? "last" : "") + '" data-key="' + item[that.key] + '">'
    
                    + '<div class="circle-box">'
                    + '<div class="circle-icon-box"><span class="circle"></span></div>'
                    + '<div class="step-line"></div>'
                    + '</div>'
    
                    + '<div class="tips-box">'
                    + '<div class="title-box">'
                    + '<span class="title">' + item[that.showKey] + '</span>'
                    + '<span class="date">'+ (item.date || '') +'</span>'
                    + '</div>'
                    + '<div class="msg">'+ (item.msg || '') +'</div>'
                    + '</div>'
    
                    + '<span class="clear"></span>'
    
                    + '</div>';
            })
            str += '</div>';
        }
        
        this.box.innerHTML = str;
    }

    MyStep.prototype.setStepKey = function(key){
        var that = this;
        var flag = this.mode != "bottom" && this.mode != "right" ? false : true;
        $(this.box).find('.step').map(function(index, item){
            var aKey = $(item).data('key');
            $(item).removeClass('active');
            if(that.mode != "bottom" && that.mode != "right"){
                if(!flag){
                    $(item).addClass('active');
                }
                flag = aKey == key ? !flag : flag;
            }else{
                flag = aKey == key ? !flag : flag;
                if(!flag){
                    $(item).addClass('active');
                }
            }
        })
    }

    MyStep.prototype.setStepIndex = function(index){
        var len = this.source.length;
        if(index >= len || index < 0){
            throw new Error('index is out of range');
        }
        if(this.mode == "left" || this.mode == "top"){
            $(this.box).find('.step').removeClass('active').eq(index).addClass('active').prevAll().addClass('active');
        }
        else if(this.mode == "bottom" || this.mode == "right"){
            $(this.box).find('.step').removeClass('active').eq(len - 1 - index).addClass('active').nextAll().addClass('active');
        }
    }

    MyStep.prototype.getCurrent = function(key){
        var index = $(this.box).find('.step.active').length - 1;
        var key = $(this.box).find('.step.active').eq(index).data('key');
        var source = this.mode != "left" && this.mode != "top" ? this.source.reverse() : this.source;
        var item = source[index];
        return {
            index: index,
            key: key,
            item: item
        }
    }

    /**
     * 来改变某一个节点的色值,这个方法只建议静态显示的时候用
     * @param key - 唯一值
     * @param color - 颜色值 rgb(247, 53, 53, 0.5) - 粉色;#f73535=rgb(247, 53, 53) - 红色
     */
    MyStep.prototype.setStepColor = function(key, color){
        $(this.box).find('.step').map(function(index, item){
            var aKey = $(item).data('key');
            if(aKey == key){
                $(item).find('.circle').css({
                    border: '2px solid #e9ecf0',
                    backgroundColor: color
                });
                $(item).find('.text').css('color', color);
            }
        })
    }

    return MyStep;

});

七、组件的css代码

/*
步骤条样式
*/
.yby-steps-box.left {
  width: 100%;
  display: flex;
  box-sizing: border-box;
  margin: 20px auto;
}
.yby-steps-box.left * {
  box-sizing: border-box;
}
.yby-steps-box.left .step {
  align-items: center;
  justify-content: space-between;
  text-align: center;
}
.yby-steps-box.left .step .circle-box {
  position: relative;
  width: 100%;
  height: 40px;
  padding-top: 12px;
}
.yby-steps-box.left .step .circle-box .circle-icon-box {
  position: absolute;
  z-index: 5;
  width: 100%;
}
.yby-steps-box.left .step .circle-box .circle-icon-box .circle {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  display: inline-block;
  background-color: #e9ecf0;
  text-align: center;
}
.yby-steps-box.left .step .circle-box .step-line {
  position: absolute;
  width: 100%;
  top: 20px;
  font-size: 0;
  border: none;
  height: 2px;
  background-color: #e9ecf0;
}
.yby-steps-box.left .step .tips-box .title {
  display: inline-block;
  width: 100px;
}
.yby-steps-box.left .step.active .circle-box .circle {
  background-color: #90c31f;
  border: 2px solid #e9ecf0;
}
.yby-steps-box.left .step.first .step-line {
  width: 50%;
  left: 50%;
}
.yby-steps-box.left .step.last .step-line {
  width: 50%;
  left: 0;
}
.yby-steps-box.bottom {
  display: block;
  width: 100%;
}
.yby-steps-box.bottom .step {
  width: 100%;
  height: 100px;
}
.yby-steps-box.bottom .step .circle-box {
  float: left;
  width: 100px;
  height: 100%;
  text-align: center;
  position: relative;
}
.yby-steps-box.bottom .step .circle-box .circle-icon-box {
  width: 100%;
  height: 16px;
}
.yby-steps-box.bottom .step .circle-box .circle-icon-box .circle {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  display: inline-block;
  background-color: #e9ecf0;
  text-align: center;
}
.yby-steps-box.bottom .step .circle-box .step-line {
  position: absolute;
  bottom: 0;
  display: inline-block;
  width: 2px;
  font-size: 0;
  border: none;
  height: calc(100% - 16px);
  background-color: #e9ecf0;
}
.yby-steps-box.bottom .step .tips-box {
  float: right;
  width: calc(100% - 100px);
}
.yby-steps-box.bottom .step .tips-box .title-box {
  width: 100%;
  height: 30px;
  font-size: 13px;
}
.yby-steps-box.bottom .step .tips-box .title-box .title {
  display: inline-block;
  width: calc(100% - 150px);
  color: #333333;
}
.yby-steps-box.bottom .step .tips-box .title-box .date {
  float: right;
  width: 150px;
  text-align: right;
  color: #999999;
}
.yby-steps-box.bottom .step .tips-box .msg {
  width: calc(100% - 150px);
  font-size: 12px;
  line-height: 28px;
  color: #999999;
}
.yby-steps-box.bottom .step .clear {
  clear: both;
}
.yby-steps-box.bottom .step.active .circle-box .circle {
  background-color: #90c31f;
  border: 2px solid #e9ecf0;
}
.yby-steps-box.bottom .step.last .step-line {
  display: none;
}

通过组件实例化之后的实例,可以调用实例的方法获取当前节点的信息,可以通过key或者index来设置步骤条的当前步骤。

就这么多了,构造中都有相应的注释,应该很明白了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值