分享一个select无限级分类的选择器

源代码

class selectTree {
    elem;
    elemShow;
    elemMain;
    elemShowOption;
    optionHtml = [];
    nameFiled;
    valueFiled;
    i

    constructor(option) {
        this.elem = $(option.elem);
        this.nameFiled = option.name || 'name'
        this.valueFiled = option.value || 'value'
        this.buildMain();
    }

    build(data) {
        this.optionHtml = [];
        this.buildOption(data, 15)
        this.elemShowOption.html(this.optionHtml.join(''))
        this.buildOptionCSSEvent()
        let value = this.elem.val()
        if (!value) {
            value = data[0] ? data[0][this.valueFiled] : ''
        }
        let val = this.elemShowOption.find('div[tag-data="' + value + '"]');
        let parents = val.parents('dd');
        let scroll = 0;
        parents.each(function (k, v) {
            $(v).children(':first').find('div').click()
            scroll += $(v).prevAll().length * 36
        })
        this.elemShowOption.css({visibility:'hidden'})
        val.click()
        var _this = this
        setTimeout(function () {
            _this.elemShowOption.scrollTop(scroll)
            _this.elemShowOption.hide()
            _this.elemShowOption.css({visibility:'visible'})
        }, 500)
        this.i.css({transform: 'rotate(0deg)', marginTop: '-3px',})
        this.i.i = 1
    }

    buildMain() {
        var _this = this
        this.elem.after('<div tag="selectTree-main" style="position:relative;display: inline-block;"></div>')
        this.elemMain = this.elem.next()
        this.elemMain.append('<input name="selectTreeNameShow"/>')
        this.elemShow = this.elemMain.find('input[name=selectTreeNameShow]')
        this.elemMain.append(this.elem)
        this.elemMain.append('<i></i>')
        let i = this.elem.next()
        this.i = i
        this.elem.hide();
        this.elemShow.css({
            height: '38px',
            width: '100%',
            lineHeight: '1.3',
            border: '1px solid #e6e6e6',
            borderRadius: '2px',
            backgroundColor: '#fff',
            paddingRight: '30px',
            paddingLeft: '10px',
            cursor: 'pointer',
        })
        this.elemShow.prop('readonly', true)
        i.css({
            width: 0,
            height: 0,
            border: '7px solid transparent',
            borderTopColor: '#c2c2c2',
            position: 'absolute',
            right: '10px',
            top: (this.elemShow.height() / 2 + "px"),
            marginTop: '-3px',
            transition: 'all .3s'
        })
        this.elemShow.click(function () {
            i.i = 0;
            return function () {
                if (i.i) {
                    i.css({transform: 'rotate(180deg)', marginTop: '-9px'})
                } else {
                    i.css({transform: 'rotate(0deg)', marginTop: '-3px',})
                }
                i.i = !i.i;
                _this.elemShowOption.slideToggle(200);
                return false;
            }
        }())
        this.elemMain.append('<div tag="show-option"></div>')
        this.elemShowOption = this.elemMain.find('div[tag=show-option]')
        this.elemShowOption.css({
            minWidth: '100%',
            maxHeight: '300px',
            position: 'absolute',
            top: (this.elemShow.height() + 5 + "px"),
            backgroundColor: '#ffffff',
            zIndex: 9999,
            display: 'none',
            overflowY: 'auto',
            border: '1px solid #ccc',
        })
    }

    buildOption(data, paddingLeft) {
        const _this = this;
        this.optionHtml.push('<dl>')
        $(data).each(function (k, v) {
            _this.optionHtml.push('<dd><div tag-data="' + v[_this.valueFiled] + '">');
            if (v.children && v.children.length > 0) {
                _this.optionHtml.push('<div style="padding-left: ' + paddingLeft + 'px;display: inline-block">');
                _this.optionHtml.push('<i></i>');
            } else {
                _this.optionHtml.push('<div style="padding-left: ' + (paddingLeft + 10) + 'px;display: inline-block">&nbsp;');
            }
            _this.optionHtml.push('</div><span>' + v[_this.nameFiled] + '</span></div>');
            if (v.children && v.children.length > 0) {
                _this.buildOption(v.children, paddingLeft + 15)
            }
            _this.optionHtml.push('</dd>');
        })
        this.optionHtml.push('</dl>')
    }

    buildOptionCSSEvent() {
        const _this = this;
        let div = this.elemShowOption.find('dd>div')
        this.elemShowOption.find('dd>dl').hide()
        let i = this.elemShowOption.find('i')
        div.css({
            whiteSpace: 'nowrap',
            paddingRight: '15px',
            lineHeight: '36px',
            cursor: 'pointer',
        })
        div.hover(function () {
            $(this).not('.check').css({backgroundColor: '#eee'})
        }, function () {
            $(this).not('.check').css({backgroundColor: '#ffffff00'})

        })
        div.click(function () {
            div.css({backgroundColor: '#ffffff00', color: '#000'})
            div.removeClass('check')
            let name = $(this).find('span').html();
            let value = $(this).attr('tag-data');
            $(this).css({backgroundColor: '#5FB878', color: '#fff'})
            $(this).addClass('check')
            _this.elem.val(value);
            _this.elemShow.val(name)
            _this.elemShow.click();
            return false;
        })
        i.css({
            width: 0,
            height: 0,
            border: '7px solid transparent',
            borderLeftColor: '#c2c2c2',
            position: 'relative',
            left: '0px',
            transition: 'all .3s',
            display: 'inline-block',
        })
        this.elemShowOption.find('dd>div>div').click(function () {
            let a = $(this).attr('unfold') || 'true';
            if (a === 'true') {
                $(this).find('i').css({transform: 'rotate(90deg)', top: '3px', left: '-3px'})
                $(this).attr('unfold', 'false')
            } else {
                $(this).find('i').css({transform: 'rotate(0deg)', top: '1px', left: '0px'})
                $(this).attr('unfold', 'true')
            }
            $(this).parent().next().slideToggle(200);
            return false;
        })
    }
}

使用方法

<input type="text" name="cate_id" required lay-verify="required" placeholder="请输入标题"
                                   autocomplete="off"
                                   class="layui-input" id="cate">
var select = new selectTree({
        elem: '#cate',
        name: 'name',//指定展示的名字字段
        value: 'id'//指定提交值的字段
    });
select.build(selectData)//执行构建选择器

数据结构
let a = [
        {
            name:'手机',
            id:'10',
            children:[
                {
                    name:'苹果手机',
                    id:'20'
                }
            ]
        }
    ];

效果

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值